diff --git a/.gitignore b/.gitignore index 4f9b5df..2fb7a13 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,11 @@ pluto.*/ pluto.xpr component.xml +firmware/build/ +projects/libre/libre.cache/ +projects/libre/libre.gen/ +projects/libre/libre.hw/ +projects/libre/libre.ip_user_files/ +projects/libre/libre.runs/ +projects/libre/libre.srcs/ +projects/libre/libre.xpr diff --git a/README.md b/README.md index 54f24e3..4a24982 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,8 @@ The following ORI library components are used as submodules to this repository: 6. [power_detector](https://github.com/OpenResearchInstitute/power_detector) 7. [Exponential Moving Average Filter](https://github.com/OpenResearchInstitute/lowpass_ema) -## Building Pluto Firmware -In oder to build the FPGA bitstream, you first need to install Vivado. Recommended version is 2022.2. In this documentation and in the `Makefile`, the Vivado installation path is assumed to be `/opt/Xilinx/Vivado`. If it is in another directory, change the path in the steps below (for example, to `/tools/Xilinx/Vivado`) or create a symbolic link in `/opt` pointing to the actual installation directory. For example, +## Building +In order to build the FPGA bitstream, you first need to install Vivado. Recommended version is 2022.2. In this documentation and in the `Makefile`, the Vivado installation path is assumed to be `/opt/Xilinx/Vivado`. If it is in another directory, change the path in the steps below (for example, to `/tools/Xilinx/Vivado`) or create a symbolic link in `/opt` pointing to the actual installation directory. For example, ``` sudo ln -s /tools/Xilinx /opt/Xilinx ``` @@ -172,6 +172,8 @@ sys 39m46.236s | 0x84 |lowpass_ema_alpha1| Exponential Moving Average Alpha | | 0x88 |lowpass_ema_alpha2| Exponential Moving Average Alpha | | 0x8C | rx_power | Receive Power | +| 0x90 |tx_async_fifo_rd_wr_ptr| Tx async FIFO read and write pointers | +| 0x94 |rx_async_fifo_rd_wr_ptr| Rx async FIFO read and write pointers | See [MSK Top Regs](rdl/msk_top_regs.pdf) for detailed register definitions. diff --git a/docs/msk_math.md b/docs/msk_math.md index fd03d93..186dfea 100644 --- a/docs/msk_math.md +++ b/docs/msk_math.md @@ -115,10 +115,12 @@ The four resulting values for the f1 mix are cos(2𝝿f1t)*cos(2𝝿f1t) = 1/2 [ cos(2𝝿f1t - 2𝝿f1t) + cos(2𝝿f1t + 2𝝿f1t) ] = 1/2 [ cos(0) + cos(4𝝿f1t) ] = 1/2 [ 1 + cos(4𝝿f1t)] + = 1/2 + 1/2cos(2𝝿2f1t) -cos(2𝝿f1t)*cos(2𝝿f1t) = -1/2 [ cos(2𝝿f1t - 2𝝿f1t) + cos(2𝝿f1t + 2𝝿f1t) ] = -1/2 [ cos(0) + cos(4𝝿f1t) ] = -1/2 [ 1 + cos(4𝝿f1t)] + = -1/2 - 1/2cos(2𝝿2f1t) (both the previous results are a DC value and a sinusoid at 2*f1) @@ -149,16 +151,16 @@ cos(2𝝿f1t)*sin(2𝝿f1t) = 1/2 [ sin(2𝝿f1t + 2𝝿f1t + theta) - sin(2𝝿 = 1/2 sin(4𝝿f1t + theta) --cos(2𝝿f1t)*sin(2𝝿f1t) = -1/2 [ sin(2𝝿f1t + 2𝝿f1t) - sin(2𝝿f1t - 2𝝿f1t) ] - = -1/2 [ sin(4𝝿f1t) - sin(0) ] - = -1/2 sin(4𝝿f1t) +-cos(2𝝿f1t)*sin(2𝝿f1t) = -1/2 [ sin(2𝝿f1t + 2𝝿f1t + theta) - sin(2𝝿f1t - 2𝝿f1t + theta) ] + = -1/2 [ sin(2𝝿2f1t + theta) - sin(theta) ] + = -1/2 sin(2𝝿2f1t + theta) again we only care about the DC component, which when the phases are aligned is 0. If the phases are not aligned the sin(0) term becomes sin(Δφ) a constant. cos(2𝝿f1t)*sin(2𝝿f1t) = 1/2 [ sin(2𝝿f2t + 2𝝿f1t) - sin(2𝝿f2t - 2𝝿f1t) ] - = 1/2 [ sin(2𝝿(f2+f1)t) - sin(2𝝿(f2-f1)t) ] + = 1/2 [ sin(2𝝿(f2+f1)t) - sin(2𝝿(f2-f1)t) ] cos(2𝝿f1t)*sin(2𝝿f1t) = -1/2 [ sin(2𝝿f2t + 2𝝿f1t) - sin(2𝝿f2t - 2𝝿f1t) ] @@ -166,3 +168,11 @@ cos(2𝝿f1t)*sin(2𝝿f1t) = -1/2 [ sin(2𝝿f2t + 2𝝿f1t) - sin(2𝝿f2t - 2 + +error_instant = 1/2 sin(2𝝿2f1t + theta) * sign( 1/2 + 1/2cos(2𝝿2f1t)) + = -1/2 sin(2𝝿2f1t + theta) * sign(-1/2 - 1/2cos(2𝝿2f1t)) + = 1/2 sin(2𝝿2f1t + theta) + +error = SUM_T(1/2 sin(2𝝿2f1t + theta)) = -cos(2𝝿2f1t + theta) + C + + diff --git a/firmware/Makefile b/firmware/Makefile index 82c136f..f6ed163 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -23,7 +23,6 @@ VERSION=$(shell git describe --abbrev=4 --always --tags) PATCH=$(shell cd ori && ./applypatch.sh ) $(shell git log --pretty=format:"%h - %ad : %s" > ori/board/pluto/overlay/root/fwhistory.txt) #LATEST_TAG=$(shell git describe --abbrev=0 --tags) -UBOOT_VERSION=$(shell echo -n "PlutoSDR " && cd u-boot-xlnx && git describe --abbrev=0 --dirty --always --tags) HAVE_VIVADO= $(shell bash -c "source $(VIVADO_SETTINGS) > /dev/null 2>&1 && vivado -version > /dev/null 2>&1 && echo 1 || echo 0") #XSA_URL ?= http://github.com/maia-sdr/plutosdr-fw/releases/download/${LATEST_TAG}/system_top.xsa @@ -43,25 +42,26 @@ ifneq (1, ${PATCH}) $(warning patch granted $(PATCH)) endif -TARGET ?= pluto -SUPPORTED_TARGETS:=pluto plutoplus e200 -#XSA_FILE ?= ori/bitstream/${TARGET}/system_top.xsa +PLATFORM ?= pluto +SUPPORTED_TARGETS:=pluto plutoplus e200 libre +#XSA_FILE ?= ori/bitstream/${PLATFORM}/system_top.xsa -$(warning *** Building target $(TARGET),) +$(warning *** Building target $(PLATFORM),) # Include target specific constants -include scripts/$(TARGET).mk +include scripts/$(PLATFORM).mk +UBOOT_VERSION=$(COMPLETE_NAME) $(VERSION) ifeq (, $(shell which dfu-suffix)) $(warning "No dfu-utils in PATH consider doing: sudo apt-get install dfu-util") -TARGETS = build/pluto.frm build/boot.frm +TARGETS = build/$(PLATFORM).frm build/boot.frm else -TARGETS = build/$(TARGET).dfu build/uboot-env.dfu build/pluto.frm build/boot.dfu build/boot.frm +TARGETS = build/$(PLATFORM).dfu build/uboot-env.dfu build/$(PLATFORM).frm build/boot.dfu build/boot.frm endif -ifeq ($(findstring $(TARGET),$(SUPPORTED_TARGETS)),) +ifeq ($(findstring $(PLATFORM),$(SUPPORTED_TARGETS)),) all: - @echo "Invalid `TARGET variable ; valid values are: pluto, sidekiqz2, plutoplus" && + @echo "Invalid `PLATFORM variable ; valid values are: pluto, sidekiqz2, plutoplus" && exit 1 else all: clean-build $(TARGETS) zip-all legal-info @@ -85,8 +85,8 @@ build: ### u-boot ### u-boot-xlnx/u-boot u-boot-xlnx/tools/mkimage: TOOLCHAIN -# $(TOOLS_PATH) make -C u-boot-xlnx ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) zynq_$(TARGET)_defconfig - $(TOOLS_PATH) make -C u-boot-xlnx ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) zynq_$(TARGET)_defconfig +# $(TOOLS_PATH) make -C u-boot-xlnx ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) zynq_$(PLATFORM)_defconfig + $(TOOLS_PATH) make -C u-boot-xlnx ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) zynq_$(PLATFORM)_defconfig $(TOOLS_PATH) make -C u-boot-xlnx ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) UBOOTVERSION="$(UBOOT_VERSION)" .PHONY: u-boot-xlnx/u-boot @@ -103,10 +103,10 @@ build/uboot-env.bin: build/uboot-env.txt ### Linux ### linux/arch/arm/boot/zImage: TOOLCHAIN - $(TOOLS_PATH) make -C linux -j $(NCORES) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) zynq_$(TARGET)_linux_defconfig zImage UIMAGE_LOADADDR=0x8000 - $(TOOLS_PATH) make -C linux -j $(NCORES) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) zynq_$(TARGET)_linux_defconfig uImage UIMAGE_LOADADDR=0x8000 -## $(TOOLS_PATH) make -C linux ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) defconfig zynq_$(TARGET)_defconfig -##$(TOOLS_PATH) make BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE=$(ABSOLUTE_PATH)/datv/configs/zynq_$(TARGET)datv_linux_defconfig -C linux -j $(NCORES) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) zImage UIMAGE_LOADADDR=0x8000 + $(TOOLS_PATH) make -C linux -j $(NCORES) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) zynq_$(PLATFORM)_linux_defconfig zImage UIMAGE_LOADADDR=0x8000 + $(TOOLS_PATH) make -C linux -j $(NCORES) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) zynq_$(PLATFORM)_linux_defconfig uImage UIMAGE_LOADADDR=0x8000 +## $(TOOLS_PATH) make -C linux ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) defconfig zynq_$(PLATFORM)_defconfig +##$(TOOLS_PATH) make BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE=$(ABSOLUTE_PATH)/datv/configs/zynq_$(PLATFORM)datv_linux_defconfig -C linux -j $(NCORES) ARCH=arm CROSS_COMPILE=$(CROSS_COMPILE) zImage UIMAGE_LOADADDR=0x8000 .PHONY: linux/arch/arm/boot/zImage .PHONY: linux/arch/arm/boot/uImage @@ -134,7 +134,7 @@ buildroot/output/images/rootfs.cpio.gz: @echo device-fw $(VERSION) > $(BR2_EXTERNAL)/board/pluto/VERSIONS @$(foreach dir,$(VSUBDIRS),echo $(dir) $(shell cd $(dir) && git describe --abbrev=4 --dirty --always --tags) >> $(BR2_EXTERNAL)/board/pluto/VERSIONS;) make BR2_EXTERNAL=$(ABSOLUTE_PATH)/ori -C buildroot ARCH=arm zynq_pluto_ori_defconfig -## make -C buildroot ARCH=arm zynq_$(TARGET)_defconfig +## make -C buildroot ARCH=arm zynq_$(PLATFORM)_defconfig ifneq (1, ${SKIP_LEGAL}) make -C buildroot legal-info @@ -152,29 +152,39 @@ build/rootfs.cpio.gz: buildroot/output/images/rootfs.cpio.gz | build make -C buildroot BUSYBOX_CONFIG_FILE=$(BR2_EXTERNAL)/board/pluto/busybox-1.25.0.config all cp $< $@ -build/$(TARGET).itb: u-boot-xlnx/tools/mkimage build/zImage build/rootfs.cpio.gz $(TARGET_DTS_FILES) build/system_top.bit - u-boot-xlnx/tools/mkimage -f scripts/$(TARGET).its $@ +build/$(PLATFORM).itb: u-boot-xlnx/tools/mkimage build/zImage build/rootfs.cpio.gz $(TARGET_DTS_FILES) build/system_top.bit + u-boot-xlnx/tools/mkimage -f scripts/$(PLATFORM).its $@ -build/system_top.xsa: | build +# HDL source dependencies - rebuild if any VHDL or TCL changes +HDL_SRCS := $(wildcard ../src/*.vhd) \ + $(wildcard ../projects/$(PLATFORM)/*.tcl) \ + $(wildcard ../library/*.tcl) \ + $(wildcard ../msk_demodulator/src/*.vhd) + +build/system_top.xsa: $(HDL_SRCS) | build ifneq ($(XSA_FILE),) cp $(XSA_FILE) $@ else ifneq ($(XSA_URL),) wget -T 3 -t 1 -N --directory-prefix build $(XSA_URL) else ifeq (1, ${HAVE_VIVADO}) -#bash -c "source $(VIVADO_SETTINGS) && make -C maia-sdr/maia-hdl/projects/$(TARGET) && cp maia-sdr/maia-hdl/projects/$(TARGET)/$(TARGET).sdk/system_top.xsa $@" -#unzip -l $@ | grep -q ps7_init || cp maia-sdr/maia-hdl/projects/$(TARGET)/$(TARGET).srcs/sources_1/bd/system/ip/system_sys_ps7_0/ps7_init* build/ -ifeq ($(TARGET),pluto) - bash -c "source $(VIVADO_SETTINGS) && make -C ../projects/pluto && cp ../projects/pluto/pluto.sdk/system_top.xsa $@" +#bash -c "source $(VIVADO_SETTINGS) && make -C maia-sdr/maia-hdl/projects/$(PLATFORM) && cp maia-sdr/maia-hdl/projects/$(PLATFORM)/$(PLATFORM).sdk/system_top.xsa $@" +#unzip -l $@ | grep -q ps7_init || cp maia-sdr/maia-hdl/projects/$(PLATFORM)/$(PLATFORM).srcs/sources_1/bd/system/ip/system_sys_ps7_0/ps7_init* build/ +ifeq ($(PLATFORM),pluto) + bash -c "source $(VIVADO_SETTINGS) && cd ../projects/pluto && unset MAKEFLAGS && /usr/bin/make && cd ../../firmware && cp ../projects/pluto/pluto.sdk/system_top.xsa $@" unzip -l $@ | grep -q ps7_init || cp ../projects/pluto/pluto.srcs/sources_1/bd/system/ip/system_sys_ps7_0/ps7_init* build/ endif -ifeq ($(TARGET),plutoplus) - bash -c "source $(VIVADO_SETTINGS) && make -C ../hdl/projects/pluto-ori-plus && cp ../hdl/projects/pluto-ori-plus/pluto.sdk/system_top.xsa $@" +ifeq ($(PLATFORM),plutoplus) + bash -c "source $(VIVADO_SETTINGS) && cd ../hdl/projects/pluto-ori-plus && unset MAKEFLAGS && /usr/bin/make && cd ../../../firmware && cp ../hdl/projects/pluto-ori-plus/pluto.sdk/system_top.xsa $@" unzip -l $@ | grep -q ps7_init || cp ../hdl/projects/pluto-ori-plus/pluto.srcs/sources_1/bd/system/ip/system_sys_ps7_0/ps7_init* build/ endif -ifeq ($(TARGET),e200) - bash -c "source $(VIVADO_SETTINGS) && make -C ../hdl/projects/pluto-ori-e200 && cp ../hdl/projects/pluto-ori-e200/e200.sdk/system_top.xsa $@" +ifeq ($(PLATFORM),e200) + bash -c "source $(VIVADO_SETTINGS) && cd ../hdl/projects/pluto-ori-e200 && unset MAKEFLAGS && /usr/bin/make && cd ../../../firmware && cp ../hdl/projects/pluto-ori-e200/e200.sdk/system_top.xsa $@" unzip -l $@ | grep -q ps7_init || cp ../hdl/projects/pluto-ori-e200/e200.srcs/sources_1/bd/system/ip/system_sys_ps7_0/ps7_init* build/ endif +ifeq ($(PLATFORM),libre) + bash -c "source $(VIVADO_SETTINGS) && make -C ../library && cd ../projects/libre && unset MAKEFLAGS && /usr/bin/make && cp libre.sdk/system_top.xsa ../../firmware/$@" + unzip -l $@ | grep -q ps7_init || cp ../projects/libre/libre.srcs/sources_1/bd/system/ip/system_sys_ps7_0/ps7_init* build/ +endif #bash -c "source $(VIVADO_SETTINGS) && make -C ../hdl/projects/pluto-ori-plus" endif @@ -184,6 +194,8 @@ build/fsbl.elf build/system_top.bit : build/system_top.xsa rm -Rf build/sdk ifeq (1, ${HAVE_VIVADO}) bash -c "source $(VIVADO_SETTINGS) && xsct scripts/create_fsbl_project.tcl" + cp build/sdk/fsbl/Release/fsbl.elf build/fsbl.elf + unzip -o build/system_top.xsa system_top.bit -d build else unzip -o build/system_top.xsa system_top.bit -d build endif @@ -194,12 +206,12 @@ ifeq (1, ${HAVE_VIVADO}) cp build/sdk/fsbl/Release/fsbl.elf build/fsbl.elf bash -c "source $(VIVADO_SETTINGS) && bootgen -image build/boot.bif -w -o $@" else - cp ori/bitstream/$(TARGET)/fsbl.elf build/fsbl.elf + cp ori/bitstream/$(PLATFORM)/fsbl.elf build/fsbl.elf bash -c "bootgen -image build/boot.bif -w -o $@" endif ### MSD update firmware file ### -build/pluto.frm: build/$(TARGET).itb +build/$(PLATFORM).frm: build/$(PLATFORM).itb md5sum $< | cut -d ' ' -f 1 > $@.md5 cat $< $@.md5 > $@ @@ -213,39 +225,46 @@ build/%.dfu: build/%.bin dfu-suffix -a $<.tmp -v $(DEVICE_VID) -p $(DEVICE_PID) mv $<.tmp $@ -build/$(TARGET).dfu: build/$(TARGET).itb +build/$(PLATFORM).dfu: build/$(PLATFORM).itb cp $< $<.tmp dfu-suffix -a $<.tmp -v $(DEVICE_VID) -p $(DEVICE_PID) mv $<.tmp $@ SDIMGDIR = build/sdimg -sdimg: build | build/rootfs.cpio.gz +sdimg: build build/fsbl.elf build/system_top.bit build/u-boot.elf build/zynq-libre.dtb build/uboot-env.txt | build/rootfs.cpio.gz mkdir -p $(SDIMGDIR) - cp ori/bitstream/$(TARGET)/fsbl.elf $(SDIMGDIR)/fsbl.elf + if [ "$(PLATFORM)" = "libre" ]; then cp build/fsbl.elf $(SDIMGDIR)/fsbl.elf; else cp ori/bitstream/$(PLATFORM)/fsbl.elf $(SDIMGDIR)/fsbl.elf; fi cp build/system_top.bit $(SDIMGDIR)/system_top.bit cp build/u-boot.elf $(SDIMGDIR)/u-boot.elf cp linux/arch/arm/boot/uImage $(SDIMGDIR)/uImage -ifeq ($(TARGET),pluto) +ifeq ($(PLATFORM),pluto) cp build/zynq-pluto-sdr.dtb $(SDIMGDIR)/devicetree.dtb endif -ifeq ($(TARGET),plutoplus) +ifeq ($(PLATFORM),plutoplus) cp build/zynq-plutoplus-maiasdr.dtb $(SDIMGDIR)/devicetree.dtb endif -ifeq ($(TARGET),e200) +ifeq ($(PLATFORM),e200) cp build/zynq-e200.dtb $(SDIMGDIR)/devicetree.dtb endif +ifeq ($(PLATFORM),libre) + cp build/zynq-libre.dtb $(SDIMGDIR)/devicetree.dtb +endif cp build/uboot-env.txt $(SDIMGDIR)/uEnv.txt + @if [ "$(PLATFORM)" = "libre" ]; then \ + echo 'sdboot=if mmcinfo; then run uenvboot; echo Copying Linux from SD to RAM... && load mmc 0 $${fit_load_address} $${kernel_image} && load mmc 0 $${devicetree_load_address} $${devicetree_image} && load mmc 0 $${ramdisk_load_address} $${ramdisk_image} && bootm $${fit_load_address} $${ramdisk_load_address} $${devicetree_load_address}; fi' >> $(SDIMGDIR)/uEnv.txt; \ + sed -i 's/serial@e0001000/serial@e0000000/g' $(SDIMGDIR)/uEnv.txt; \ + fi cp build/rootfs.cpio.gz $(SDIMGDIR)/ramdisk.image.gz mkimage -A arm -T ramdisk -C gzip -d $(SDIMGDIR)/ramdisk.image.gz $(SDIMGDIR)/uramdisk.image.gz touch $(SDIMGDIR)/boot.bif echo "img : {[bootloader] $(SDIMGDIR)/fsbl.elf $(SDIMGDIR)/system_top.bit $(SDIMGDIR)/u-boot.elf}" > $(SDIMGDIR)/boot.bif bootgen -image $(SDIMGDIR)/boot.bif -w -o i $(SDIMGDIR)/BOOT.bin - rm $(SDIMGDIR)/fsbl.elf - rm $(SDIMGDIR)/system_top.bit - rm $(SDIMGDIR)/u-boot.elf - rm $(SDIMGDIR)/ramdisk.image.gz - rm $(SDIMGDIR)/boot.bif + #rm $(SDIMGDIR)/fsbl.elf + #rm $(SDIMGDIR)/system_top.bit + #rm $(SDIMGDIR)/u-boot.elf + #rm $(SDIMGDIR)/ramdisk.image.gz + #rm $(SDIMGDIR)/boot.bif clean-build: @@ -262,8 +281,8 @@ clean: zip-all: $(TARGETS) mkdir -p Release && cd build && zip -r ../Release/$(ZIP_ARCHIVE_PREFIX)-fw-$(VERSION).zip *.dfu *.frm -dfu-$(TARGET): build/$(TARGET).dfu - dfu-util -D build/$(TARGET).dfu -a firmware.dfu +dfu-$(PLATFORM): build/$(PLATFORM).dfu + dfu-util -D build/$(PLATFORM).dfu -a firmware.dfu dfu-util -e dfu-sf-uboot: build/boot.dfu build/uboot-env.dfu @@ -272,17 +291,17 @@ dfu-sf-uboot: build/boot.dfu build/uboot-env.dfu dfu-util -D build/uboot-env.dfu -a uboot-env.dfu dfu-util -e -dfu-all: build/$(TARGET).dfu build/boot.dfu build/uboot-env.dfu +dfu-all: build/$(PLATFORM).dfu build/boot.dfu build/uboot-env.dfu echo "Erasing u-boot be careful - Press Return to continue... " && read key && \ - dfu-util -D build/$(TARGET).dfu -a firmware.dfu && \ + dfu-util -D build/$(PLATFORM).dfu -a firmware.dfu && \ dfu-util -D build/boot.dfu -a boot.dfu && \ dfu-util -D build/uboot-env.dfu -a uboot-env.dfu dfu-util -e -dfu-ram: build/$(TARGET).dfu - sshpass -p analog ssh root@$(TARGET) '/usr/sbin/device_reboot ram;' +dfu-ram: build/$(PLATFORM).dfu + sshpass -p analog ssh root@$(PLATFORM) '/usr/sbin/device_reboot ram;' sleep 7 - dfu-util -D build/$(TARGET).dfu -a firmware.dfu + dfu-util -D build/$(PLATFORM).dfu -a firmware.dfu dfu-util -e jtag-bootstrap: build/u-boot.elf build/ps7_init.tcl build/system_top.bit scripts/run.tcl scripts/run-xsdb.tcl diff --git a/firmware/ori/board/pluto/VERSIONS b/firmware/ori/board/pluto/VERSIONS index 992d770..1f3ac76 100644 --- a/firmware/ori/board/pluto/VERSIONS +++ b/firmware/ori/board/pluto/VERSIONS @@ -1,4 +1,4 @@ -device-fw b340 +device-fw e2a4 buildroot 2022.02.3-adi-5712-gf70f4a -linux adi-xilinx-2020.1-175882-ge14e351 -u-boot-xlnx v0.20-PlutoSDR-25-g90401c +linux v5.15-20952-ge14e351 +u-boot-xlnx v0.20-PlutoSDR-25-g90401c-dirty diff --git a/firmware/ori/board/pluto/overlay/root/fwhistory.txt b/firmware/ori/board/pluto/overlay/root/fwhistory.txt index 2607012..470122c 100644 --- a/firmware/ori/board/pluto/overlay/root/fwhistory.txt +++ b/firmware/ori/board/pluto/overlay/root/fwhistory.txt @@ -1,3 +1,229 @@ +e2a45a7 - Sun Nov 30 23:20:46 2025 -0800 : transmitter stall resolved. had 134 as loop limit when needed 268. +77336cb - Thu Nov 27 18:35:05 2025 -0800 : Prevent Vivado from optimizing away data paths. I think synthesis was tracing through the PRBS mux and determining that the entire TX data path was unused, and then removed the deserializer, the encoder_tdata buses, fifo_tadatoutputs (which gave a no routable loads warning that tipped me off) and tx_data_bit signal. Added do not touch attributes to preserve evertyhing. This may have been the reason we were stalling. +501c991 - Thu Nov 27 16:30:10 2025 -0800 : Revert "Change the encoder to deassert tvalid unconditionally after frame completion. Don't wait for tready." because it did not work in simulation. +44356f2 - Thu Nov 27 16:26:25 2025 -0800 : Change the encoder to deassert tvalid unconditionally after frame completion. Don't wait for tready. +cd5f27c - Thu Nov 27 11:03:52 2025 -0800 : decoder created a stall with no gaps between frames. this is a fix for that. works in encoder-decoder testbench and end-to-end testbench. +247bead - Wed Nov 26 08:40:30 2025 -0800 : experiment to isolate encoder as source of lab hardware transmitter stall +2cc8fa5 - Tue Nov 25 09:56:43 2025 -0800 : simulation now working with yet again the count back from tlast method working for us. added a lot of comments about this to the source code. +a563e0a - Mon Nov 24 19:41:21 2025 -0800 : simulation looks good for byte level interleaver. byte vs bit now optional. +184aa7d - Mon Nov 24 18:49:17 2025 -0800 : works in simulation, comes under LUT limit for PLUTO, but doesn't route. Right before generate byte vs bit interleaver option installed. +dbc5a1f - Mon Nov 24 17:31:36 2025 -0800 : end to end data corruption resolved. input equals output. +af474e7 - Sun Nov 23 12:46:56 2025 -0800 : seg fault resolved. needs testing on full test bench on mymelody. +e4ce3c2 - Thu Nov 20 22:36:48 2025 -0800 : input matches output but firmware build seg faults. Please send help. +8ba0705 - Thu Nov 20 14:29:21 2025 -0800 : hard decision Viterbit decoder installed and input data equals output data to modem. Randomization, FEC, Interleaving all working as intended. +eae5b60 - Wed Nov 19 23:45:26 2025 -0800 : added hard decision convolutional encoder and decoder +f9b7ab0 - Wed Nov 19 08:04:14 2025 -0800 : new encoder and decoder files added to the list in msk_top_ip.tcl +e0ddf29 - Tue Nov 18 22:21:07 2025 -0800 : data now good in loopback - defeated tricky FIFO to encoder timing bug +7708fd8 - Mon Nov 17 20:03:41 2025 -0800 : encoder and decoder tested in loopback and pass. encoder and decoder then installed in msk_top.vhd. Compiles clean. +628ca20 - Fri Nov 14 18:00:14 2025 -0800 : Improved reset of FIFO read and write pointers. Works in sim and hardware. +6174fd3 - Fri Nov 14 14:05:07 2025 -0700 : rdl: update frame sync status register descriptions. +19c15f1 - Wed Nov 12 22:38:44 2025 -0700 : rdl: update outputs +cfd64ea - Wed Nov 12 21:30:12 2025 -0700 : rdl: add requested rx frame sync status register +1c55316 - Tue Nov 11 20:42:45 2025 -0800 : Clean up signal initializations in AXIS components +ffc877c - Tue Nov 11 20:22:32 2025 -0800 : Merge initialization cleanup from test-init-removal Clean up signal initializations following FPGA best practices. All signals now properly reset-initialized with clear documentation. +7948a30 - Tue Nov 11 20:20:58 2025 -0800 : Remove unnecessary signal initializations and fix missing counter resets +18ed769 - Tue Nov 11 18:49:02 2025 -0800 : Revert frame_sync_detector.vhd - initialization changes inadvertently moved byte_shift_reg shifting inside state machine, causing data corruption +7d7a5f0 - Tue Nov 11 15:53:16 2025 -0800 : Merge branch 'peakrdl' of https://github.com/OpenResearchInstitute/pluto_msk into peakrdl +5976835 - Tue Nov 11 15:47:33 2025 -0800 : resolved issue number 22 with comments to distinguish between signals that must be initialized and signals where the initialization can and was removed +a767c1c - Sat Nov 8 10:12:54 2025 -0700 : rdl: output artifacts +0cf8b61 - Sat Nov 8 10:11:11 2025 -0700 : rdl: register description improvements +6aeaa74 - Sat Nov 8 01:39:25 2025 -0800 : SYNC_TRANSFER_START is asking for a separate external sync signal, not using TLAST as a trigger. TLAST already works automatically with the AXIS DMA. It marks frame boundaries and the DMA respects it without needing any special config. SYNC_TRANSFER_START was erroneously set to TRUE, which overrode the FALSE setting in the ADC DMA block in system_bd.tcl. Once this was fixed, rx_buffer_refill() no longer timed out and data is being seen by the processor side application. +9eb101e - Fri Nov 7 23:00:32 2025 -0800 : Add XSim testbench support with PeakRDL compatibility +169f9bd - Fri Nov 7 13:07:32 2025 -0800 : merging edits from main to peakrdl, resolving conflicts to include the debug registers from sync_detect, and publishing the updated branch +0613fd1 - Fri Nov 7 12:51:55 2025 -0800 : Reset hdl submodule to match main +1e2defc - Fri Nov 7 10:10:12 2025 -0800 : Merge pull request #21 from OpenResearchInstitute/sync_detect +a908758 - Thu Nov 6 11:08:42 2025 -0700 : sim: add readback of power register +eadbfcb - Thu Nov 6 11:07:54 2025 -0700 : rdl: update register descriptions, add HTML output +4641dc5 - Tue Nov 4 20:57:11 2025 -0800 : Fix critical async FIFO bugs causing frame corruption. Remove 3-byte safety margin that prevented last bytes from being read, fix stale tvalid_int causing runaway read pointer, remove becoming_empty check that blocked last byte output, clear TLAST when FIFO becomes empty +17471be - Tue Nov 4 19:41:07 2025 -0800 : potential fix +fce224f - Tue Nov 4 12:22:17 2025 -0700 : rdl: update descriptions for write-to-capture registers +e0dd889 - Tue Nov 4 11:47:28 2025 -0700 : rdl: move away from external registers to a write to capture model +5ce1cee - Tue Nov 4 00:00:05 2025 -0800 : first byte of first frame was crushed! bug that caused it was then crushed. +b9c4c36 - Mon Nov 3 11:29:14 2025 -0800 : set safety margin to zero without any other changes +3df04a7 - Thu Oct 30 12:31:04 2025 -0700 : Fix hdl submodule pointer to correct stable commit 1978df298 +bc8ebdf - Thu Oct 30 12:20:26 2025 -0700 : reset the shift register to zero right before VERIFYING_SYNC +56cce9d - Thu Oct 30 12:09:26 2025 -0700 : Merge pull request #18 from OpenResearchInstitute/fix-hdl-submodule-revert +c150319 - Wed Oct 29 13:42:51 2025 -0700 : Update msk_demodulator to e837e29 (includes rx_dec_lbk_ena) +39642f7 - Wed Oct 29 13:25:43 2025 -0700 : Also revert msk_demodulator to 6b3e9bd (fixes costas_loop.vhd missing file) +3ed613c - Wed Oct 29 12:57:34 2025 -0700 : Revert hdl submodule to 1978df2 (fixes build breakage from 2c5e472 conferred with KB5MU) +dc22efd - Wed Oct 29 00:55:10 2025 -0600 : Update regmap in README.md +4c3e9b2 - Tue Oct 28 07:21:23 2025 -0700 : flywheel frame synchronization starting to work +86943dd - Mon Oct 27 19:10:56 2025 -0700 : added cdc_resync.vhd pulse_detect.vhd and data_capture.vhd to add ip files list in librar/msk_top_ip.tcl +d821407 - Mon Oct 27 18:54:16 2025 -0700 : vhdl2008 added to msk_top_regs.vhd. Should be the last one? +cfe0a80 - Mon Oct 27 18:45:26 2025 -0700 : vhdl2008 added to reg_utils.vhd to resolve errors +e3c30b9 - Mon Oct 27 18:38:30 2025 -0700 : cast the wrong spell but fixed it to /rdl/outputs/rtl/msk_top_regs.vhd +5266d12 - Mon Oct 27 18:30:08 2025 -0700 : changed path from rdl/vhdl/msk_top_regs/ to rdl/outputs/rtl +0550e64 - Mon Oct 27 18:23:37 2025 -0700 : removed desyrdl package from /library/msk_top_ip.tcl build script +a56c29b - Mon Oct 27 18:22:41 2025 -0700 : added reg_utils.vhd to /library/msk_top_ip.tcl build script +bdac6a3 - Mon Oct 27 18:57:00 2025 -0600 : Remove rdl/vhdl folder and contents, revert USE library to work.msk_top_regs_pkg in msk_top_csr.vhd +86fd5cb - Mon Oct 27 17:47:19 2025 -0700 : changed sync word from concatenated Barker code with PSLR of 3:1 to an optimized 24 bit sequence that has a PSLR of 8:1 +3558ba2 - Mon Oct 27 17:16:21 2025 -0700 : there was a name mismatch so I changed it to match like this: USE work.axi4lite_intf_pkg.ALL; --USE work.msk_top_regs_pkg.ALL; USE work.pkg_msk_top_regs.ALL; +b23e0f8 - Mon Oct 27 17:05:08 2025 -0700 : putting read_vhdl pkg_msk_top_regs.vhd up above, and making sure 2008 is called out for /axi4lite_intf_pkg.vhd +a0e1f6f - Mon Oct 27 16:34:44 2025 -0700 : added /rdl/src/axi4lite_intf_pkg.vhd to the IP list in /pluto_msk/library/msk_top_ip.tcl +5da15eb - Mon Oct 27 16:22:24 2025 -0700 : added = '1' to rd_status_req_sync2 test in order to gresolve implicit type cast from std_logic to boolean. Now make will work. +ccd7b74 - Mon Oct 27 16:14:29 2025 -0700 : added the = '1' so implicit type casting from std_logic to boolean won't derail the firmware build +4923b1f - Sun Oct 26 23:55:56 2025 -0600 : Fix fifo pointer read +ca022b9 - Sun Oct 26 23:35:31 2025 -0600 : Add read back of async FIFO read/write pointers +3cf82bb - Sun Oct 26 21:46:34 2025 -0600 : Resolve merge/rebase conflicts +860deae - Sun Oct 26 20:46:59 2025 -0600 : CDC updates for CSRs and PeakRDL transition complete +7e15c4a - Sat Oct 25 23:17:28 2025 -0600 : Switch from desyrdl to peakrdl for sysrdl +80de180 - Fri Oct 24 18:41:43 2025 -0700 : Merge pull request #16 from OpenResearchInstitute/sync_detect +844df58 - Fri Oct 24 17:52:32 2025 -0700 : converted from LSB to MSB because pain +0893335 - Fri Oct 24 00:19:34 2025 -0700 : clean up m_axis interface to try to get Dialogus to notice it. Didn't seem to work. Simulation looks pretty good. +dc55ddb - Thu Oct 23 22:22:25 2025 -0700 : m_axis_tlast at proper rate +3e28193 - Thu Oct 23 20:17:51 2025 -0700 : new state machine instead of boolean to fix receive framing AXIS comms +a0ea65f - Thu Oct 23 20:12:07 2025 -0700 : receiver to PS FIFO re-reading old data bug fix +4054a0e - Thu Oct 23 18:08:18 2025 -0700 : Merge pull request #15 from OpenResearchInstitute/sync_detect +81f762c - Thu Oct 23 17:03:10 2025 -0700 : prog_empty going high in Arizona desert fixed in sim +64c8120 - Wed Oct 22 22:29:41 2025 -0700 : increase FIFO size temporarily to rule in or out FIFO management problem +e522861 - Wed Oct 22 22:13:54 2025 -0700 : attempting to put the FIFOs in BRAM with block attributes +ebc47ab - Wed Oct 22 20:18:48 2025 -0700 : output_active was being multiply driven, and with this commit, it is now acting the way we intended. This might be causing the hardware failures we are observing. It did not cause a simulation failure because the result was X, and in simulations, those propagate through the sim and don't stop anything from working. +9712241 - Tue Oct 21 23:04:00 2025 -0700 : set up internal signals for prog_full and prog_empty to gate behavior +a2dbdde - Tue Oct 21 22:11:19 2025 -0700 : now using prog_full instead of hard limit for FIFO backpressure +51c60ef - Tue Oct 21 20:36:21 2025 -0700 : backpressure from msk_top to DMA controller to processor side added +2caa3fe - Tue Oct 21 07:13:21 2025 -0700 : Frame sync detect beginning to work +7fb9def - Fri Oct 17 23:07:52 2025 -0700 : sync word detect compiles cleanly and now we are figuring out how to manage receive buffer before the sync word is detected +53e9e65 - Fri Oct 17 16:47:43 2025 -0700 : Merge pull request #14 from OpenResearchInstitute/axis_fifo +72c4cfa - Thu Oct 16 22:22:02 2025 -0700 : bit order now correct and sync word visually verified in receive buffer in Dialogus +5d60cea - Thu Oct 16 21:32:23 2025 -0700 : bit counter correctly initialized, but the bit order is reversed from what it should be. +83b1c67 - Thu Oct 16 18:06:13 2025 -0700 : Add AXI stream frame-based transmission with continuous TVALID flow control. Implements Opulent Voice protcol support with lowest byte extraction from the DMA transfer, implements a dual-clock FIFO to handle clock domain crossing and TLAST for frame boundaries, and prepends the 3 byte sync word. Original parallel to serial converter in msk_top.vhd was replaced. The differential loopback encoder loopback ports were connected. The design was validated in tb_msk_frame_axistream_debug.vhd testbench, with continuous TVALID behavior matching DMA operation, 10 frames tested through the 2048 FIFO, backpressure and flow control validated, and verified zero data loss, proper TREADY toggling when capacity was reached. Waveforms were captured and the FIFO internal state was checked. There are some new files and the system_bd.tcl and ip files were updated. s_axis port names still need to be standardized (s_axis_valid vs s_axis_tvalid), the FIFO is kind of large. It might could be reduced in size. Differential decoder might need some checking. Frame sync word detection on RX side not yet implemented. Tested in simulation and in PLUTO SDR hardware with Dialogus. +aa68694 - Sun Oct 12 00:45:45 2025 -0600 : Fix tx_bit_counter to count modem bit requests +4e20ac7 - Sat Oct 11 22:37:02 2025 -0600 : Fix bug in parallel to serial converter +8e60dd5 - Fri Oct 10 14:33:51 2025 -0700 : Merge pull request #12 from OpenResearchInstitute/thirty_two_bit +468a599 - Fri Oct 10 14:30:24 2025 -0700 : Merge main into thirty_two_bit, use main's msk_demodulator version +2c5e472 - Fri Oct 10 13:47:24 2025 -0700 : Update submodule references +b38b542 - Thu Oct 9 23:41:44 2025 -0600 : New differential encoder; differential encoder loopback +246de80 - Tue Oct 7 18:08:29 2025 -0700 : DMAC source and destination addresses changed from 64 to 32 and S_AXIS_DATA_W changed from 64 to 32, to match Dialogus, allow for TLAST without requiring TKEEP for 134 byte frame, and to match DVB-S2 encoder data width. +1c18ff4 - Thu Mar 27 20:51:03 2025 -0600 : mod: update for sequencer +3d8949a - Thu Feb 13 03:05:55 2025 +0000 : Update system_project.tcl to configure ILA insertion +5400418 - Thu Feb 13 00:39:14 2025 +0000 : Set ADI CONFIG variables to leave out unused modules which should increase space for the MSK design +96b804f - Tue Feb 11 18:39:43 2025 -0700 : EMA: Refactor code to more optimally map operations onto Zynq DSP slice +070bdea - Tue Feb 11 10:46:58 2025 -0700 : PD: Added GENERIC to enable cascaded EMAs +7df7081 - Mon Feb 10 16:27:40 2025 -0700 : EMA: Fix average_ena signal and remove VHDL 2008 constructs +3f8e522 - Mon Feb 10 20:43:43 2025 +0000 : LIB: Update modules list in msk_top_ip.tcl +34ad475 - Mon Feb 10 20:35:27 2025 +0000 : LIB: Update Makefile to build lowpass_ema and power_detector; PROJ: Connect complex I/Q inputs from DAC to msk_top +24cfa33 - Mon Feb 10 17:55:40 2025 +0000 : Update .gitmodules +11f3262 - Sat Feb 8 22:08:49 2025 -0700 : EMA: Update README.md contents +cf8452b - Sat Feb 8 22:04:17 2025 -0700 : PD: add README.md contents +229b312 - Sat Feb 8 17:39:32 2025 -0700 : Add lowpass_ema and power_detector submodules +16f581f - Sat Feb 8 17:36:58 2025 -0700 : MOD: add tx sync transmission; TOP: integrate IQ power detector +7a26f7b - Fri Jan 24 05:15:28 2025 +0000 : Connect tx_samples_q output to DAC Q input +a943cbc - Tue Jan 21 20:16:57 2025 -0700 : MSK_TOP: updates for quadrature I/Q outputs +43c3c3f - Tue Jan 21 20:14:17 2025 -0700 : DEMOD: Update block diagrams with Q-notation +0bd4e1e - Tue Jan 21 20:12:45 2025 -0700 : MOD: Modulate both sin and cos from NCO to create quadrature I/Q outputs +e931fa5 - Tue Jan 21 20:10:05 2025 -0700 : PI: add block diagram with Q-notation +b182430 - Sat Dec 14 23:36:15 2024 -0700 : Replace Massey's sequencer/decoder with Hodgart's differential encoder/decoder. Other minor updates. +5ce1507 - Tue Dec 3 20:45:31 2024 -0700 : Add observation points for F1/F2 NCO adjustment and loop error +8ee4509 - Tue Nov 26 22:34:18 2024 -0700 : Remove merge leftovers +112b90d - Mon Nov 25 16:54:59 2024 -0700 : Update batch_insert_ila.tcl script path +9a69b43 - Mon Nov 25 13:25:39 2024 -0700 : Update msk_top_regs.pdf +5ebb6ea - Mon Nov 25 13:24:44 2024 -0700 : Merge branch 'debug' +00abec6 - Mon Nov 25 13:03:30 2024 -0700 : Update README.md +b89fc61 - Mon Nov 25 11:53:45 2024 -0700 : Add wider PI gains and programmable shift for division by 2^-n +954a9d8 - Mon Nov 25 11:52:03 2024 -0700 : Add wider PI gains and programmable shift for division by 2^-n +d501758 - Tue Nov 19 14:00:51 2024 -0700 : simulation update +2a65906 - Tue Nov 19 13:46:47 2024 -0700 : pi controller: update to scale coefficients by 1/4096 rather than 1/256 +e18061a - Tue Nov 19 13:46:21 2024 -0700 : demod and costas: update error accumulator to only accumulator on effective sample clock +e392c9d - Tue Nov 19 13:44:43 2024 -0700 : top: update sample discard logic and sample clock generation +56b4e23 - Tue Nov 19 13:47:01 2024 -0700 : Simulation updates +779a939 - Tue Nov 19 13:46:47 2024 -0700 : pi controller: update to scale coefficients by 1/4096 rather than 1/256 +9991412 - Tue Nov 19 13:46:21 2024 -0700 : demod and costas: update error accumulator to only accumulator on effective sample clock +2e50913 - Tue Nov 19 13:44:43 2024 -0700 : top: update sample discard logic and sample clock generation +d542a97 - Tue Nov 12 12:08:25 2024 -0700 : MSK_MOD: add signals for ILA +3a25d23 - Tue Nov 12 00:20:13 2024 -0700 : MSK_MOD: Update mark_debug* attributes +7cecf51 - Mon Nov 11 20:11:12 2024 -0700 : Split Init into separate Tx and Rx Inits, as well as a 'global' init that asserts both Tx and Rx. Bit 0 of the MSK_Init register will still Init both Tx and Rx, so this is not a breaking change +2f76b0f - Mon Nov 11 20:11:12 2024 -0700 : Split Init into separate Tx and Rx Inits, as well as a 'global' init that asserts both Tx and Rx. Bit 0 of the MSK_Init register will still Init both Tx and Rx, so this is not a breaking change +19ea33e - Wed Nov 6 14:38:49 2024 -0700 : MSK_MOD: Fix mark_debug_depth attribute +2ec606c - Wed Nov 6 13:10:53 2024 -0700 : Add ILA script and updated msk_modulator with ILA attributes included. +6bbf013 - Mon Nov 4 22:05:28 2024 -0700 : Fix RDL for new register width and rw setting +96a0401 - Sun Nov 3 16:28:35 2024 -0700 : MSK_DEMOD:Add NCO sample discard capability, move tclk_dly assignment out of IF statement +f32b4fd - Sun Nov 3 16:26:03 2024 -0700 : MSK_MOD: Set discard_nco inputs to NCO to 0. +46fed46 - Sun Nov 3 16:25:07 2024 -0700 : PI: Updated P-gain divider from 16 to 256 +f8c6ce3 - Sun Nov 3 16:06:56 2024 -0700 : NCO: add sample discard +634aab1 - Sun Nov 3 16:06:17 2024 -0700 : Update simulation +5d5bbf1 - Sun Nov 3 16:05:26 2024 -0700 : MSK_TOP: update Rx sample discard logic +c781942 - Sun Nov 3 16:04:27 2024 -0700 : Added register for Rx NCO sample discard, moved Rx sample discard to same register. +b783e04 - Mon Oct 28 23:30:24 2024 -0600 : Simulation updates +07de961 - Mon Oct 28 23:29:04 2024 -0600 : Update Makefile for GHDL +05c74dc - Mon Oct 28 23:28:44 2024 -0600 : PRBS_MON: Zero LFSR at start of sync +daae161 - Mon Oct 28 23:28:01 2024 -0600 : Remove loopback_ena OR from rx_svalid port mapping to enable sample discard mode during loopback. +81c229c - Fri Oct 25 20:12:41 2024 -0600 : MSK_DEMOD: Remove 'signed' casting in Costas Loop low-pass filter +f956290 - Thu Oct 24 18:55:25 2024 -0600 : Add missing initial values in RDL source +e428057 - Thu Oct 24 18:53:49 2024 -0600 : MSK_DEMOD: Fix port mapping for Costas Loop 'enable' input. +7acf28e - Wed Oct 23 08:31:17 2024 -0700 : Merge pull request #7 from OpenResearchInstitute/clarify-vivado-path +362b110 - Mon Oct 21 20:32:01 2024 -0700 : Clarify Vivado path in README +54c8952 - Thu Oct 17 09:51:35 2024 -0700 : Merge pull request #5 from OpenResearchInstitute/Makefile +19d2716 - Wed Oct 16 20:16:58 2024 -0700 : Update MSK_CONTROL register to add reserved field between lower and upper fields. +7737f0d - Tue Oct 15 01:38:04 2024 +0000 : Update Makefile +6538fd6 - Wed Oct 9 15:46:07 2024 -0600 : Fix loopback operation by asserting tx_valid and rx_valid when loopback is enabled. +10f5477 - Wed Oct 9 15:45:11 2024 -0600 : PI Controller: Fixed data scaling issue in proportional path +a2497b6 - Sun Oct 6 23:59:22 2024 -0600 : Update simulation +9e5c2e1 - Sun Oct 6 21:57:57 2024 -0600 : Updates for msk_demodulator to fix data scaling issue +77b3b53 - Sat Oct 5 23:23:42 2024 -0600 : Updates for msk_modulator to allow operation at correct F1/F2 +6c4c2ea - Tue Oct 1 22:04:43 2024 -0600 : Add relevant MSK papers. +e97e804 - Fri Sep 27 07:41:46 2024 -0600 : Update MSK Status registers so that register IDs and naming are consistent (both 0-indexed) +ed7a35a - Wed Sep 25 23:22:35 2024 -0600 : Updated README.md register map +0cf7298 - Wed Sep 25 23:19:09 2024 -0600 : Added and improved status/diagnostics registers +6831b7d - Wed Sep 25 02:01:03 2024 -0600 : Simulation update +24d96c1 - Tue Sep 24 14:11:30 2024 -0600 : Merge remote-tracking branch 'origin/dev-rdl' +9b31d59 - Fri Sep 20 00:09:21 2024 -0600 : Update design to support PRBS toggle control and auto sync. +e4bc1a2 - Fri Sep 20 00:07:18 2024 -0600 : Fixed issues with RDL where unused bits between fields resulted in multi-driven nets. +bff3fa9 - Thu Sep 19 23:35:30 2024 -0600 : Minor update to PRBS. +f8fc975 - Thu Sep 19 23:22:29 2024 -0600 : Update SystemRDL to add PRBS Auto Sync Threshold field in PRBS Control Register. +c4349ba - Thu Sep 19 23:08:48 2024 -0600 : Simulation updates for PRBS seed. +e8dd707 - Thu Sep 19 23:06:25 2024 -0600 : PRBS module with auto-sync and TOGGLE_ENABLE capabilities. +c52688a - Mon Sep 16 00:47:47 2024 -0600 : Simulation updates: LPF gains and turn on Rx Invert +9909f97 - Sun Sep 15 23:27:31 2024 -0600 : Simulations updates +4b4df2d - Sun Sep 15 23:15:48 2024 -0600 : PRBS Updates +90c51a9 - Tue Aug 6 16:14:18 2024 +0200 : Signed integer represenation +a9c94a6 - Sun Aug 4 22:46:09 2024 -0600 : Update firmware pluto_msk_prbs.sh script +7adf0ca - Sun Aug 4 22:44:27 2024 -0600 : Update to allow decimation (discarding) of Rx samples. New registers added to support separate Tx and Rx F1/F2 NCOs. +b7cbc8d - Sun Aug 4 22:42:15 2024 -0600 : Update README with new regs and start of Theory of operation. +0fb49cf - Sun Aug 4 20:14:39 2024 +0200 : Add register cmd +f2a0a7b - Sun Aug 4 20:12:37 2024 +0200 : display register address in hex +d57f778 - Sun Aug 4 11:25:43 2024 +0200 : Fix prbs and display decimal status +f7c14af - Sat Aug 3 11:30:26 2024 +0200 : Add mqtt scripts and prbs test +1e2fd74 - Fri Aug 2 00:07:30 2024 -0600 : Add pi controller accumulator read registers +3cb22b1 - Thu Aug 1 21:58:13 2024 -0600 : Various RDL updates and README.md update from RDL markdown +8e04258 - Tue Jul 30 15:03:19 2024 -0600 : Add PeakRDL artifacts for c-header and markdown +6b01682 - Tue Jul 30 16:00:24 2024 +0000 : Update README.md +4c6feef - Tue Jul 30 09:57:19 2024 -0600 : Rename DFU RAM load script, and add modemtest.sh. The latter needs some updates, but is useful, and portions added to the prbs script +7368bc3 - Tue Jul 30 09:54:08 2024 -0600 : Added DFU RAM load script +b111663 - Tue Jul 30 09:41:03 2024 -0600 : Add rx_invert section and fix PRBS configurations +13d48e3 - Tue Jul 30 16:42:13 2024 +0200 : Update README.md with perf on building on i7 +b6b5a95 - Tue Jul 30 14:06:54 2024 +0000 : Update README.md +6d8e4de - Tue Jul 30 12:44:28 2024 +0000 : Update README.md +6b4faee - Tue Jul 30 11:15:55 2024 +0200 : Fix typo address and deinit in script +95c96b8 - Tue Jul 30 05:56:41 2024 +0000 : Update README.md +5da70a7 - Mon Jul 29 21:16:40 2024 -0600 : Add PRBS scripts for pluto +634259b - Mon Jul 29 15:52:31 2024 -0600 : Remove unused signals from RTL +161d0df - Mon Jul 29 15:49:43 2024 -0600 : Update library build for RDL library +fa8e689 - Mon Jul 29 14:35:07 2024 -0600 : Updates for RDL registers +1f24fd2 - Mon Jul 29 13:07:54 2024 -0600 : Rename library to pkg_msk_top_regs +ac11dc5 - Mon Jul 29 12:56:53 2024 -0600 : Pull in msk_top.vhd with RDL wrapper instantiated +8b8fbc0 - Mon Jul 29 12:45:48 2024 -0600 : Merge pull request #2 from OpenResearchInstitute/dev +ce18bf9 - Mon Jul 29 12:36:01 2024 -0600 : Fix sim Makefile to use the submodules +d9dccc7 - Mon Jul 29 11:22:49 2024 -0600 : Add RDL files in msk_top_ip.tcl +5b1deb3 - Mon Jul 29 11:19:50 2024 -0600 : Update simulation files +1bfdfc4 - Mon Jul 29 10:55:16 2024 -0600 : Add RDL doc and cocotb artifacts +7e109e4 - Mon Jul 29 10:53:44 2024 -0600 : Add DesyRDL RTL artificacts +4bae155 - Mon Jul 29 10:46:28 2024 -0600 : Update msk_top_ip.tcl to add RDL wrapper +71c42e0 - Mon Jul 29 10:42:59 2024 -0600 : Add RDL wrapper +4faaa74 - Mon Jul 29 10:40:49 2024 -0600 : Add RDL files +56761b3 - Wed Jul 24 18:24:10 2024 +0000 : Update README.md +5da5307 - Wed Jul 24 17:08:43 2024 +0000 : Update README.md +28cec80 - Wed Jul 24 17:03:59 2024 +0000 : Update README.md +352ac73 - Wed Jul 24 16:21:10 2024 +0000 : Update README.md +133355c - Wed Jul 24 15:11:24 2024 +0000 : Update README.md +ff762fa - Wed Jul 24 03:58:50 2024 +0000 : Update README.md +af75a7f - Wed Jul 24 03:42:38 2024 +0000 : Update README.md +9a67af1 - Wed Jul 24 03:39:58 2024 +0000 : Update README.md +8e9d1c8 - Wed Jul 24 03:34:23 2024 +0000 : Update README.md +af79961 - Wed Jul 24 03:28:45 2024 +0000 : Update README.md +26a71d1 - Tue Jul 23 13:03:39 2024 +0200 : Instructions for vivado path +871bd13 - Tue Jul 23 12:38:39 2024 +0200 : Update README.md for firmware instructions +8c79132 - Tue Jul 23 12:31:01 2024 +0200 : Initial pluto-ori firmware +75611ec - Mon Jul 22 21:57:40 2024 +0000 : Update README.md b3406b7 - Mon Jul 22 22:30:47 2024 +0200 : Add firmware submodules 942aa51 - Mon Jul 22 19:35:30 2024 +0000 : Update README.md 4c0ea7c - Mon Jul 22 19:11:04 2024 +0000 : Update README.md diff --git a/firmware/ori/libre/buildroot-configs/zynq_libre_defconfig b/firmware/ori/libre/buildroot-configs/zynq_libre_defconfig new file mode 100644 index 0000000..0692d2d --- /dev/null +++ b/firmware/ori/libre/buildroot-configs/zynq_libre_defconfig @@ -0,0 +1,68 @@ +BR2_arm=y +BR2_cortex_a9=y +BR2_ARM_ENABLE_NEON=y +BR2_ARM_ENABLE_VFP=y +BR2_ARM_FPU_NEON=y +BR2_TOOLCHAIN_EXTERNAL=y +BR2_TOOLCHAIN_EXTERNAL_LINARO_ARM=y +BR2_OPTIMIZE_3=y +BR2_PACKAGE_ETHTOOL=y +BR2_PACKAGE_ETHTOOL_PRETTY_PRINT=y +BR2_PACKAGE_IPERF3=y +BR2_PACKAGE_HTOP=y +BR2_TARGET_GENERIC_HOSTNAME="libre" +BR2_TARGET_GENERIC_ISSUE="Welcome to LibreSDR" +BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_MDEV=y +BR2_TARGET_GENERIC_ROOT_PASSWD="analog" +BR2_TARGET_GENERIC_GETTY_PORT="ttyPS0" +BR2_ROOTFS_POST_BUILD_SCRIPT="board/libre/post-build.sh" +BR2_PACKAGE_ZSTD=y +BR2_PACKAGE_MTD=y +# BR2_PACKAGE_MTD_NANDDUMP is not set +# BR2_PACKAGE_MTD_NANDTEST is not set +# BR2_PACKAGE_MTD_NANDWRITE is not set +# BR2_PACKAGE_MTD_UBIATTACH is not set +# BR2_PACKAGE_MTD_UBICRC32 is not set +# BR2_PACKAGE_MTD_UBIDETACH is not set +# BR2_PACKAGE_MTD_UBIFORMAT is not set +# BR2_PACKAGE_MTD_UBIMKVOL is not set +# BR2_PACKAGE_MTD_UBINFO is not set +# BR2_PACKAGE_MTD_UBINIZE is not set +# BR2_PACKAGE_MTD_UBIRENAME is not set +# BR2_PACKAGE_MTD_UBIRMVOL is not set +# BR2_PACKAGE_MTD_UBIRSVOL is not set +# BR2_PACKAGE_MTD_UBIUPDATEVOL is not set +# BR2_PACKAGE_MTD_UBIBLOCK is not set +BR2_PACKAGE_LINUX_FIRMWARE=y +BR2_PACKAGE_LINUX_FIRMWARE_RALINK_RT61=y +BR2_PACKAGE_LINUX_FIRMWARE_RALINK_RT73=y +BR2_PACKAGE_LINUX_FIRMWARE_RALINK_RT2XX=y +BR2_PACKAGE_LINUX_FIRMWARE_RTL_81XX=y +BR2_PACKAGE_LINUX_FIRMWARE_RTL_87XX=y +BR2_PACKAGE_LINUX_FIRMWARE_RTL_88XX=y +BR2_PACKAGE_INPUT_EVENT_DAEMON=y +BR2_PACKAGE_UBOOT_TOOLS=y +BR2_PACKAGE_ZLIB=y +BR2_PACKAGE_LIBAD9361_IIO=y +BR2_PACKAGE_LIBGPIOD=y +BR2_PACKAGE_LIBGPIOD_TOOLS=y +BR2_PACKAGE_LIBIIO_IIOD_USBD=y +BR2_PACKAGE_LIBIIO_TESTS=y +BR2_PACKAGE_LIBINI=y +BR2_PACKAGE_AVAHI=y +BR2_PACKAGE_AVAHI_DAEMON=y +BR2_PACKAGE_AVAHI_LIBDNSSD_COMPATIBILITY=y +BR2_PACKAGE_DROPBEAR=y +BR2_PACKAGE_DROPBEAR_LOCALOPTIONS_FILE="board/pluto/dropbrear_localoptions.h" +BR2_PACKAGE_IW=y +BR2_PACKAGE_WPA_SUPPLICANT=y +BR2_PACKAGE_WPA_SUPPLICANT_CLI=y +BR2_PACKAGE_WPA_SUPPLICANT_PASSPHRASE=y +BR2_PACKAGE_POLL_SYSFS=y +BR2_PACKAGE_AD936X_REF_CAL=y +BR2_TARGET_ROOTFS_CPIO=y +BR2_TARGET_ROOTFS_CPIO_GZIP=y +BR2_TARGET_ROOTFS_CPIO_UIMAGE=y +BR2_PACKAGE_HOST_DOSFSTOOLS=y +BR2_PACKAGE_HOST_GENIMAGE=y +BR2_PACKAGE_HOST_MTOOLS=y \ No newline at end of file diff --git a/firmware/ori/libre/linux-configs/zynq_libre_linux_defconfig b/firmware/ori/libre/linux-configs/zynq_libre_linux_defconfig new file mode 100644 index 0000000..73790cc --- /dev/null +++ b/firmware/ori/libre/linux-configs/zynq_libre_linux_defconfig @@ -0,0 +1,286 @@ +CONFIG_SYSVIPC=y +CONFIG_USELIB=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_PREEMPT=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_LOG_BUF_SHIFT=15 +CONFIG_CGROUPS=y +CONFIG_BLK_DEV_INITRD=y +# CONFIG_RD_BZIP2 is not set +# CONFIG_RD_LZMA is not set +# CONFIG_RD_XZ is not set +# CONFIG_RD_LZO is not set +# CONFIG_RD_LZ4 is not set +CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE_O3=y +CONFIG_EMBEDDED=y +CONFIG_PERF_EVENTS=y +CONFIG_SLAB=y +CONFIG_ARCH_ZYNQ=y + + +CONFIG_MMC=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_OF_ARASAN=y + +CONFIG_UEVENT_HELPER=y +CONFIG_MACB=y +CONFIG_MDIO_BITBANG=y +CONFIG_MARVELL_PHY=y +CONFIG_XILINX_GMII2RGMII=y +CONFIG_USB_NET_DM9601=y + +CONFIG_XILINX_RESET_CODE=y +CONFIG_PL310_ERRATA_588369=y +CONFIG_PL310_ERRATA_727915=y +CONFIG_PL310_ERRATA_769419=y +# CONFIG_ARM_ERRATA_643719 is not set +CONFIG_ARM_ERRATA_754322=y +CONFIG_ARM_ERRATA_754327=y +CONFIG_ARM_ERRATA_764369=y +CONFIG_ARM_ERRATA_775420=y +CONFIG_SMP=y +CONFIG_SCHED_MC=y +CONFIG_SCHED_SMT=y +CONFIG_HIGHMEM=y +# CONFIG_HIGHPTE is not set +CONFIG_CMDLINE="console=ttyPS0,115200n8 root=/dev/ram rw earlyprintk" +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_MENU=y +CONFIG_ARM_ZYNQ_CPUIDLE=y +CONFIG_VFP=y +CONFIG_NEON=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MODVERSIONS=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_COMPACTION is not set +CONFIG_CMA=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_NET_IPIP=m +# CONFIG_IPV6 is not set +CONFIG_VLAN_8021Q=m +CONFIG_CFG80211=y +CONFIG_MAC80211=y +CONFIG_MAC80211_LEDS=y +CONFIG_RFKILL=y +CONFIG_RFKILL_INPUT=y +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_DMA_CMA=y +CONFIG_CMA_SIZE_MBYTES=256 +CONFIG_CONNECTOR=y +CONFIG_MTD=y +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_MTD_BLOCK=y +CONFIG_MTD_CFI=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_OF=y +CONFIG_MTD_M25P80=y +CONFIG_MTD_SPI_NOR=y +# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=16384 +CONFIG_ADI_AXI_TDD=y +CONFIG_SRAM=y +# CONFIG_MATHWORKS_IP_CORE is not set +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_SG=y +# CONFIG_BLK_DEV_BSG is not set +CONFIG_NETDEVICES=y +# CONFIG_NET_VENDOR_ALACRITECH is not set +# CONFIG_NET_VENDOR_AMAZON is not set +# CONFIG_NET_VENDOR_AQUANTIA is not set +# CONFIG_NET_VENDOR_ARC is not set +# CONFIG_NET_VENDOR_BROADCOM is not set +# CONFIG_NET_VENDOR_CIRRUS is not set +# CONFIG_NET_VENDOR_EZCHIP is not set +# CONFIG_NET_VENDOR_FARADAY is not set +# CONFIG_NET_VENDOR_HISILICON is not set +# CONFIG_NET_VENDOR_HUAWEI is not set +# CONFIG_NET_VENDOR_INTEL is not set +# CONFIG_NET_VENDOR_MARVELL is not set +# CONFIG_NET_VENDOR_MELLANOX is not set +# CONFIG_NET_VENDOR_MICREL is not set +# CONFIG_NET_VENDOR_MICROCHIP is not set +# CONFIG_NET_VENDOR_NATSEMI is not set +# CONFIG_NET_VENDOR_NETRONOME is not set +# CONFIG_NET_VENDOR_QUALCOMM is not set +# CONFIG_NET_VENDOR_RENESAS is not set +# CONFIG_NET_VENDOR_ROCKER is not set +# CONFIG_NET_VENDOR_SAMSUNG is not set +# CONFIG_NET_VENDOR_SEEQ is not set +# CONFIG_NET_VENDOR_SOLARFLARE is not set +# CONFIG_NET_VENDOR_SMSC is not set +# CONFIG_NET_VENDOR_STMICRO is not set +# CONFIG_NET_VENDOR_SYNOPSYS is not set +# CONFIG_NET_VENDOR_VIA is not set +# CONFIG_NET_VENDOR_WIZNET is not set +# CONFIG_NET_VENDOR_XILINX is not set +CONFIG_USB_RTL8152=y +CONFIG_USB_LAN78XX=y +CONFIG_USB_USBNET=y +# CONFIG_USB_NET_CDC_NCM is not set +CONFIG_USB_NET_SMSC75XX=y +CONFIG_USB_NET_SMSC95XX=y +# CONFIG_USB_NET_NET1080 is not set +CONFIG_USB_NET_RNDIS_HOST=y +# CONFIG_USB_NET_CDC_SUBSET is not set +# CONFIG_USB_NET_ZAURUS is not set +# CONFIG_WLAN_VENDOR_ADMTEK is not set +# CONFIG_WLAN_VENDOR_ATH is not set +# CONFIG_WLAN_VENDOR_ATMEL is not set +# CONFIG_WLAN_VENDOR_BROADCOM is not set +# CONFIG_WLAN_VENDOR_CISCO is not set +# CONFIG_WLAN_VENDOR_INTEL is not set +# CONFIG_WLAN_VENDOR_INTERSIL is not set +# CONFIG_WLAN_VENDOR_MARVELL is not set +# CONFIG_WLAN_VENDOR_MEDIATEK is not set +CONFIG_RT2X00=y +CONFIG_RT2500USB=y +CONFIG_RT73USB=y +CONFIG_RT2800USB=y +CONFIG_RT2800USB_RT3573=y +CONFIG_RT2800USB_RT53XX=y +CONFIG_RT2800USB_RT55XX=y +CONFIG_RT2800USB_UNKNOWN=y +CONFIG_RTL8187=y +CONFIG_RTL8192CU=y +# CONFIG_RTLWIFI_DEBUG is not set +CONFIG_RTL8XXXU=y +CONFIG_RTL8XXXU_UNTESTED=y +# CONFIG_WLAN_VENDOR_RSI is not set +# CONFIG_WLAN_VENDOR_ST is not set +# CONFIG_WLAN_VENDOR_TI is not set +# CONFIG_WLAN_VENDOR_ZYDAS is not set +CONFIG_INPUT_FF_MEMLESS=y +CONFIG_INPUT_SPARSEKMAP=y +CONFIG_INPUT_EVDEV=y +CONFIG_KEYBOARD_GPIO=y +# CONFIG_INPUT_MOUSE is not set +CONFIG_VT_HW_CONSOLE_BINDING=y +# CONFIG_LEGACY_PTYS is not set +CONFIG_SERIAL_XILINX_PS_UART=y +CONFIG_SERIAL_XILINX_PS_UART_CONSOLE=y +# CONFIG_HW_RANDOM is not set +CONFIG_I2C=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_CADENCE=y +CONFIG_I2C_GPIO=y +CONFIG_I2C_XILINX=y +CONFIG_SPI=y +CONFIG_SPI_AXI_SPI_ENGINE=y +CONFIG_SPI_CADENCE=y +CONFIG_SPI_XILINX=y +CONFIG_SPI_ZYNQ_QSPI=y +CONFIG_SPI_SPIDEV=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_SYSFS=y +CONFIG_GPIO_ZYNQ=y +CONFIG_POWER_SUPPLY=y +CONFIG_THERMAL=y +CONFIG_WATCHDOG=y +CONFIG_XILINX_WATCHDOG=y +CONFIG_CADENCE_WATCHDOG=y +CONFIG_SSB=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_HIDRAW=y +CONFIG_USB_HIDDEV=y +CONFIG_USB=y +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +CONFIG_USB_OTG=y +CONFIG_USB_EHCI_HCD=y +# CONFIG_USB_EHCI_TT_NEWSCHED is not set +CONFIG_USB_STORAGE=y +CONFIG_USB_CHIPIDEA=y +CONFIG_USB_CHIPIDEA_UDC=y +CONFIG_USB_CHIPIDEA_HOST=y +CONFIG_USB_SERIAL=y +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_FTDI_SIO=y +CONFIG_USB_ULPI=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_VBUS_DRAW=500 +CONFIG_USB_GADGET_XILINX=y +CONFIG_USB_CONFIGFS=y +CONFIG_USB_CONFIGFS_SERIAL=y +CONFIG_USB_CONFIGFS_ACM=y +CONFIG_USB_CONFIGFS_NCM=y +CONFIG_USB_CONFIGFS_ECM=y +CONFIG_USB_CONFIGFS_ECM_SUBSET=y +CONFIG_USB_CONFIGFS_RNDIS=y +CONFIG_USB_CONFIGFS_EEM=y +CONFIG_USB_CONFIGFS_MASS_STORAGE=y +CONFIG_USB_CONFIGFS_F_FS=y +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_GPIO=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_ONESHOT=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_CPU=y +CONFIG_LEDS_TRIGGER_GPIO=y +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y +CONFIG_DMADEVICES=y +CONFIG_AXI_DMAC=y +CONFIG_UIO=y +CONFIG_UIO_PDRV_GENIRQ=y +CONFIG_UIO_DMEM_GENIRQ=y +CONFIG_UIO_XILINX_APM=y +CONFIG_STAGING=y +CONFIG_R8712U=y +CONFIG_R8188EU=y +CONFIG_COMMON_CLK_AXI_CLKGEN=y +# CONFIG_IOMMU_SUPPORT is not set +CONFIG_MEMORY=y +CONFIG_IIO=y +CONFIG_ADM1177=y +CONFIG_AD9361=y +CONFIG_AD9361_EXT_BAND_CONTROL=y +CONFIG_ADMC=y +CONFIG_XILINX_XADC=y +CONFIG_ONE_BIT_ADC_DAC=y +CONFIG_CF_AXI_DDS=y +CONFIG_ADI_IIO_FAKEDEV=y +CONFIG_FPGA=y +CONFIG_FPGA_MGR_ZYNQ_FPGA=y +CONFIG_EXT4_FS=y +# CONFIG_DNOTIFY is not set +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +# CONFIG_NETWORK_FILESYSTEMS is not set +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ASCII=y +CONFIG_NLS_ISO8859_1=y +CONFIG_CRYPTO_ECB=y +CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_FS=y +CONFIG_DETECT_HUNG_TASK=y +CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=20 +# CONFIG_SCHED_DEBUG is not set +# CONFIG_DEBUG_PREEMPT is not set +CONFIG_RCU_CPU_STALL_TIMEOUT=60 +# CONFIG_FTRACE is not set +CONFIG_DEBUG_LL=y +CONFIG_DEBUG_ZYNQ_UART0=y +CONFIG_EARLY_PRINTK=y \ No newline at end of file diff --git a/firmware/ori/libre/linux-dts/zynq-libre.dts b/firmware/ori/libre/linux-dts/zynq-libre.dts new file mode 100644 index 0000000..1c43423 --- /dev/null +++ b/firmware/ori/libre/linux-dts/zynq-libre.dts @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * + * hdl_project: + * board_revision: <5> + * + */ +/dts-v1/; +#include "zynq-libre.dtsi" + + +// &axi_i2c0 { +// current_limiter@5a { +// compatible = "adi,adm1177"; +// reg = <0x5a>; +// adi,r-sense-mohm = <50>; /* 50 mOhm */ +// adi,shutdown-threshold-ma = <1059>; /* 1.059 A */ +// adi,vrange-high-enable; +// }; +// }; + + +&adc0_ad9364 { + /* This property is controlled by u-boot environment. */ + adi,2rx-2tx-mode-enable; +}; + +&cf_ad9364_dac_core_0 { + /* This property is controlled by u-boot environment. */ + compatible = "adi,axi-ad9361-dds-6.00.a"; +}; + + +/ { + + leds { + compatible = "gpio-leds"; + led0 { + label = "led0:green"; + gpios = <&gpio0 15 0>; + linux,default-trigger = "heartbeat"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + button { + interrupt-parent = <&gpio0>; + interrupts = <14 IRQ_TYPE_EDGE_FALLING>; + label = "Button"; + linux,code = ; + }; + + }; +}; + + diff --git a/firmware/ori/libre/linux-dts/zynq-libre.dtsi b/firmware/ori/libre/linux-dts/zynq-libre.dtsi new file mode 100644 index 0000000..8ddade7 --- /dev/null +++ b/firmware/ori/libre/linux-dts/zynq-libre.dtsi @@ -0,0 +1,461 @@ +/* + * Libre SDR (Z7020/AD936x) + * + * + * Licensed under the GPL-2. + */ +#include "zynq.dtsi" +#include +#include +#include + +#define AD9361_EXT_BAND_CTL_SHORTHANDS +#include + +/ { + model = "LibreSDR Rev.5 (Z7020/AD9363)"; + memory { + device_type = "memory"; + reg = <0x00000000 0x40000000>; + }; + + chosen { + stdout-path = "/amba@0/uart@E0000000"; + }; + + + clocks { + ad9364_clkin: clock@0 { + #clock-cells = <0>; + compatible = "adjustable-clock"; + clock-frequency = <40000000>; + clock-accuracy = <200000>; /* 200 ppm (ppb) */ + clock-output-names = "ad9364_ext_refclk"; + }; + }; + + usb_phy0: phy0 { + compatible = "ulpi-phy"; + #phy-cells = <0>; + reg = <0xe0002000 0x1000>; + view-port = <0x0170>; + drv-vbus; + }; + +}; + +&clkc { + ps-clk-frequency = <50000000>; +}; + +&sdhci0 { + status = "okay"; + xlnx,has-cd = <0x0>; + xlnx,has-power = <0x0>; + xlnx,has-wp = <0x0>; +}; + +&watchdog0 { + status = "okay"; + reset-on-timeout; +}; + +&gem0 { + status = "okay"; + phy-mode = "rgmii-id"; + phy-handle = <&phy0>; + + phy0: phy@0 { /* Marvell 88e1512 */ + reg = <0>; + compatible = "ethernet-phy-ieee802.3-c22"; + reset-gpios = <&gpio0 46 1>; + }; +}; + +&usb0 { + xlnx,phy-reset-gpio = <&gpio0 47 0>; + dr_mode = "otg"; + status = "okay"; + usb-phy = <&usb_phy0>; +}; + +&uart0 { + u-boot,dm-pre-reloc; + status = "okay"; +}; + +&qspi { + status = "okay"; + is-dual = <0>; + num-cs = <1>; + primary_flash: ps7-qspi@0 { + #address-cells = <1>; + #size-cells = <1>; + spi-tx-bus-width = <1>; + spi-rx-bus-width = <4>; + compatible = "n25q256a", "n25q512a", "jedec,spi-nor"; /* same as S25FL256 */ + reg = <0x0>; + spi-max-frequency = <50000000>; + partition@qspi-fsbl-uboot { + label = "qspi-fsbl-uboot"; + reg = <0x0 0x100000>; /* 1M */ + }; + partition@qspi-uboot-env { + label = "qspi-uboot-env"; + reg = <0x100000 0x20000>; /* 128k */ + }; + partition@qspi-nvmfs { + label = "qspi-nvmfs"; + reg = <0x120000 0xE0000>; /* 1M */ + }; + partition@qspi-linux { + label = "qspi-linux"; + reg = <0x200000 0x1E00000>; /* 30M */ + }; + }; +}; + +&adc { + xlnx,channels { + #address-cells = <1>; + #size-cells = <0>; + channel@0 { + reg = <0>; + }; + }; +}; + +/ { + fpga_axi: fpga-axi@0 { + compatible = "simple-bus"; + #address-cells = <0x1>; + #size-cells = <0x1>; + ranges; + + // axi_i2c0: i2c@41600000 { + // compatible = "xlnx,axi-iic-1.02.a", "xlnx,xps-iic-2.00.a"; + // reg = <0x41600000 0x10000>; + // interrupt-parent = <&intc>; + // interrupts = <0 59 IRQ_TYPE_LEVEL_HIGH>; + // clocks = <&clkc 15>; + // clock-names = "pclk"; + + // #address-cells = <1>; + // #size-cells = <0>; + + // }; + + rx_dma: dma@7c400000 { + compatible = "adi,axi-dmac-1.00.a"; + reg = <0x7c400000 0x10000>; + #dma-cells = <1>; + interrupts = <0 57 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clkc 16>; + + adi,channels { + #size-cells = <0>; + #address-cells = <1>; + + dma-channel@0 { + reg = <0>; + adi,source-bus-width = <32>; + adi,source-bus-type = <2>; + adi,destination-bus-width = <64>; + adi,destination-bus-type = <0>; + }; + }; + }; + + tx_dma: dma@7c420000 { + compatible = "adi,axi-dmac-1.00.a"; + reg = <0x7c420000 0x10000>; + #dma-cells = <1>; + interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clkc 16>; + + adi,channels { + #size-cells = <0>; + #address-cells = <1>; + + dma-channel@0 { + reg = <0>; + adi,source-bus-width = <64>; + adi,source-bus-type = <0>; + adi,destination-bus-width = <32>; + adi,destination-bus-type = <2>; + }; + }; + }; + + cf_ad9364_adc_core_0: cf-ad9361-lpc@79020000 { + compatible = "adi,axi-ad9361-6.00.a"; + reg = <0x79020000 0x6000>; + dmas = <&rx_dma 0>; + dma-names = "rx"; + spibus-connected = <&adc0_ad9364>; + adi,axi-decimation-core-available; + }; + + cf_ad9364_dac_core_0: cf-ad9361-dds-core-lpc@79024000 { + compatible = "adi,axi-ad9364-dds-6.00.a"; + reg = <0x79024000 0x1000>; + clocks = <&adc0_ad9364 13>; + clock-names = "sampl_clk"; + dmas = <&tx_dma 0>; + dma-names = "tx"; + adi,axi-interpolation-core-available; + adi,axi-dds-default-scale = <0>; + }; + + mwipcore@43c00000 { + compatible = "mathworks,mwipcore-axi4lite-v1.00"; + reg = <0x43c00000 0xffff>; + }; + }; +}; + +&spi0 { + status = "okay"; + + adc0_ad9364: ad9361-phy@0 { + #address-cells = <1>; + #size-cells = <0>; + #clock-cells = <1>; + compatible = "adi,ad9361"; + + /* SPI Setup */ + reg = <0>; + spi-cpha; + spi-max-frequency = <10000000>; + + /* Clocks */ + clocks = <&ad9364_clkin 0>; + clock-names = "ad9364_ext_refclk"; + clock-output-names = "rx_sampl_clk", "tx_sampl_clk"; + + /* Digital Interface Control */ + + /* adi,digital-interface-tune-skip-mode: + * 0 = TUNE RX&TX + * 1 = SKIP TX + * 2 = SKIP ALL + */ + adi,digital-interface-tune-skip-mode = <2>; /* Skip TX tuning - MSK owns TX path */ + + adi,pp-tx-swap-enable; + adi,pp-rx-swap-enable; + adi,rx-frame-pulse-mode-enable; + adi,lvds-mode-enable; + adi,lvds-bias-mV = <150>; + adi,lvds-rx-onchip-termination-enable; + adi,rx-data-delay = <4>; + adi,tx-fb-clock-delay = <7>; + adi,tx-data-delay = <9>; + + adi,xo-disable-use-ext-refclk-enable; + + /* Mode Setup */ + + //adi,split-gain-table-mode-enable; + + /* ENSM Mode */ + adi,frequency-division-duplex-mode-enable; + //adi,ensm-enable-pin-pulse-mode-enable; + //adi,ensm-enable-txnrx-control-enable; + + + /* adi,rx-rf-port-input-select: + * 0 = (RX1A_N & RX1A_P) and (RX2A_N & RX2A_P) enabled; balanced + * 1 = (RX1B_N & RX1B_P) and (RX2B_N & RX2B_P) enabled; balanced + * 2 = (RX1C_N & RX1C_P) and (RX2C_N & RX2C_P) enabled; balanced + * + * 3 = RX1A_N and RX2A_N enabled; unbalanced + * 4 = RX1A_P and RX2A_P enabled; unbalanced + * 5 = RX1B_N and RX2B_N enabled; unbalanced + * 6 = RX1B_P and RX2B_P enabled; unbalanced + * 7 = RX1C_N and RX2C_N enabled; unbalanced + * 8 = RX1C_P and RX2C_P enabled; unbalanced + */ + + adi,rx-rf-port-input-select = <0>; /* (RX1A_N & RX1A_P) and (RX2A_N & RX2A_P) enabled; balanced */ + adi,rx-rf-port-input-select-lock-enable; + + /* adi,tx-rf-port-input-select: + * 0 TX1A, TX2A + * 1 TX1B, TX2B + */ + + adi,tx-rf-port-input-select = <0>; /* TX1A, TX2A */ + adi,tx-rf-port-input-select-lock-enable; + + //adi,update-tx-gain-in-alert-enable; + adi,tx-attenuation-mdB = <10000>; + adi,tx-lo-powerdown-managed-enable; + + adi,rf-rx-bandwidth-hz = <18000000>; + adi,rf-tx-bandwidth-hz = <18000000>; + adi,rx-synthesizer-frequency-hz = /bits/ 64 <2400000000>; + adi,tx-synthesizer-frequency-hz = /bits/ 64 <2450000000>; + + /* stock clock rates */ + /* BBPLL ADC R2CLK R1CLK CLKRF RSAMPL */ + adi,rx-path-clock-frequencies = <983040000 245760000 122880000 61440000 30720000 30720000>; + /* BBPLL DAC T2CLK T1CLK CLKTF TSAMPL */ + adi,tx-path-clock-frequencies = <983040000 122880000 122880000 61440000 30720000 30720000>; + + /* clocks for Opulent Voice HDL */ + /* BBPLL ADC R2CLK R1CLK CLKRF RSAMPL */ + //adi,rx-path-clock-frequencies = <983040000 245760000 122880000 61440000 61440000 61440000>; + /* BBPLL DAC T2CLK T1CLK CLKTF TSAMPL */ + //adi,tx-path-clock-frequencies = <983040000 122880000 122880000 61440000 61440000 61440000>; + + /* clocks for Opulent Voice HDL */ + //adi,rx-path-clock-frequencies = <983040000 245760000 122880000 61440000 30720000 15360000>; + //adi,tx-path-clock-frequencies = <983040000 122880000 122880000 61440000 30720000 15360000>; + + + /* Gain Control */ + + /* adi,gc-rx[1|2]-mode: + * 0 = RF_GAIN_MGC + * 1 = RF_GAIN_FASTATTACK_AGC + * 2 = RF_GAIN_SLOWATTACK_AGC + * 3 = RF_GAIN_HYBRID_AGC + */ + + adi,gc-rx1-mode = <2>; + adi,gc-rx2-mode = <2>; + adi,gc-adc-ovr-sample-size = <4>; /* sum 4 samples */ + adi,gc-adc-small-overload-thresh = <47>; /* sum of squares */ + adi,gc-adc-large-overload-thresh = <58>; /* sum of squares */ + adi,gc-lmt-overload-high-thresh = <800>; /* mV */ + adi,gc-lmt-overload-low-thresh = <704>; /* mV */ + adi,gc-dec-pow-measurement-duration = <8192>; /* 0..524288 Samples */ + adi,gc-low-power-thresh = <24>; /* 0..-64 dBFS vals are set pos */ + //adi,gc-dig-gain-enable; + //adi,gc-max-dig-gain = <15>; + + /* Manual Gain Control Setup */ + + //adi,mgc-rx1-ctrl-inp-enable; /* uncomment to use ctrl inputs */ + //adi,mgc-rx2-ctrl-inp-enable; /* uncomment to use ctrl inputs */ + adi,mgc-inc-gain-step = <2>; + adi,mgc-dec-gain-step = <2>; + + /* adi,mgc-split-table-ctrl-inp-gain-mode: + * (relevant if adi,split-gain-table-mode-enable is set) + * 0 = AGC determine this + * 1 = only in LPF + * 2 = only in LMT + */ + + adi,mgc-split-table-ctrl-inp-gain-mode = <0>; + + /* Automatic Gain Control Setup */ + + adi,agc-attack-delay-extra-margin-us= <1>; /* us */ + adi,agc-outer-thresh-high = <5>; /* -dBFS */ + adi,agc-outer-thresh-high-dec-steps = <2>; /* 0..15 */ + adi,agc-inner-thresh-high = <10>; /* -dBFS */ + adi,agc-inner-thresh-high-dec-steps = <1>; /* 0..7 */ + adi,agc-inner-thresh-low = <12>; /* -dBFS */ + adi,agc-inner-thresh-low-inc-steps = <1>; /* 0..7 */ + adi,agc-outer-thresh-low = <18>; /* -dBFS */ + adi,agc-outer-thresh-low-inc-steps = <2>; /* 0..15 */ + + adi,agc-adc-small-overload-exceed-counter = <10>; /* 0..15 */ + adi,agc-adc-large-overload-exceed-counter = <10>; /* 0..15 */ + adi,agc-adc-large-overload-inc-steps = <2>; /* 0..15 */ + //adi,agc-adc-lmt-small-overload-prevent-gain-inc-enable; + adi,agc-lmt-overload-large-exceed-counter = <10>; /* 0..15 */ + adi,agc-lmt-overload-small-exceed-counter = <10>; /* 0..15 */ + adi,agc-lmt-overload-large-inc-steps = <2>; /* 0..7 */ + //adi,agc-dig-saturation-exceed-counter = <3>; /* 0..15 */ + //adi,agc-dig-gain-step-size = <4>; /* 1..8 */ + + //adi,agc-sync-for-gain-counter-enable; + adi,agc-gain-update-interval-us = <1000>; /* 1ms */ + //adi,agc-immed-gain-change-if-large-adc-overload-enable; + //adi,agc-immed-gain-change-if-large-lmt-overload-enable; + + /* Fast AGC */ + + adi,fagc-dec-pow-measurement-duration = <64>; /* 64 Samples */ + //adi,fagc-allow-agc-gain-increase-enable; + adi,fagc-lp-thresh-increment-steps = <1>; + adi,fagc-lp-thresh-increment-time = <5>; + + adi,fagc-energy-lost-stronger-sig-gain-lock-exit-cnt = <8>; + adi,fagc-final-overrange-count = <3>; + //adi,fagc-gain-increase-after-gain-lock-enable; + adi,fagc-gain-index-type-after-exit-rx-mode = <0>; + adi,fagc-lmt-final-settling-steps = <1>; + adi,fagc-lock-level = <10>; + adi,fagc-lock-level-gain-increase-upper-limit = <5>; + adi,fagc-lock-level-lmt-gain-increase-enable; + + adi,fagc-lpf-final-settling-steps = <1>; + adi,fagc-optimized-gain-offset = <5>; + adi,fagc-power-measurement-duration-in-state5 = <64>; + adi,fagc-rst-gla-engergy-lost-goto-optim-gain-enable; + adi,fagc-rst-gla-engergy-lost-sig-thresh-below-ll = <10>; + adi,fagc-rst-gla-engergy-lost-sig-thresh-exceeded-enable; + adi,fagc-rst-gla-if-en-agc-pulled-high-mode = <0>; + adi,fagc-rst-gla-large-adc-overload-enable; + adi,fagc-rst-gla-large-lmt-overload-enable; + adi,fagc-rst-gla-stronger-sig-thresh-above-ll = <10>; + adi,fagc-rst-gla-stronger-sig-thresh-exceeded-enable; + adi,fagc-state-wait-time-ns = <260>; + adi,fagc-use-last-lock-level-for-set-gain-enable; + + /* RSSI */ + + /* adi,rssi-restart-mode: + * 0 = AGC_IN_FAST_ATTACK_MODE_LOCKS_THE_GAIN, + * 1 = EN_AGC_PIN_IS_PULLED_HIGH, + * 2 = ENTERS_RX_MODE, + * 3 = GAIN_CHANGE_OCCURS, + * 4 = SPI_WRITE_TO_REGISTER, + * 5 = GAIN_CHANGE_OCCURS_OR_EN_AGC_PIN_PULLED_HIGH, + */ + adi,rssi-restart-mode = <3>; + //adi,rssi-unit-is-rx-samples-enable; + adi,rssi-delay = <1>; /* 1us */ + adi,rssi-wait = <1>; /* 1us */ + adi,rssi-duration = <1000>; /* 1ms */ + + /* Control Outputs */ + adi,ctrl-outs-index = <0>; + adi,ctrl-outs-enable-mask = <0xFF>; + + /* AuxADC Temp Sense Control */ + + adi,temp-sense-measurement-interval-ms = <1000>; + adi,temp-sense-offset-signed = <0xCE>; + adi,temp-sense-periodic-measurement-enable; + + /* AuxDAC Control */ + + adi,aux-dac-manual-mode-enable; + + adi,aux-dac1-default-value-mV = <0>; + //adi,aux-dac1-active-in-rx-enable; + //adi,aux-dac1-active-in-tx-enable; + //adi,aux-dac1-active-in-alert-enable; + adi,aux-dac1-rx-delay-us = <0>; + adi,aux-dac1-tx-delay-us = <0>; + + adi,aux-dac2-default-value-mV = <0>; + //adi,aux-dac2-active-in-rx-enable; + //adi,aux-dac2-active-in-tx-enable; + //adi,aux-dac2-active-in-alert-enable; + adi,aux-dac2-rx-delay-us = <0>; + adi,aux-dac2-tx-delay-us = <0>; + + /* Control GPIOs */ + + en_agc-gpios = <&gpio0 66 0>; + reset-gpios = <&gpio0 67 0>; + + }; +}; diff --git a/firmware/ori/libre/setup_libre.sh b/firmware/ori/libre/setup_libre.sh new file mode 100755 index 0000000..6f1a4fd --- /dev/null +++ b/firmware/ori/libre/setup_libre.sh @@ -0,0 +1,51 @@ +#!/bin/bash +# Setup script to install LibreSDR support files into submodules +# Run this after cloning the repo and initializing submodules + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +FIRMWARE_DIR="$(dirname "$(dirname "$SCRIPT_DIR")")" + +echo "==========================================" +echo "LibreSDR Setup for pluto_msk" +echo "==========================================" + +echo "Installing Linux device tree and config..." +cp "$SCRIPT_DIR/linux-dts/zynq-libre.dts" "$FIRMWARE_DIR/linux/arch/arm/boot/dts/" +cp "$SCRIPT_DIR/linux-dts/zynq-libre.dtsi" "$FIRMWARE_DIR/linux/arch/arm/boot/dts/" +cp "$SCRIPT_DIR/linux-configs/zynq_libre_linux_defconfig" "$FIRMWARE_DIR/linux/arch/arm/configs/" + +echo "Installing U-Boot device tree and config..." +cp "$SCRIPT_DIR/uboot-dts/zynq-libre-sdr.dts" "$FIRMWARE_DIR/u-boot-xlnx/arch/arm/dts/" +cp "$SCRIPT_DIR/uboot-configs/zynq_libre_defconfig" "$FIRMWARE_DIR/u-boot-xlnx/configs/" + +# Add zynq-libre-sdr.dtb to U-Boot DTS Makefile if not present +if ! grep -q "zynq-libre-sdr.dtb" "$FIRMWARE_DIR/u-boot-xlnx/arch/arm/dts/Makefile"; then + sed -i '/zynq-pluto-sdr.dtb/a\ zynq-libre-sdr.dtb \\' "$FIRMWARE_DIR/u-boot-xlnx/arch/arm/dts/Makefile" + echo " Added zynq-libre-sdr.dtb to U-Boot DTS Makefile" +fi + +echo "Installing Buildroot config..." +cp "$SCRIPT_DIR/buildroot-configs/zynq_libre_defconfig" "$FIRMWARE_DIR/buildroot/configs/" + +echo "" +echo "==========================================" +echo "LibreSDR setup complete!" +echo "==========================================" +echo "" +echo "To build LibreSDR firmware:" +echo "" +echo " Option 1 - Build HDL first (requires Vivado, ~30 min):" +echo " cd pluto_msk/projects/libre && make" +echo " cd pluto_msk/firmware" +echo " make PLATFORM=libre" +echo "" +echo " Option 1a - Build SD Card Image Files" +echo " cd pluto_msk/firmware" +echo " make PLATFORM=libre sdimg" +echo "" +echo " Option 2 - Use pre-built XSA:" +echo " cd pluto_msk/firmware" +echo " make PLATFORM=libre XSA_FILE=/path/to/system_top.xsa" +echo "" diff --git a/firmware/ori/libre/uboot-configs/zynq_libre_defconfig b/firmware/ori/libre/uboot-configs/zynq_libre_defconfig new file mode 100644 index 0000000..c33cb87 --- /dev/null +++ b/firmware/ori/libre/uboot-configs/zynq_libre_defconfig @@ -0,0 +1,62 @@ +CONFIG_ARM=y +CONFIG_SYS_CONFIG_NAME="zynq_zc70x" +CONFIG_ARCH_ZYNQ=y +CONFIG_SYS_MALLOC_F_LEN=0x800 +CONFIG_DEFAULT_DEVICE_TREE="zynq-libre-sdr" +CONFIG_SPL=y +CONFIG_FIT=y +CONFIG_FIT_VERBOSE=y +CONFIG_FIT_SIGNATURE=y +CONFIG_BOOTDELAY=3 +CONFIG_SYS_NO_FLASH=y +CONFIG_HUSH_PARSER=y +CONFIG_SYS_PROMPT="LIBRESDR> " +# CONFIG_CMD_IMLS is not set +# CONFIG_CMD_XIMG is not set +# CONFIG_CMD_FLASH is not set +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_ZYNQ=y +CONFIG_ZYNQ_SDHCI=y +CONFIG_CMD_MMC=y +CONFIG_SD_BOOT=y + +CONFIG_CMD_SF=y +CONFIG_CMD_SPI=y +CONFIG_CMD_USB=y +CONFIG_CMD_DFU=y +CONFIG_CMD_GPIO=y +# CONFIG_CMD_SETEXPR is not set +# CONFIG_CMD_NET is not set +# CONFIG_CMD_NFS is not set +CONFIG_CMD_CACHE=y +CONFIG_CMD_EXT2=y +CONFIG_CMD_EXT4=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y +CONFIG_OF_EMBED=y +CONFIG_SPL_DM_SEQ_ALIAS=y +CONFIG_LED=y +CONFIG_LED_GPIO=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y +CONFIG_SPI_FLASH_ISSI=y +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_SPI_FLASH_SPANSION=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_SPI_FLASH_WINBOND=y +CONFIG_ZYNQ_QSPI=y +CONFIG_USB=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_ULPI_VIEWPORT=y +CONFIG_USB_ULPI=y +CONFIG_USB_STORAGE=y +CONFIG_USB_GADGET=y +CONFIG_CI_UDC=y +CONFIG_USB_GADGET_VBUS_DRAW=500 +CONFIG_USB_GADGET_DOWNLOAD=y +CONFIG_G_DNL_MANUFACTURER="Analog Devices Inc." +CONFIG_G_DNL_VENDOR_NUM=0x0456 +CONFIG_G_DNL_PRODUCT_NUM=0xb674 +CONFIG_REGEX=y +CONFIG_LIB_RAND=y \ No newline at end of file diff --git a/firmware/ori/libre/uboot-dts/zynq-libre-sdr.dts b/firmware/ori/libre/uboot-dts/zynq-libre-sdr.dts new file mode 100644 index 0000000..8121518 --- /dev/null +++ b/firmware/ori/libre/uboot-dts/zynq-libre-sdr.dts @@ -0,0 +1,111 @@ +/* + * LIBRE board DTS + * + * SPDX-License-Identifier: GPL-2.0+ + */ +/dts-v1/; +#include "zynq-7000.dtsi" + +/ { + model = "LibreSDR"; + compatible = "xlnx,zynq-7000"; + + aliases { + ethernet0 = &gem0; + serial0 = &uart0; + spi0 = &qspi; + }; + + memory { + device_type = "memory"; + reg = <0x0 0x40000000>; + }; + + chosen { + bootargs = "earlyprintk"; + linux,stdout-path = &uart0; + stdout-path = &uart0; + }; + + usb_phy0: phy0 { + compatible = "usb-nop-xceiv"; + #phy-cells = <0>; + }; + gpio_keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + button { + label = "Button"; + gpios = <&gpio0 14 0>; + linux,code = <103>; /* up */ + wakeup-source; + autorepeat; + }; + + }; + + +}; + + + + + + +&qspi { + status = "okay"; + is-dual = <0>; + num-cs = <1>; + flash@0 { + compatible = "n25q512a","micron,m25p80"; + reg = <0x0>; + spi-tx-bus-width = <1>; + spi-rx-bus-width = <4>; + spi-max-frequency = <50000000>; + #address-cells = <1>; + #size-cells = <1>; + partition@qspi-fsbl-uboot { + label = "qspi-fsbl-uboot"; + reg = <0x0 0x100000>; /* 1M */ + }; + partition@qspi-uboot-env { + label = "qspi-uboot-env"; + reg = <0x100000 0x20000>; /* 128k */ + }; + partition@qspi-nvmfs { + label = "qspi-nvmfs"; + reg = <0x120000 0xE0000>; /* 1M */ + }; + partition@qspi-linux { + label = "qspi-linux"; + reg = <0x200000 0x1E00000>; /* 30M */ + }; + }; +}; + +&uart0 { + status = "okay"; +}; + +&usb0 { + status = "okay"; + dr_mode = "host"; + usb-phy = <&usb_phy0>; +}; +&sdhci0 { + u-boot,dm-pre-reloc; + status = "okay"; + +}; + +&gem0 { + status = "okay"; + phy-mode = "rgmii-id"; + phy-handle = <ðernet_phy0>; + + ethernet_phy0: ethernet-phy@0 { + reg = <0>; + reset-gpios = <&gpio0 46 0>; + }; +}; \ No newline at end of file diff --git a/firmware/scripts/libre.its b/firmware/scripts/libre.its new file mode 100644 index 0000000..91fc4aa --- /dev/null +++ b/firmware/scripts/libre.its @@ -0,0 +1,70 @@ +/* + * U-Boot uImage source file for LibreSDR + */ + +/dts-v1/; + +/ { + description = "Configuration to load fpga before Kernel"; + magic = "ITB PlutoSDR (ADALM-PLUTO)"; + #address-cells = <1>; + images { + + fdt@1 { + description = "zynq-libre"; + data = /incbin/("../build/zynq-libre.dtb"); + type = "flat_dt"; + arch = "arm"; + compression = "none"; + }; + + fpga@1 { + description = "FPGA"; + data = /incbin/("/home/abraxas3d/pluto_msk/firmware/build/system_top.bit"); + type = "fpga"; + arch = "arm"; + compression = "none"; + load = <0xF000000>; + hash@1 { + algo = "md5"; + }; + }; + + linux_kernel@1 { + description = "Linux"; + data = /incbin/("../build/zImage"); + type = "kernel"; + arch = "arm"; + os = "linux"; + compression = "none"; + load = <0x8000>; + entry = <0x8000>; + hash@1 { + algo = "md5"; + }; + }; + + ramdisk@1 { + description = "Ramdisk"; + data = /incbin/("../build/rootfs.cpio.gz"); + type = "ramdisk"; + arch = "arm"; + os = "linux"; + compression = "gzip"; + hash@1 { + algo = "md5"; + }; + }; + }; + + configurations { + default = "config@0"; + config@0 { + description = "Linux with fpga LibreSDR"; + fdt = "fdt@1"; + kernel = "linux_kernel@1"; + ramdisk = "ramdisk@1"; + fpga = "fpga@1"; + }; + }; +}; diff --git a/firmware/scripts/libre.mk b/firmware/scripts/libre.mk new file mode 100644 index 0000000..2fb18e9 --- /dev/null +++ b/firmware/scripts/libre.mk @@ -0,0 +1,7 @@ +# Target specific constants go here + +TARGET_DTS_FILES:= zynq-libre.dtb +COMPLETE_NAME:=LIBRE +ZIP_ARCHIVE_PREFIX:=libresdr +DEVICE_VID:=0x0456 +DEVICE_PID:=0xb673 diff --git a/library/msk_top_ip.tcl b/library/msk_top_ip.tcl index 36151aa..15b908b 100644 --- a/library/msk_top_ip.tcl +++ b/library/msk_top_ip.tcl @@ -1,40 +1,48 @@ # ip -# "src/axi_ctrlif.vhd" - source ../hdl/scripts/adi_env.tcl source $ad_hdl_dir/library/scripts/adi_ip_xilinx.tcl adi_ip_create msk_top -read_vhdl -library "desyrdl" "../rdl/vhdl/desyrdl/pkg_desyrdl_common.vhd" +# Register ALL VHDL-2008 files first with read_vhdl -vhdl2008 +# Order matters: dependencies before modules that use them +read_vhdl -vhdl2008 "../rdl/src/axi4lite_intf_pkg.vhd" +read_vhdl -vhdl2008 "../rdl/src/reg_utils.vhd" +read_vhdl "../rdl/outputs/rtl/msk_top_regs_pkg.vhd" +read_vhdl -vhdl2008 "../rdl/outputs/rtl/msk_top_regs.vhd" +read_vhdl -vhdl2008 "../src/conv_encoder_k7.vhd" +read_vhdl -vhdl2008 "../src/viterbi_decoder_k7_simple.vhd" +read_vhdl -vhdl2008 "../src/viterbi_decoder_k7_soft.vhd" +read_vhdl -vhdl2008 "../src/ov_frame_encoder.vhd" +read_vhdl -vhdl2008 "../src/ov_frame_decoder.vhd" +read_vhdl -vhdl2008 "../src/ov_frame_decoder_soft.vhd" -#set_property FILE_TYPE {VHDL 2008} [get_files $ad_hdl_dir/library/msk_top/src/*.vhd] +# Register all non-VHDL-2008 files adi_ip_files msk_top [list \ - "../rdl/vhdl/msk_top_regs/msk_top_regs_decoder_axi4l.vhd" \ - "../rdl/vhdl/msk_top_regs/pkg_msk_top_regs.vhd" \ - "../rdl/vhdl/msk_top_regs/msk_top_regs.vhd" \ "../msk_demodulator/src/costas_loop.vhd" \ "../pi_controller/src/pi_controller.vhd" \ "../lowpass_ema/src/lowpass_ema.vhd" \ "../power_detector/src/power_detector.vhd" \ "../msk_demodulator/src/msk_demodulator.vhd" \ "../msk_modulator/src/msk_modulator.vhd" \ + "../src/cdc_resync.vhd" \ + "../src/pulse_detect.vhd" \ + "../src/data_capture.vhd" \ "../src/msk_top.vhd" \ "../src/msk_top_csr.vhd" \ "../src/axis_dma_adapter.vhd" \ "../src/axis_async_fifo.vhd" \ "../src/byte_to_bit_deserializer.vhd" \ - "../src/bit_to_byte_serializer.vhd" \ "../src/frame_sync_detector.vhd" \ + "../src/frame_sync_detector_soft.vhd" \ "../nco/src/nco.vhd" \ "../prbs/src/prbs_gen.vhd" \ "../prbs/src/prbs_mon.vhd" \ "../nco/src/sin_cos_lut.vhd" ] -# use this command if we have AXI lite interface for register control +# Configure IP properties adi_ip_properties msk_top - # Remove auto-inferred ADI custom bus interfaces before defining proper AXI-Stream set core [ipx::current_core] foreach intf {rx s_axis tx} { @@ -43,7 +51,7 @@ foreach intf {rx s_axis tx} { } } - +# TX AXIS slave interface (from DMA to MSK) adi_add_bus "s_axis" "slave" \ "xilinx.com:interface:axis_rtl:1.0" \ "xilinx.com:interface:axis:1.0" \ @@ -66,10 +74,6 @@ adi_add_bus "m_axis" "master" \ {"m_axis_tdata" "TDATA"} \ {"m_axis_tlast" "TLAST"}] -# m_axis shares the same clock as the demodulator adi_add_bus_clock "s_axis_aclk" "m_axis" "s_axis_aresetn" ipx::save_core [ipx::current_core] - -ipx::save_core [ipx::current_core] - diff --git a/msk_demodulator b/msk_demodulator index e837e29..028e264 160000 --- a/msk_demodulator +++ b/msk_demodulator @@ -1 +1 @@ -Subproject commit e837e291cc2ad3c503b54203de741e27dbe4a6eb +Subproject commit 028e264f9997173e23200db846f55179a435e05b diff --git a/projects/libre/Makefile b/projects/libre/Makefile new file mode 100644 index 0000000..4190e6c --- /dev/null +++ b/projects/libre/Makefile @@ -0,0 +1,37 @@ +#################################################################################### +## Copyright (c) 2018 - 2023 Analog Devices, Inc. +### SPDX short identifier: BSD-1-Clause +## Auto-generated, do not modify! +#################################################################################### +export ADI_IGNORE_VERSION_CHECK = 1 +export ADI_GENERATE_UTILIZATION = 1 +PROJECT_NAME := libre + +M_DEPS += ../../hdl/projects/common/xilinx/adi_fir_filter_constr.xdc +M_DEPS += ../../hdl/projects/common/xilinx/adi_fir_filter_bd.tcl +M_DEPS += ../../hdl/library/util_cdc/sync_bits.v +M_DEPS += ../../hdl/library/common/util_pulse_gen.v +M_DEPS += ../../hdl/library/common/ad_iobuf.v +M_DEPS += ../../hdl/library/common/ad_bus_mux.v +M_DEPS += ../../hdl/library/axi_tdd/scripts/axi_tdd.tcl +M_DEPS += ../../hdl/library/axi_ad9361/axi_ad9361_delay.tcl +M_DEPS += msk_top +M_DEPS += ../../src/msk_top.vhd +M_DEPS += ../../src/ov_frame_encoder.vhd +M_DEPS += ../../src/conv_encoder_k7.vhd +M_DEPS += ../../src/axis_async_fifo.vhd +M_DEPS += ../../src/axis_dma_adapter.vhd +M_DEPS += ../../msk_demodulator/src/msk_demodulator.vhd +M_DEPS += system_bd.tcl +M_DEPS += system_constr.xdc + +LIB_DEPS += axi_ad9361 +LIB_DEPS += axi_dmac +LIB_DEPS += axi_tdd +LIB_DEPS += util_pack/util_cpack2 +LIB_DEPS += util_pack/util_upack2 + +include ../../hdl/projects/scripts/project-xilinx.mk + +msk_top: + make -C ../../library diff --git a/projects/libre/README.md b/projects/libre/README.md new file mode 100644 index 0000000..b185a01 --- /dev/null +++ b/projects/libre/README.md @@ -0,0 +1,50 @@ +# LibreSDR Support + +LibreSDR is a PlutoSDR-compatible board with upgraded hardware: +- **FPGA**: XC7Z020-CLG400 (53,200 LUTs vs PlutoSDR's 17,600) +- **RF**: AD9363 (same as PlutoSDR AD9361 but different frequency range) +- **Memory**: 1GB DDR3 +- **Interface**: LVDS (vs PlutoSDR's CMOS) + +## Building LibreSDR Firmware + +### Prerequisites +- Vivado 2022.2 (for HDL build) +- ARM cross-compiler (arm-none-linux-gnueabihf-) + +### Quick Start +```bash +# 1. Clone and init submodules +git clone --branch encoder-dev https://github.com/OpenResearchInstitute/pluto_msk.git +cd pluto_msk +git submodule update --init --recursive + +# 2. Run LibreSDR setup +cd firmware/ori/libre +./setup_libre.sh + +# 3. Build firmware (auto-builds HDL) +cd ../.. +make PLATFORM=libre +``` + +### Using Pre-built XSA + +If you have a pre-built XSA file (from CI or another build): +```bash +cd firmware +make TARGET=libre XSA_FILE=/path/to/system_top.xsa +``` + +### Output + +Firmware files will be in `firmware/build/`: +- `libre.frm` - Main firmware image +- `boot.frm` - Boot image + +### Flashing + +Copy `libre.frm` to the LibreSDR mass storage device, or use DFU: +```bash +dfu-util -D build/libre.dfu -a firmware.dfu +``` diff --git a/projects/libre/Readme.md b/projects/libre/Readme.md new file mode 100755 index 0000000..c42a660 --- /dev/null +++ b/projects/libre/Readme.md @@ -0,0 +1,10 @@ +# PLUTO HDL Project + +Here are some pointers to help you: + * [Board Product Page](https://www.analog.com/adalm-pluto) + * [Board Product Page](https://www.analog.com/cn0566) + * Parts : [RF Agile Transceiver](https://www.analog.com/ad9363) + * Project Doc: https://wiki.analog.com/university/tools/pluto + * Project Doc: https://wiki.analog.com/resources/eval/user-guides/circuits-from-the-lab/cn0566 + * HDL Doc: https://wiki.analog.com/resources/eval/user-guides/ad-fmcomms2-ebz/reference_hdl + * Linux Drivers: https://wiki.analog.com/resources/tools-software/linux-drivers/iio-transceiver/ad9361 diff --git a/projects/libre/system_bd.tcl b/projects/libre/system_bd.tcl new file mode 100644 index 0000000..3808cae --- /dev/null +++ b/projects/libre/system_bd.tcl @@ -0,0 +1,732 @@ +# create board design +# LibreSDR with MSK Modem Integration +# Based on pluto MSK design adapted for LibreSDR LVDS interface +# +############################################################################## +# CLOCK DIVIDER MODIFICATION +############################################################################## +# In LVDS mode, AD9361 DATA_CLK (l_clk) runs at 245.76 MHz (4x sample rate). +# The MSK modem expects to run at the sample rate (61.44 MHz). +# This design uses a BUFR-based clock divider to create the correct clock. +# +# Changes from original: +# 1. Added clk_div_by4 module instantiation +# 2. msk_top/clk connected to divided clock (61.44 MHz) +# 3. msk_top/s_axis_aclk stays at l_clk (245 MHz) for DMA interface +# 4. tx_valid and rx_svalid tied to VCC (every divided clock cycle is valid) +# +# To revert: Search for "CLOCK_DIVIDER" comments +############################################################################## + +source $ad_hdl_dir/projects/common/xilinx/adi_fir_filter_bd.tcl + +# Add MSK IP repository +set_property ip_repo_paths [list $ad_hdl_dir/library ../../library] [current_fileset] +update_ip_catalog + +# default ports + +create_bd_intf_port -mode Master -vlnv xilinx.com:interface:ddrx_rtl:1.0 ddr +create_bd_intf_port -mode Master -vlnv xilinx.com:display_processing_system7:fixedio_rtl:1.0 fixed_io + +create_bd_port -dir O spi0_csn_2_o +create_bd_port -dir O spi0_csn_1_o +create_bd_port -dir O spi0_csn_0_o +create_bd_port -dir I spi0_csn_i +create_bd_port -dir I spi0_clk_i +create_bd_port -dir O spi0_clk_o +create_bd_port -dir I spi0_sdo_i +create_bd_port -dir O spi0_sdo_o +create_bd_port -dir I spi0_sdi_i + +create_bd_port -dir I -from 24 -to 0 gpio_i +create_bd_port -dir O -from 24 -to 0 gpio_o +create_bd_port -dir O -from 24 -to 0 gpio_t + +create_bd_port -dir O spi_csn_o +create_bd_port -dir I spi_csn_i +create_bd_port -dir I spi_clk_i +create_bd_port -dir O spi_clk_o +create_bd_port -dir I spi_sdo_i +create_bd_port -dir O spi_sdo_o +create_bd_port -dir I spi_sdi_i + +# instance: sys_ps7 + +ad_ip_instance processing_system7 sys_ps7 + +# ps7 settings + +ad_ip_parameter sys_ps7 CONFIG.PCW_PRESET_BANK0_VOLTAGE {LVCMOS 3.3V} +ad_ip_parameter sys_ps7 CONFIG.PCW_PRESET_BANK1_VOLTAGE {LVCMOS 2.5V} +ad_ip_parameter sys_ps7 CONFIG.PCW_PACKAGE_NAME clg400 +ad_ip_parameter sys_ps7 CONFIG.PCW_GPIO_MIO_GPIO_ENABLE 1 +ad_ip_parameter sys_ps7 CONFIG.PCW_ENET0_PERIPHERAL_ENABLE 1 +ad_ip_parameter sys_ps7 CONFIG.PCW_ENET0_ENET0_IO "MIO 16 .. 27" +ad_ip_parameter sys_ps7 CONFIG.PCW_ENET0_GRP_MDIO_ENABLE 1 +ad_ip_parameter sys_ps7 CONFIG.PCW_ENET0_GRP_MDIO_IO "MIO 52 .. 53" +ad_ip_parameter sys_ps7 CONFIG.PCW_ENET_RESET_SELECT "Separate reset pins" +ad_ip_parameter sys_ps7 CONFIG.PCW_ENET0_RESET_ENABLE 1 +ad_ip_parameter sys_ps7 CONFIG.PCW_ENET0_RESET_IO "MIO 46" +ad_ip_parameter sys_ps7 CONFIG.PCW_USE_S_AXI_HP1 1 +ad_ip_parameter sys_ps7 CONFIG.PCW_USE_S_AXI_HP2 1 +ad_ip_parameter sys_ps7 CONFIG.PCW_EN_CLK1_PORT 1 +ad_ip_parameter sys_ps7 CONFIG.PCW_EN_RST1_PORT 1 +ad_ip_parameter sys_ps7 CONFIG.PCW_FPGA0_PERIPHERAL_FREQMHZ 100.0 +ad_ip_parameter sys_ps7 CONFIG.PCW_FPGA1_PERIPHERAL_FREQMHZ 200.0 +ad_ip_parameter sys_ps7 CONFIG.PCW_CRYSTAL_PERIPHERAL_FREQMHZ 50 +ad_ip_parameter sys_ps7 CONFIG.PCW_GPIO_EMIO_GPIO_ENABLE 1 +ad_ip_parameter sys_ps7 CONFIG.PCW_GPIO_EMIO_GPIO_IO 25 +ad_ip_parameter sys_ps7 CONFIG.PCW_SPI1_PERIPHERAL_ENABLE 0 +ad_ip_parameter sys_ps7 CONFIG.PCW_I2C0_PERIPHERAL_ENABLE 0 +ad_ip_parameter sys_ps7 CONFIG.PCW_SD0_PERIPHERAL_ENABLE 1 +ad_ip_parameter sys_ps7 CONFIG.PCW_SDIO_PERIPHERAL_FREQMHZ 50 +ad_ip_parameter sys_ps7 CONFIG.PCW_UART0_PERIPHERAL_ENABLE 1 +ad_ip_parameter sys_ps7 CONFIG.PCW_UART0_UART0_IO {MIO 14 .. 15} +ad_ip_parameter sys_ps7 CONFIG.PCW_I2C1_PERIPHERAL_ENABLE 0 +ad_ip_parameter sys_ps7 CONFIG.PCW_QSPI_PERIPHERAL_ENABLE 1 +ad_ip_parameter sys_ps7 CONFIG.PCW_QSPI_GRP_SINGLE_SS_ENABLE 1 +ad_ip_parameter sys_ps7 CONFIG.PCW_SPI0_PERIPHERAL_ENABLE 1 +ad_ip_parameter sys_ps7 CONFIG.PCW_SPI0_SPI0_IO EMIO +ad_ip_parameter sys_ps7 CONFIG.PCW_TTC0_PERIPHERAL_ENABLE 0 +ad_ip_parameter sys_ps7 CONFIG.PCW_USE_FABRIC_INTERRUPT 1 +ad_ip_parameter sys_ps7 CONFIG.PCW_USB0_PERIPHERAL_ENABLE 1 +ad_ip_parameter sys_ps7 CONFIG.PCW_GPIO_MIO_GPIO_ENABLE 1 +ad_ip_parameter sys_ps7 CONFIG.PCW_GPIO_MIO_GPIO_IO MIO +ad_ip_parameter sys_ps7 CONFIG.PCW_USB0_RESET_IO {MIO 47} +ad_ip_parameter sys_ps7 CONFIG.PCW_USB0_RESET_ENABLE 1 +ad_ip_parameter sys_ps7 CONFIG.PCW_IRQ_F2P_INTR 1 +ad_ip_parameter sys_ps7 CONFIG.PCW_IRQ_F2P_MODE REVERSE +ad_ip_parameter sys_ps7 CONFIG.PCW_MIO_0_PULLUP {enabled} +ad_ip_parameter sys_ps7 CONFIG.PCW_MIO_9_PULLUP {enabled} +ad_ip_parameter sys_ps7 CONFIG.PCW_MIO_10_PULLUP {enabled} +ad_ip_parameter sys_ps7 CONFIG.PCW_MIO_11_PULLUP {enabled} +ad_ip_parameter sys_ps7 CONFIG.PCW_MIO_48_PULLUP {enabled} +ad_ip_parameter sys_ps7 CONFIG.PCW_MIO_49_PULLUP {disabled} +ad_ip_parameter sys_ps7 CONFIG.PCW_MIO_53_PULLUP {enabled} +ad_ip_parameter sys_ps7 CONFIG.PCW_APU_PERIPHERAL_FREQMHZ 750 + +# DDR MT41K256M16 HA-125 (32M, 16bit, 8banks) + +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_ACT_DDR_FREQ_MHZ 525 +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_PARTNO {Custom} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_BANK_ADDR_COUNT {3} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_ROW_ADDR_COUNT {15} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_COL_ADDR_COUNT {10} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_CL {7} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_CWL {5} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_T_RCD {7} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_T_RP {7} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_T_RC {48.91} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_T_RAS_MIN {35.0} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_T_FAW {40.0} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_0 {0.048} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_1 {0.050} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY0 {0.241} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY1 {0.240} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_ECC {Disabled} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_BUS_WIDTH {32 Bit} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_DRAM_WIDTH {16 Bits} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_DEVICE_CAPACITY {4096 MBits} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_SPEED_BIN {DDR3_1066F} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_TRAIN_WRITE_LEVEL {1} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_TRAIN_READ_GATE {1} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_TRAIN_DATA_EYE {1} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_USE_INTERNAL_VREF {0} + +ad_ip_instance xlconcat sys_concat_intc +ad_ip_parameter sys_concat_intc CONFIG.NUM_PORTS 16 + +ad_ip_instance proc_sys_reset sys_rstgen +ad_ip_parameter sys_rstgen CONFIG.C_EXT_RST_WIDTH 1 + +# system reset/clock definitions + +# add external spi + +ad_ip_instance axi_quad_spi axi_spi +ad_ip_parameter axi_spi CONFIG.C_USE_STARTUP 0 +ad_ip_parameter axi_spi CONFIG.C_NUM_SS_BITS 1 +ad_ip_parameter axi_spi CONFIG.C_SCK_RATIO 8 + +ad_connect sys_cpu_clk sys_ps7/FCLK_CLK0 +ad_connect sys_200m_clk sys_ps7/FCLK_CLK1 +ad_connect sys_cpu_reset sys_rstgen/peripheral_reset +ad_connect sys_cpu_resetn sys_rstgen/peripheral_aresetn +ad_connect sys_cpu_clk sys_rstgen/slowest_sync_clk +ad_connect sys_rstgen/ext_reset_in sys_ps7/FCLK_RESET0_N + +# interface connections + +ad_connect ddr sys_ps7/DDR +ad_connect gpio_i sys_ps7/GPIO_I +ad_connect gpio_o sys_ps7/GPIO_O +ad_connect gpio_t sys_ps7/GPIO_T +ad_connect fixed_io sys_ps7/FIXED_IO + +# ps7 spi connections + +ad_connect spi0_csn_2_o sys_ps7/SPI0_SS2_O +ad_connect spi0_csn_1_o sys_ps7/SPI0_SS1_O +ad_connect spi0_csn_0_o sys_ps7/SPI0_SS_O +ad_connect spi0_csn_i sys_ps7/SPI0_SS_I +ad_connect spi0_clk_i sys_ps7/SPI0_SCLK_I +ad_connect spi0_clk_o sys_ps7/SPI0_SCLK_O +ad_connect spi0_sdo_i sys_ps7/SPI0_MOSI_I +ad_connect spi0_sdo_o sys_ps7/SPI0_MOSI_O +ad_connect spi0_sdi_i sys_ps7/SPI0_MISO_I + +# axi spi connections + +ad_connect sys_cpu_clk axi_spi/ext_spi_clk +ad_connect spi_csn_i axi_spi/ss_i +ad_connect spi_csn_o axi_spi/ss_o +ad_connect spi_clk_i axi_spi/sck_i +ad_connect spi_clk_o axi_spi/sck_o +ad_connect spi_sdo_i axi_spi/io0_i +ad_connect spi_sdo_o axi_spi/io0_o +ad_connect spi_sdi_i axi_spi/io1_i + +# interrupts + +ad_connect sys_concat_intc/dout sys_ps7/IRQ_F2P +ad_connect sys_concat_intc/In15 GND +ad_connect sys_concat_intc/In14 GND +ad_connect sys_concat_intc/In13 GND +ad_connect sys_concat_intc/In12 GND +ad_connect sys_concat_intc/In11 GND +ad_connect sys_concat_intc/In10 GND +ad_connect sys_concat_intc/In9 GND +ad_connect sys_concat_intc/In8 GND +ad_connect sys_concat_intc/In7 GND +ad_connect sys_concat_intc/In6 GND +ad_connect sys_concat_intc/In5 GND +ad_connect sys_concat_intc/In4 GND +ad_connect sys_concat_intc/In3 GND +ad_connect sys_concat_intc/In2 GND +ad_connect sys_concat_intc/In1 GND +ad_connect sys_concat_intc/In0 GND + +# iic + +create_bd_intf_port -mode Master -vlnv xilinx.com:interface:iic_rtl:1.0 iic_main + +ad_ip_instance axi_iic axi_iic_main + +ad_connect iic_main axi_iic_main/iic +ad_cpu_interconnect 0x41600000 axi_iic_main +ad_cpu_interrupt ps-15 mb-15 axi_iic_main/iic2intc_irpt + +# ad9361 + +create_bd_port -dir I rx_clk_in_p +create_bd_port -dir I rx_clk_in_n +create_bd_port -dir I rx_frame_in_p +create_bd_port -dir I rx_frame_in_n +create_bd_port -dir I -from 5 -to 0 rx_data_in_p +create_bd_port -dir I -from 5 -to 0 rx_data_in_n + +create_bd_port -dir O tx_clk_out_p +create_bd_port -dir O tx_clk_out_n +create_bd_port -dir O tx_frame_out_p +create_bd_port -dir O tx_frame_out_n +create_bd_port -dir O -from 5 -to 0 tx_data_out_p +create_bd_port -dir O -from 5 -to 0 tx_data_out_n + +create_bd_port -dir O enable +create_bd_port -dir O txnrx +create_bd_port -dir I up_enable +create_bd_port -dir I up_txnrx + +# ad9361 core +ad_ip_instance axi_ad9361 axi_ad9361 +ad_ip_parameter axi_ad9361 CONFIG.ID 0 +ad_ip_parameter axi_ad9361 CONFIG.CMOS_OR_LVDS_N 0 + +# This place is horrible +ad_ip_parameter axi_ad9361 CONFIG.MODE_1R1T 0 +ad_ip_parameter axi_ad9361 CONFIG.ADC_INIT_DELAY 30 + +# TDD, DDS, and more +ad_ip_parameter axi_ad9361 CONFIG.TDD_DISABLE 1 +ad_ip_parameter axi_ad9361 CONFIG.DAC_DDS_DISABLE 1 +ad_ip_parameter axi_ad9361 CONFIG.ADC_DCFILTER_DISABLE 1 +ad_ip_parameter axi_ad9361 CONFIG.ADC_IQCORRECTION_DISABLE 1 +ad_ip_parameter axi_ad9361 CONFIG.DAC_IQCORRECTION_DISABLE 1 + +# Enable user ports for direct MSK connection +ad_ip_parameter axi_ad9361 CONFIG.DAC_USERPORTS_DISABLE 0 +ad_ip_parameter axi_ad9361 CONFIG.ADC_USERPORTS_DISABLE 0 + +# DAC DMA - TX data from PS to MSK +ad_ip_instance axi_dmac axi_ad9361_dac_dma +ad_ip_parameter axi_ad9361_dac_dma CONFIG.DMA_TYPE_SRC 0 +ad_ip_parameter axi_ad9361_dac_dma CONFIG.DMA_TYPE_DEST 1 +ad_ip_parameter axi_ad9361_dac_dma CONFIG.CYCLIC 0 +ad_ip_parameter axi_ad9361_dac_dma CONFIG.AXI_SLICE_SRC 0 +ad_ip_parameter axi_ad9361_dac_dma CONFIG.AXI_SLICE_DEST 0 +ad_ip_parameter axi_ad9361_dac_dma CONFIG.DMA_2D_TRANSFER 0 +ad_ip_parameter axi_ad9361_dac_dma CONFIG.DMA_DATA_WIDTH_DEST 32 + +# ADC DMA - RX data from MSK to PS (AXIS interface) +ad_ip_instance axi_dmac axi_ad9361_adc_dma +ad_ip_parameter axi_ad9361_adc_dma CONFIG.DMA_TYPE_SRC 1 +ad_ip_parameter axi_ad9361_adc_dma CONFIG.DMA_TYPE_DEST 0 +ad_ip_parameter axi_ad9361_adc_dma CONFIG.CYCLIC 0 +ad_ip_parameter axi_ad9361_adc_dma CONFIG.SYNC_TRANSFER_START 0 +ad_ip_parameter axi_ad9361_adc_dma CONFIG.AXI_SLICE_SRC 0 +ad_ip_parameter axi_ad9361_adc_dma CONFIG.AXI_SLICE_DEST 0 +ad_ip_parameter axi_ad9361_adc_dma CONFIG.DMA_2D_TRANSFER 0 +ad_ip_parameter axi_ad9361_adc_dma CONFIG.DMA_DATA_WIDTH_SRC 32 + +# connections + +ad_connect rx_clk_in_p axi_ad9361/rx_clk_in_p +ad_connect rx_clk_in_n axi_ad9361/rx_clk_in_n +ad_connect rx_frame_in_p axi_ad9361/rx_frame_in_p +ad_connect rx_frame_in_n axi_ad9361/rx_frame_in_n +ad_connect rx_data_in_p axi_ad9361/rx_data_in_p +ad_connect rx_data_in_n axi_ad9361/rx_data_in_n +ad_connect tx_clk_out_p axi_ad9361/tx_clk_out_p +ad_connect tx_clk_out_n axi_ad9361/tx_clk_out_n +ad_connect tx_frame_out_p axi_ad9361/tx_frame_out_p +ad_connect tx_frame_out_n axi_ad9361/tx_frame_out_n +ad_connect tx_data_out_p axi_ad9361/tx_data_out_p +ad_connect tx_data_out_n axi_ad9361/tx_data_out_n +ad_connect enable axi_ad9361/enable +ad_connect txnrx axi_ad9361/txnrx +ad_connect up_enable axi_ad9361/up_enable +ad_connect up_txnrx axi_ad9361/up_txnrx + +ad_connect axi_ad9361/tdd_sync GND +ad_connect sys_200m_clk axi_ad9361/delay_clk +ad_connect axi_ad9361/l_clk axi_ad9361/clk + +# Logic OR for reset +ad_ip_instance util_vector_logic logic_or_1 [list \ + C_OPERATION {or} \ + C_SIZE 1] + +ad_connect logic_or_1/Op1 axi_ad9361/rst +ad_connect logic_or_1/Op2 GND + +# DMA clock connections - these stay at l_clk (245 MHz) +ad_connect axi_ad9361/l_clk axi_ad9361_adc_dma/s_axis_aclk +ad_connect axi_ad9361/l_clk axi_ad9361_dac_dma/m_axis_aclk + +# Tie off unused signals +ad_connect GND axi_ad9361/adc_dovf +ad_connect GND axi_ad9361/dac_dunf + +# interconnects + +ad_cpu_interconnect 0x79020000 axi_ad9361 +ad_cpu_interconnect 0x7C400000 axi_ad9361_adc_dma +ad_cpu_interconnect 0x7C420000 axi_ad9361_dac_dma +ad_cpu_interconnect 0x7C430000 axi_spi + +ad_ip_parameter sys_ps7 CONFIG.PCW_USE_S_AXI_HP1 {1} +ad_connect sys_cpu_clk sys_ps7/S_AXI_HP1_ACLK +ad_connect axi_ad9361_adc_dma/m_dest_axi sys_ps7/S_AXI_HP1 + +create_bd_addr_seg -range 0x40000000 -offset 0x00000000 \ + [get_bd_addr_spaces axi_ad9361_adc_dma/m_dest_axi] \ + [get_bd_addr_segs sys_ps7/S_AXI_HP1/HP1_DDR_LOWOCM] \ + SEG_sys_ps7_HP1_DDR_LOWOCM + +ad_ip_parameter sys_ps7 CONFIG.PCW_USE_S_AXI_HP2 {1} +ad_connect sys_cpu_clk sys_ps7/S_AXI_HP2_ACLK +ad_connect axi_ad9361_dac_dma/m_src_axi sys_ps7/S_AXI_HP2 + +create_bd_addr_seg -range 0x40000000 -offset 0x00000000 \ + [get_bd_addr_spaces axi_ad9361_dac_dma/m_src_axi] \ + [get_bd_addr_segs sys_ps7/S_AXI_HP2/HP2_DDR_LOWOCM] \ + SEG_sys_ps7_HP2_DDR_LOWOCM + +ad_connect sys_cpu_clk axi_ad9361_dac_dma/m_src_axi_aclk +ad_connect sys_cpu_clk axi_ad9361_adc_dma/m_dest_axi_aclk +ad_connect sys_cpu_resetn axi_ad9361_adc_dma/m_dest_axi_aresetn +ad_connect sys_cpu_resetn axi_ad9361_dac_dma/m_src_axi_aresetn + +# interrupts + +ad_cpu_interrupt ps-13 mb-13 axi_ad9361_adc_dma/irq +ad_cpu_interrupt ps-12 mb-12 axi_ad9361_dac_dma/irq +ad_cpu_interrupt ps-11 mb-11 axi_spi/ip2intc_irpt + + +############################################################################## +# CLOCK_DIVIDER: Clock divider for MSK modem (245.76 MHz -> 61.44 MHz) +############################################################################## +# Uses BUFR primitive to divide l_clk by 4. +# This provides a phase-aligned 61.44 MHz clock for the MSK modem. +# The BUFR output edges align with every 4th l_clk edge, ensuring proper +# timing for DAC/ADC data which is stable for 4 l_clk cycles per sample. +############################################################################## + +# Add the clock divider source file to the project before creating the BD cell +add_files -norecurse ../../src/clk_div_by4.vhd +update_compile_order -fileset sources_1 + +create_bd_cell -type module -reference clk_div_by4 clk_divider +ad_connect axi_ad9361/l_clk clk_divider/clk_in + + +############################################################################## +# MSK Modem Integration +############################################################################## + +ad_ip_instance msk_top msk_top + +# CLOCK_DIVIDER: MSK processing clock - use divided clock (61.44 MHz) +# This is where the NCO, modulator, demodulator all run +ad_connect msk_top/clk clk_divider/clk_out + +# CLOCK_DIVIDER: MSK AXIS clock - keep at l_clk (245 MHz) for DMA interface +# The async FIFO inside msk_top handles CDC between s_axis_aclk and clk +# TX input (s_axis_aclk): stays at l_clk because TX DMA feeds through the 245 MHz domain +# RX output (m_axis_aclk): now at sys_cpu_clk (100 MHz) because RX DMA runs there +ad_connect msk_top/s_axis_aclk axi_ad9361/l_clk +ad_connect msk_top/m_axis_aclk sys_cpu_clk + + +# MSK AXI-Lite register interface (100 MHz CPU clock) +ad_connect msk_top/s_axi_aclk sys_cpu_clk +ad_connect msk_top/s_axis_aresetn sys_cpu_resetn +ad_connect msk_top/s_axi_aresetn sys_cpu_resetn + +# MSK AXI-Lite register interface +ad_cpu_interconnect 0x43C00000 msk_top + +# MSK TX Connects - Channel 0 I/Q to AD9361 +# CLOCK_DIVIDER: TX samples need to be synchronized from clk_div4 to l_clk domain +# The msk_top outputs change on clk_div4 edges, but AD9361 samples on l_clk. +# Without sync, the DAC might catch glitches during transitions. + +# Create sync registers for TX I/Q (resample clk_div4 outputs to l_clk) +create_bd_cell -type ip -vlnv xilinx.com:ip:c_shift_ram:12.0 tx_i_sync +set_property -dict [list \ + CONFIG.Width {16} \ + CONFIG.Depth {2} \ + CONFIG.DefaultData {0000000000000000} \ + CONFIG.AsyncInitVal {0000000000000000} \ +] [get_bd_cells tx_i_sync] + +create_bd_cell -type ip -vlnv xilinx.com:ip:c_shift_ram:12.0 tx_q_sync +set_property -dict [list \ + CONFIG.Width {16} \ + CONFIG.Depth {2} \ + CONFIG.DefaultData {0000000000000000} \ + CONFIG.AsyncInitVal {0000000000000000} \ +] [get_bd_cells tx_q_sync] + +# Clock sync registers with l_clk (245 MHz) +ad_connect axi_ad9361/l_clk tx_i_sync/CLK +ad_connect axi_ad9361/l_clk tx_q_sync/CLK + +# MSK outputs -> sync registers +ad_connect msk_top/tx_samples_I tx_i_sync/D +ad_connect msk_top/tx_samples_Q tx_q_sync/D + +# Sync registers -> AD9361 Channel 0 +ad_connect tx_i_sync/Q axi_ad9361/dac_data_i0 +ad_connect tx_q_sync/Q axi_ad9361/dac_data_q0 +ad_connect msk_top/tx_enable axi_ad9361/dac_enable_i0 +#ad_connect msk_top/tx_enable axi_ad9361/dac_enable_q0 + +#The dac_enable_* signals are outputs from axi_ad9361 indicating +#which channels are active (set by software). +#Not connecting dac_enable_q0 doesn't disable Q. +#It just means nobody reads that status signal. + +# Sync registers -> AD9361 Channel 1 (duplicate for LVDS interleaving) +ad_connect tx_i_sync/Q axi_ad9361/dac_data_i1 +ad_connect tx_q_sync/Q axi_ad9361/dac_data_q1 +#ad_connect msk_top/tx_enable axi_ad9361/dac_enable_i1 +#ad_connect msk_top/tx_enable axi_ad9361/dac_enable_q1 + +# CLOCK_DIVIDER: tx_valid tied HIGH - every 61.44 MHz clock cycle is a valid sample +# (Previously connected to dac_valid_i0 which pulses in l_clk domain) +#ad_connect msk_top/tx_valid VCC + +# ok that was a bad idea maybe, connect it back +# TX side - connect to actual DAC valid, using pulse stretcher. +ad_connect axi_ad9361/dac_valid_i0 clk_divider/dac_valid_in +ad_connect clk_divider/dac_valid_out msk_top/tx_valid + +# TX DMA Connections +ad_connect axi_ad9361_dac_dma/m_axis_data msk_top/s_axis_tdata +ad_connect axi_ad9361_dac_dma/m_axis_valid msk_top/s_axis_tvalid +ad_connect axi_ad9361_dac_dma/m_axis_ready msk_top/s_axis_tready +ad_connect axi_ad9361_dac_dma/m_axis_last msk_top/s_axis_tlast +ad_connect axi_ad9361_dac_dma/m_axis_keep msk_top/s_axis_tkeep + +# MSK RX Connects - Channel 0 I/Q from AD9361 +ad_connect msk_top/rx_samples_I axi_ad9361/adc_data_i0 +ad_connect msk_top/rx_samples_Q axi_ad9361/adc_data_q0 +ad_connect msk_top/rx_enable axi_ad9361/adc_enable_i0 + +# CLOCK_DIVIDER: rx_svalid tied HIGH - every 61.44 MHz clock cycle is a valid sample +# (Previously connected to adc_valid_i0 which pulses in l_clk domain) +#ad_connect msk_top/rx_svalid VCC + +# Ok that might have been a bad idea. Connect it back, using pulse stretcher. +ad_connect axi_ad9361/adc_valid_i0 clk_divider/adc_valid_in +ad_connect clk_divider/adc_valid_out msk_top/rx_svalid + +# MSK RX AXIS to DMA - interface connection +ad_connect msk_top/m_axis axi_ad9361_adc_dma/s_axis + +############################################################################## +# ILA Debug Core - Deserializer Monitoring +############################################################################## +# Captures deserializer signals in clk_div4 domain (61 MHz). +# +# Probes: +# probe0: tx_data_bit - bit output to modulator +# probe1: tx_req - modulator requesting next bit +# probe2: encoder_tvalid - encoder has data available +# probe3: encoder_tready - deserializer ready for byte +# probe4: frame_complete - end of frame marker +# +# At 61 MHz with 16384 samples, we get ~268us of capture (~6.8 frames). +# At 61 MHz with 32768 samples, we get more time fails to place (over on BRAM) +# Look for patterns at byte boundaries (every 8 tx_req pulses). +############################################################################## +#create_bd_cell -type ip -vlnv xilinx.com:ip:ila:6.2 ila_msk_tx +#set_property -dict [list \ +# CONFIG.C_PROBE0_WIDTH {1} \ +# CONFIG.C_PROBE1_WIDTH {1} \ +# CONFIG.C_PROBE2_WIDTH {1} \ +# CONFIG.C_PROBE3_WIDTH {1} \ +# CONFIG.C_PROBE4_WIDTH {1} \ +# CONFIG.C_PROBE5_WIDTH {8} \ +# CONFIG.C_NUM_OF_PROBES {6} \ +# CONFIG.C_DATA_DEPTH {16384} \ +# CONFIG.C_TRIGIN_EN {false} \ +# CONFIG.C_EN_STRG_QUAL {1} \ +# CONFIG.ALL_PROBE_SAME_MU_CNT {2} \ +#] [get_bd_cells ila_msk_tx] +## Clock ILA with clk_div4 (61 MHz) - deserializer clock domain +#ad_connect clk_divider/clk_out ila_msk_tx/clk +## Probe 0: tx_data_bit - the bit going to modulator +#ad_connect msk_top/dbg_tx_data_bit ila_msk_tx/probe0 +## Probe 1: tx_req - when modulator requests a bit +#ad_connect msk_top/dbg_tx_req ila_msk_tx/probe1 +## Probe 2: encoder_tvalid - data available from encoder +#ad_connect msk_top/dbg_encoder_tvalid ila_msk_tx/probe2 +## Probe 3: encoder_tready - deserializer ready for data +#ad_connect msk_top/dbg_encoder_tready ila_msk_tx/probe3 +## Probe 4: frame_complete - end of frame marker +#ad_connect msk_top/dbg_frame_complete ila_msk_tx/probe4 +## Probe 5: encoder_tdata - 8-bit data from encoder to deserializer +#ad_connect msk_top/dbg_encoder_tdata ila_msk_tx/probe5 + + + + +############################################################################## +# ILA Debug Core - TX DAC Path Monitoring +############################################################################## +# Add this after the existing ila_msk_tx section in system_bd.tcl +# Probes the I/Q samples going to the AD9361 +############################################################################## + +#create_bd_cell -type ip -vlnv xilinx.com:ip:ila:6.2 ila_dac_tx +#set_property -dict [list \ +# CONFIG.C_MONITOR_TYPE {Native} \ +# CONFIG.C_NUM_OF_PROBES {7} \ +# CONFIG.C_PROBE0_WIDTH {16} \ +# CONFIG.C_PROBE1_WIDTH {16} \ +# CONFIG.C_PROBE2_WIDTH {16} \ +# CONFIG.C_PROBE3_WIDTH {16} \ +# CONFIG.C_PROBE4_WIDTH {1} \ +# CONFIG.C_PROBE5_WIDTH {1} \ +# CONFIG.C_PROBE6_WIDTH {1} \ +# CONFIG.C_DATA_DEPTH {4096} \ +# CONFIG.C_TRIGIN_EN {false} \ +# CONFIG.C_EN_STRG_QUAL {1} \ +# CONFIG.ALL_PROBE_SAME_MU_CNT {2} \ +#] [get_bd_cells ila_dac_tx] + +# Clock with l_clk (245 MHz) - same as AD9361 DAC interface +#ad_connect axi_ad9361/l_clk ila_dac_tx/clk + +# Probe 0: TX I samples from msk_top (before CDC) +#ad_connect msk_top/tx_samples_I ila_dac_tx/probe0 + +# Probe 1: TX Q samples from msk_top (before CDC) +#ad_connect msk_top/tx_samples_Q ila_dac_tx/probe1 + +# Probe 2: TX I after CDC sync (going to AD9361) +#ad_connect tx_i_sync/Q ila_dac_tx/probe2 + +# Probe 3: TX Q after CDC sync (going to AD9361) +#ad_connect tx_q_sync/Q ila_dac_tx/probe3 + +# Probe 4: TX enable signal +#ad_connect msk_top/tx_enable ila_dac_tx/probe4 + +# Probe 5: dac_valid_i0 - DAC valid signal from AD9361 +#ad_connect axi_ad9361/dac_valid_i0 ila_dac_tx/probe5 + +# Probe 6: adc_valid_i0 - ADC valid signal from AD9361 (while we're at it) +#ad_connect axi_ad9361/adc_valid_i0 ila_dac_tx/probe6 + +############################################################################## +# FUTURE DEBUG: Comprehensive MSK Datapath ILA +############################################################################## +# Uncomment this section to add a second ILA for internal datapath debugging. +# This ILA runs at the modem clock (61.44 MHz) to capture the bit-level signals. +# +# OBSERVATION POINTS IN TX PATH: +# ───────────────────────────────────────────────────────────────────────────── +# 1. FIFO output (after CDC from PS clock to modem clock): +# - fifo_tdata[7:0] : Byte from async FIFO +# - fifo_tvalid : FIFO has data +# - fifo_tready : Encoder ready to accept +# - fifo_tlast : Frame boundary marker +# +# 2. Encoder output (after FEC, interleaving): +# - encoder_tdata[7:0] : Encoded byte to deserializer +# - encoder_tvalid : Encoder has data +# - encoder_tready : Deserializer ready +# - encoder_tlast : Encoded frame boundary +# - encoder_debug_state[2:0] : Encoder FSM state +# +# 3. Deserializer output (byte-to-bit conversion): +# - tx_data_bit : Current bit to modulator +# - tx_req : Modulator requesting next bit (tclk pulse) +# - frame_complete : End of frame marker +# +# 4. Modulator internals (if needed): +# - tclk : Bit clock from NCO +# - tx_samples_I[15:0] : I samples (already in ila_dac_tx) +# - tx_samples_Q[15:0] : Q samples (already in ila_dac_tx) +# +# SIGNALS ACTIVE IN CURRENT ila_dac_tx (245 MHz, l_clk domain): +# - probe0: tx_samples_I[15:0] - I samples before CDC +# - probe1: tx_samples_Q[15:0] - Q samples before CDC +# - probe2: tx_i_sync/Q[15:0] - I samples after CDC (to AD9361) +# - probe3: tx_q_sync/Q[15:0] - Q samples after CDC (to AD9361) +# - probe4: tx_enable - TX enable signal +# +# TO DEBUG 3375 Hz SPURS (16-bit periodicity): +# If the problem is us, then it is likely to be +# in the encoder to deserializer handshaking. +# Enable ila_msk_tx below to capture bit-level timing. +# ───────────────────────────────────────────────────────────────────────────── + +create_bd_cell -type ip -vlnv xilinx.com:ip:ila:6.2 ila_msk_tx +set_property -dict [list \ + CONFIG.C_MONITOR_TYPE {Native} \ + CONFIG.C_NUM_OF_PROBES {10} \ + CONFIG.C_PROBE0_WIDTH {1} \ + CONFIG.C_PROBE1_WIDTH {1} \ + CONFIG.C_PROBE2_WIDTH {1} \ + CONFIG.C_PROBE3_WIDTH {1} \ + CONFIG.C_PROBE4_WIDTH {8} \ + CONFIG.C_PROBE5_WIDTH {1} \ + CONFIG.C_PROBE6_WIDTH {8} \ + CONFIG.C_PROBE7_WIDTH {1} \ + CONFIG.C_PROBE8_WIDTH {1} \ + CONFIG.C_PROBE9_WIDTH {3} \ + CONFIG.C_DATA_DEPTH {16384} \ + CONFIG.C_TRIGIN_EN {false} \ + CONFIG.C_EN_STRG_QUAL {1} \ + CONFIG.ALL_PROBE_SAME_MU_CNT {2} \ +] [get_bd_cells ila_msk_tx] + +# Clock with divided clock (61.44 MHz) - modem clock domain +ad_connect clk_divider/clk_out ila_msk_tx/clk + +# Probe 0: tx_data_bit - bit output to modulator +ad_connect msk_top/dbg_tx_data_bit ila_msk_tx/probe0 + +# Probe 1: tx_req - modulator requesting next bit (tclk) +ad_connect msk_top/dbg_tx_req ila_msk_tx/probe1 + +# Probe 2: encoder_tvalid - encoder has data available +ad_connect msk_top/dbg_encoder_tvalid ila_msk_tx/probe2 + +# Probe 3: encoder_tready - deserializer ready for byte +ad_connect msk_top/dbg_encoder_tready ila_msk_tx/probe3 + +# Probe 4: encoder_tdata - encoded byte data +ad_connect msk_top/dbg_encoder_tdata ila_msk_tx/probe4 + +# Probe 5: frame_complete - end of frame marker +ad_connect msk_top/dbg_frame_complete ila_msk_tx/probe5 + +# Probe 6: fifo_tdata - data from async FIFO (now exposed in msk_top) +ad_connect msk_top/dbg_fifo_tdata ila_msk_tx/probe6 + +# Probe 7: fifo_tvalid - FIFO has data (now exposed in msk_top) +ad_connect msk_top/dbg_fifo_tvalid ila_msk_tx/probe7 + +# Probe 8: fifo_tready - encoder ready for FIFO data (now exposed in msk_top) +ad_connect msk_top/dbg_fifo_tready ila_msk_tx/probe8 + +# Probe 9: encoder_debug_state - encoder FSM state (now exposed in msk_top) +ad_connect msk_top/dbg_encoder_state ila_msk_tx/probe9 + + + + +############################################################################## +# ILA Debug Core - Randomizer Monitoring +############################################################################## +create_bd_cell -type ip -vlnv xilinx.com:ip:ila:6.2 ila_randomizer +set_property -dict [list \ + CONFIG.C_MONITOR_TYPE {Native} \ + CONFIG.C_NUM_OF_PROBES {5} \ + CONFIG.C_PROBE0_WIDTH {8} \ + CONFIG.C_PROBE1_WIDTH {8} \ + CONFIG.C_PROBE2_WIDTH {8} \ + CONFIG.C_PROBE3_WIDTH {1} \ + CONFIG.C_PROBE4_WIDTH {3} \ + CONFIG.C_DATA_DEPTH {16384} \ + CONFIG.C_TRIGIN_EN {false} \ + CONFIG.C_EN_STRG_QUAL {1} \ + CONFIG.ALL_PROBE_SAME_MU_CNT {2} \ +] [get_bd_cells ila_randomizer] + +ad_connect clk_divider/clk_out ila_randomizer/clk + +# Probe 0: LFSR state (should cycle through values, NOT stuck at FF) +ad_connect msk_top/dbg_lfsr_state ila_randomizer/probe0 + +# Probe 1: Input byte (before XOR) +ad_connect msk_top/dbg_input_byte ila_randomizer/probe1 + +# Probe 2: Randomized byte (after XOR) - should be input XOR lfsr_output +ad_connect msk_top/dbg_rand_byte ila_randomizer/probe2 + +# Probe 3: Randomize active (trigger on rising edge to capture start) +ad_connect msk_top/dbg_rand_active ila_randomizer/probe3 + +# Probe 4: Encoder state +ad_connect msk_top/dbg_encoder_state ila_randomizer/probe4 + + + + + + + + + + + + +############################################################################## +# LVDS SIGNALS (External - requires scope/logic analyzer) +############################################################################## +# These are physical pins going to the AD9361 chip: +# tx_clk_out_p/n : TX clock to AD9361 +# tx_frame_out_p/n : TX frame signal +# tx_data_out_p/n : TX data (6-bit DDR) +# +# Cannot probe with ILA - need external test equipment. +# The axi_ad9361 IP handles the LVDS serialization internally. +############################################################################## diff --git a/projects/libre/system_constr.xdc b/projects/libre/system_constr.xdc new file mode 100644 index 0000000..d8f7e59 --- /dev/null +++ b/projects/libre/system_constr.xdc @@ -0,0 +1,164 @@ +# LibreSDR XC7Z020-CLG400 Pin Constraints +# Extracted from hz12opensource/libresdr hdl.diff patch + +# ============================================================================= +# Clock Constraints +# ============================================================================= + +# AD9363 LVDS RX clock (125 MHz max) +create_clock -name rx_clk -period 16.27 [get_ports rx_clk_in_p] +# needed to be updated to LVDS +#create_clock -name rx_clk -period 4.069 [get_ports rx_clk_in_p] + +# PS7 fabric clocks +create_clock -name clk_fpga_0 -period 10 [get_pins "i_system_wrapper/system_i/sys_ps7/inst/PS7_i/FCLKCLK[0]"] +create_clock -name clk_fpga_1 -period 5 [get_pins "i_system_wrapper/system_i/sys_ps7/inst/PS7_i/FCLKCLK[1]"] + +# SPI clock +create_clock -name spi0_clk -period 40 [get_pins -hier */EMIOSPI0SCLKO] + +# ============================================================================= +# AD9363 LVDS Interface - Bank 34 (2.5V) +# ============================================================================= + +# RX Clock (differential) +set_property -dict {PACKAGE_PIN N20 IOSTANDARD LVDS_25 DIFF_TERM 1} [get_ports rx_clk_in_p] +set_property -dict {PACKAGE_PIN P20 IOSTANDARD LVDS_25 DIFF_TERM 1} [get_ports rx_clk_in_n] + +# RX Frame (differential) +set_property -dict {PACKAGE_PIN U18 IOSTANDARD LVDS_25 DIFF_TERM 1} [get_ports rx_frame_in_p] +set_property -dict {PACKAGE_PIN U19 IOSTANDARD LVDS_25 DIFF_TERM 1} [get_ports rx_frame_in_n] + +# RX Data (differential) [5:0] - CORRECTED +set_property -dict {PACKAGE_PIN Y18 IOSTANDARD LVDS_25 DIFF_TERM 1} [get_ports {rx_data_in_p[0]}] +set_property -dict {PACKAGE_PIN Y19 IOSTANDARD LVDS_25 DIFF_TERM 1} [get_ports {rx_data_in_n[0]}] +set_property -dict {PACKAGE_PIN V17 IOSTANDARD LVDS_25 DIFF_TERM 1} [get_ports {rx_data_in_p[1]}] +set_property -dict {PACKAGE_PIN V18 IOSTANDARD LVDS_25 DIFF_TERM 1} [get_ports {rx_data_in_n[1]}] +set_property -dict {PACKAGE_PIN V20 IOSTANDARD LVDS_25 DIFF_TERM 1} [get_ports {rx_data_in_p[2]}] +set_property -dict {PACKAGE_PIN W20 IOSTANDARD LVDS_25 DIFF_TERM 1} [get_ports {rx_data_in_n[2]}] +set_property -dict {PACKAGE_PIN R16 IOSTANDARD LVDS_25 DIFF_TERM 1} [get_ports {rx_data_in_p[3]}] +set_property -dict {PACKAGE_PIN R17 IOSTANDARD LVDS_25 DIFF_TERM 1} [get_ports {rx_data_in_n[3]}] +set_property -dict {PACKAGE_PIN W18 IOSTANDARD LVDS_25 DIFF_TERM 1} [get_ports {rx_data_in_p[4]}] +set_property -dict {PACKAGE_PIN W19 IOSTANDARD LVDS_25 DIFF_TERM 1} [get_ports {rx_data_in_n[4]}] +set_property -dict {PACKAGE_PIN V16 IOSTANDARD LVDS_25 DIFF_TERM 1} [get_ports {rx_data_in_p[5]}] +set_property -dict {PACKAGE_PIN W16 IOSTANDARD LVDS_25 DIFF_TERM 1} [get_ports {rx_data_in_n[5]}] + +# TX Clock (differential) +set_property -dict {PACKAGE_PIN N18 IOSTANDARD LVDS_25} [get_ports tx_clk_out_p] +set_property -dict {PACKAGE_PIN P19 IOSTANDARD LVDS_25} [get_ports tx_clk_out_n] + +# TX Frame (differential) +set_property -dict {PACKAGE_PIN Y16 IOSTANDARD LVDS_25} [get_ports tx_frame_out_p] +set_property -dict {PACKAGE_PIN Y17 IOSTANDARD LVDS_25} [get_ports tx_frame_out_n] + +# TX Data (differential) [5:0] +set_property -dict {PACKAGE_PIN W14 IOSTANDARD LVDS_25} [get_ports {tx_data_out_p[0]}] +set_property -dict {PACKAGE_PIN Y14 IOSTANDARD LVDS_25} [get_ports {tx_data_out_n[0]}] +set_property -dict {PACKAGE_PIN T12 IOSTANDARD LVDS_25} [get_ports {tx_data_out_p[1]}] +set_property -dict {PACKAGE_PIN U12 IOSTANDARD LVDS_25} [get_ports {tx_data_out_n[1]}] +set_property -dict {PACKAGE_PIN U14 IOSTANDARD LVDS_25} [get_ports {tx_data_out_p[2]}] +set_property -dict {PACKAGE_PIN U15 IOSTANDARD LVDS_25} [get_ports {tx_data_out_n[2]}] +set_property -dict {PACKAGE_PIN T16 IOSTANDARD LVDS_25} [get_ports {tx_data_out_p[3]}] +set_property -dict {PACKAGE_PIN U17 IOSTANDARD LVDS_25} [get_ports {tx_data_out_n[3]}] +set_property -dict {PACKAGE_PIN V12 IOSTANDARD LVDS_25} [get_ports {tx_data_out_p[4]}] +set_property -dict {PACKAGE_PIN W13 IOSTANDARD LVDS_25} [get_ports {tx_data_out_n[4]}] +set_property -dict {PACKAGE_PIN V15 IOSTANDARD LVDS_25} [get_ports {tx_data_out_p[5]}] +set_property -dict {PACKAGE_PIN W15 IOSTANDARD LVDS_25} [get_ports {tx_data_out_n[5]}] + +# ============================================================================= +# AD9363 Control Signals +# ============================================================================= + +# Enable and TxNRx +set_property -dict {PACKAGE_PIN R18 IOSTANDARD LVCMOS25} [get_ports enable] +set_property -dict {PACKAGE_PIN P14 IOSTANDARD LVCMOS25} [get_ports txnrx] + +# GPIO Reset and AGC +set_property -dict {PACKAGE_PIN N17 IOSTANDARD LVCMOS25} [get_ports gpio_resetb] +set_property -dict {PACKAGE_PIN P16 IOSTANDARD LVCMOS25} [get_ports gpio_en_agc] + +# ============================================================================= +# GPIO Status [7:0] - Bank 34 (2.5V) +# ============================================================================= + +set_property -dict {PACKAGE_PIN T11 IOSTANDARD LVCMOS25} [get_ports {gpio_status[0]}] +set_property -dict {PACKAGE_PIN T17 IOSTANDARD LVCMOS25} [get_ports {gpio_status[3]}] +set_property -dict {PACKAGE_PIN T19 IOSTANDARD LVCMOS25} [get_ports {gpio_status[4]}] +set_property -dict {PACKAGE_PIN G14 IOSTANDARD LVCMOS33} [get_ports {gpio_status[5]}] + +# ============================================================================= +# GPIO Control [3:0] - Mixed Banks +# ============================================================================= + +set_property -dict {PACKAGE_PIN T10 IOSTANDARD LVCMOS25} [get_ports {gpio_ctl[0]}] +set_property -dict {PACKAGE_PIN Y11 IOSTANDARD LVCMOS33} [get_ports {gpio_ctl[1]}] +set_property -dict {PACKAGE_PIN V10 IOSTANDARD LVCMOS33} [get_ports {gpio_ctl[2]}] +set_property -dict {PACKAGE_PIN U9 IOSTANDARD LVCMOS33} [get_ports {gpio_ctl[3]}] + +# ============================================================================= +# I2C Interface - Bank 35 (3.3V) +# ============================================================================= + +set_property -dict {PACKAGE_PIN M15 IOSTANDARD LVCMOS33 PULLUP true} [get_ports iic_scl] +set_property -dict {PACKAGE_PIN K16 IOSTANDARD LVCMOS33 PULLUP true} [get_ports iic_sda] + +# ============================================================================= +# SPI Interface (AD9363) - Bank 34 (2.5V) +# ============================================================================= + +set_property -dict {PACKAGE_PIN P18 IOSTANDARD LVCMOS25} [get_ports spi_csn] +set_property -dict {PACKAGE_PIN R14 IOSTANDARD LVCMOS25} [get_ports spi_clk] +set_property -dict {PACKAGE_PIN P15 IOSTANDARD LVCMOS25} [get_ports spi_mosi] +set_property -dict {PACKAGE_PIN R19 IOSTANDARD LVCMOS25} [get_ports spi_miso] + +# ============================================================================= +# PL SPI Interface - Bank 35 (3.3V) +# ============================================================================= + +set_property -dict {PACKAGE_PIN K14 IOSTANDARD LVCMOS33} [get_ports pl_spi_clk_o] +set_property -dict {PACKAGE_PIN J14 IOSTANDARD LVCMOS33} [get_ports pl_spi_miso] +set_property -dict {PACKAGE_PIN N15 IOSTANDARD LVCMOS33} [get_ports pl_spi_mosi] + +# ============================================================================= +# Timing Exceptions +# ============================================================================= + +# False paths for GPIO outputs from axi_ad9361 +set_false_path -from [get_pins i_system_wrapper/system_i/axi_ad9361/inst/i_tdd/i_tdd_control/tdd_enable_reg/C] +set_false_path -from [get_pins i_system_wrapper/system_i/axi_ad9361/inst/i_tdd/i_tdd_control/tdd_tx_only_reg/C] +set_false_path -from [get_pins i_system_wrapper/system_i/axi_ad9361/inst/i_tdd/i_tdd_control/tdd_rx_only_reg/C] +set_false_path -from [get_pins i_system_wrapper/system_i/axi_ad9361/inst/i_tdd/i_tdd_control/tdd_gated_tx_dmapath_reg/C] +set_false_path -from [get_pins i_system_wrapper/system_i/axi_ad9361/inst/i_tdd/i_tdd_control/tdd_gated_rx_dmapath_reg/C] + +# Asynchronous clock domain crossing - CDC handled in RTL +set_clock_groups -asynchronous -group [get_clocks {clk_fpga_0 clk_fpga_1 spi0_clk}] -group [get_clocks {rx_clk}] +set_property -dict {PACKAGE_PIN T14 IOSTANDARD LVCMOS25} [get_ports {gpio_status[1]}] +set_property -dict {PACKAGE_PIN T15 IOSTANDARD LVCMOS25} [get_ports {gpio_status[2]}] +set_property -dict {PACKAGE_PIN U13 IOSTANDARD LVCMOS25} [get_ports {gpio_status[6]}] +set_property -dict {PACKAGE_PIN V13 IOSTANDARD LVCMOS25} [get_ports {gpio_status[7]}] + +# ============================================================================= +# Generated Clocks for MSK Modem +# ============================================================================= + +# l_clk is generated by AD9361 IP (4x rx_clk in LVDS mode = 245.76 MHz) +create_generated_clock -name l_clk \ + -source [get_ports rx_clk_in_p] \ + -multiply_by 4 \ + [get_pins i_system_wrapper/system_i/axi_ad9361/inst/l_clk] + +# clk_div4 is our divide-by-4 of l_clk (61.44 MHz for msk_top) +create_generated_clock -name clk_div4 \ + -source [get_pins i_system_wrapper/system_i/clk_divider/inst/clk_div_ff_reg/C] \ + -divide_by 4 \ + [get_pins i_system_wrapper/system_i/clk_divider/inst/U_BUFG/O] + +# CDC paths between l_clk and clk_div4 domains (handled by sync registers) +set_false_path -from [get_clocks clk_div4] -to [get_clocks l_clk] +set_false_path -from [get_clocks l_clk] -to [get_clocks clk_div4] + +# Add clk_div4 to async group with PS clocks +set_clock_groups -asynchronous -group [get_clocks {clk_fpga_0 clk_fpga_1 spi0_clk}] -group [get_clocks {clk_div4}] + +# l_clk is async to PS clocks (CDC handled in RTL) +set_clock_groups -asynchronous -group [get_clocks {clk_fpga_0 clk_fpga_1 spi0_clk}] -group [get_clocks {l_clk}] diff --git a/projects/libre/system_project.tcl b/projects/libre/system_project.tcl new file mode 100644 index 0000000..52f36fa --- /dev/null +++ b/projects/libre/system_project.tcl @@ -0,0 +1,16 @@ +source ../../hdl/scripts/adi_env.tcl +source $ad_hdl_dir/projects/scripts/adi_project_xilinx.tcl +source $ad_hdl_dir/projects/scripts/adi_board.tcl + +adi_project_create libre 0 {} "xc7z020clg400-2" + +adi_project_files libre [list \ + "system_top.v" \ + "system_constr.xdc" \ + "$ad_hdl_dir/library/common/ad_iobuf.v"] + +set_property is_enabled false [get_files *system_sys_ps7_0.xdc] + +set_property strategy Performance_Explore [get_runs impl_1] +adi_project_run libre +source $ad_hdl_dir/library/axi_ad9361/axi_ad9361_delay.tcl diff --git a/projects/libre/system_top.v b/projects/libre/system_top.v new file mode 100644 index 0000000..63c4413 --- /dev/null +++ b/projects/libre/system_top.v @@ -0,0 +1,183 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// In this HDL repository, there are many different and unique modules, consisting +// of various HDL (Verilog or VHDL) components. The individual modules are +// developed independently, and may be accompanied by separate and unique license +// terms. +// +// The user should read each of these license terms, and understand the +// freedoms and responsibilities that he or she has by using this source/core. +// +// This core is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +// A PARTICULAR PURPOSE. +// +// Redistribution and use of source or resulting binaries, with or without modification +// of this file, are permitted under one of the following two license terms: +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory +// of this repository (LICENSE_GPL2), and also online at: +// +// +// OR +// +// 2. An ADI specific BSD license, which can be found in the top level directory +// of this repository (LICENSE_ADIBSD), and also on-line at: +// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD +// This will allow to generate bit files and not release the source code, +// as long as it attaches to an ADI device. +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module system_top ( + + inout [14:0] ddr_addr, + inout [ 2:0] ddr_ba, + inout ddr_cas_n, + inout ddr_ck_n, + inout ddr_ck_p, + inout ddr_cke, + inout ddr_cs_n, + inout [ 3:0] ddr_dm, + inout [31:0] ddr_dq, + inout [ 3:0] ddr_dqs_n, + inout [ 3:0] ddr_dqs_p, + inout ddr_odt, + inout ddr_ras_n, + inout ddr_reset_n, + inout ddr_we_n, + + inout fixed_io_ddr_vrn, + inout fixed_io_ddr_vrp, + inout [53:0] fixed_io_mio, + inout fixed_io_ps_clk, + inout fixed_io_ps_porb, + inout fixed_io_ps_srstb, + + inout iic_scl, + inout iic_sda, + + input rx_clk_in_p, + input rx_clk_in_n, + input rx_frame_in_p, + input rx_frame_in_n, + input [ 5:0] rx_data_in_p, + input [ 5:0] rx_data_in_n, + output tx_clk_out_p, + output tx_clk_out_n, + output tx_frame_out_p, + output tx_frame_out_n, + output [ 5:0] tx_data_out_p, + output [ 5:0] tx_data_out_n, + + output enable, + output txnrx, + + inout gpio_resetb, + inout gpio_en_agc, + inout [ 3:0] gpio_ctl, + inout [ 7:0] gpio_status, + + output spi_csn, + output spi_clk, + output spi_mosi, + input spi_miso, + + output pl_spi_clk_o, + output pl_spi_mosi, + input pl_spi_miso + + ); + + // internal signals + + wire [24:0] gpio_i; + wire [24:0] gpio_o; + wire [24:0] gpio_t; + + // instantiations + + ad_iobuf #(.DATA_WIDTH(14)) i_iobuf ( + .dio_t (gpio_t[13:0]), + .dio_i (gpio_o[13:0]), + .dio_o (gpio_i[13:0]), + .dio_p ({ gpio_resetb, // 13:13 + gpio_en_agc, // 12:12 + gpio_ctl, // 11: 8 + gpio_status})); // 7: 0 + + assign gpio_i[16:14] = gpio_o[16:14]; + + system_wrapper i_system_wrapper ( + .ddr_addr (ddr_addr), + .ddr_ba (ddr_ba), + .ddr_cas_n (ddr_cas_n), + .ddr_ck_n (ddr_ck_n), + .ddr_ck_p (ddr_ck_p), + .ddr_cke (ddr_cke), + .ddr_cs_n (ddr_cs_n), + .ddr_dm (ddr_dm), + .ddr_dq (ddr_dq), + .ddr_dqs_n (ddr_dqs_n), + .ddr_dqs_p (ddr_dqs_p), + .ddr_odt (ddr_odt), + .ddr_ras_n (ddr_ras_n), + .ddr_reset_n (ddr_reset_n), + .ddr_we_n (ddr_we_n), + .enable (enable), + .fixed_io_ddr_vrn (fixed_io_ddr_vrn), + .fixed_io_ddr_vrp (fixed_io_ddr_vrp), + .fixed_io_mio (fixed_io_mio), + .fixed_io_ps_clk (fixed_io_ps_clk), + .fixed_io_ps_porb (fixed_io_ps_porb), + .fixed_io_ps_srstb (fixed_io_ps_srstb), + .gpio_i (gpio_i), + .gpio_o (gpio_o), + .gpio_t (gpio_t), + .iic_main_scl_io (iic_scl), + .iic_main_sda_io (iic_sda), + .rx_clk_in_p (rx_clk_in_p), + .rx_clk_in_n (rx_clk_in_n), + .rx_data_in_p (rx_data_in_p), + .rx_data_in_n (rx_data_in_n), + .rx_frame_in_p (rx_frame_in_p), + .rx_frame_in_n (rx_frame_in_n), + + .spi0_clk_i (1'b0), + .spi0_clk_o (spi_clk), + .spi0_csn_0_o (spi_csn), + .spi0_csn_1_o (), + .spi0_csn_2_o (), + .spi0_csn_i (1'b1), + .spi0_sdi_i (spi_miso), + .spi0_sdo_i (1'b0), + .spi0_sdo_o (spi_mosi), + + .spi_clk_i(1'b0), + .spi_clk_o(pl_spi_clk_o), + .spi_csn_i(1'b1), + .spi_csn_o(), + .spi_sdi_i(pl_spi_miso), + .spi_sdo_i(1'b0), + .spi_sdo_o(pl_spi_mosi), + + .tx_clk_out_p (tx_clk_out_p), + .tx_clk_out_n (tx_clk_out_n), + .tx_data_out_p (tx_data_out_p), + .tx_data_out_n (tx_data_out_n), + .tx_frame_out_p (tx_frame_out_p), + .tx_frame_out_n (tx_frame_out_n), + .txnrx (txnrx), + .up_enable (gpio_o[15]), + .up_txnrx (gpio_o[16])); + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/projects/pluto/hier_util.txt b/projects/pluto/hier_util.txt new file mode 100644 index 0000000..44c5eea --- /dev/null +++ b/projects/pluto/hier_util.txt @@ -0,0 +1,538 @@ +Copyright 1986-2022 Xilinx, Inc. All Rights Reserved. +------------------------------------------------------------------------------------ +| Tool Version : Vivado v.2022.2 (lin64) Build 3671981 Fri Oct 14 04:59:54 MDT 2022 +| Date : Mon Dec 1 00:30:12 2025 +| Host : mymelody running 64-bit Ubuntu 22.04.5 LTS +| Command : report_utilization -hierarchical -file hier_util.txt +| Design : system_top +| Device : xc7z010clg225-1 +| Speed File : -1 +| Design State : Routed +------------------------------------------------------------------------------------ + +Utilization Design Information + +Table of Contents +----------------- +1. Utilization by Hierarchy + +1. Utilization by Hierarchy +--------------------------- + ++----------------------------------------------------------------------------------+---------------------------------------------------------------------------------+------------+------------+---------+------+-------+--------+--------+------------+ +| Instance | Module | Total LUTs | Logic LUTs | LUTRAMs | SRLs | FFs | RAMB36 | RAMB18 | DSP Blocks | ++----------------------------------------------------------------------------------+---------------------------------------------------------------------------------+------------+------------+---------+------+-------+--------+--------+------------+ +| system_top | (top) | 14131 | 13509 | 550 | 72 | 20623 | 2 | 4 | 20 | +| (system_top) | (top) | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| i_system_wrapper | system_wrapper | 14131 | 13509 | 550 | 72 | 20623 | 2 | 4 | 20 | +| (i_system_wrapper) | system_wrapper | 2 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | +| system_i | system | 14130 | 13508 | 550 | 72 | 20623 | 2 | 4 | 20 | +| (system_i) | system | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| axi_ad9361 | system_axi_ad9361_0 | 1974 | 1974 | 0 | 0 | 3196 | 0 | 0 | 0 | +| inst | system_axi_ad9361_0_axi_ad9361 | 1974 | 1974 | 0 | 0 | 3196 | 0 | 0 | 0 | +| (inst) | system_axi_ad9361_0_axi_ad9361 | 0 | 0 | 0 | 0 | 59 | 0 | 0 | 0 | +| i_dev_if | system_axi_ad9361_0_axi_ad9361_cmos_if | 129 | 129 | 0 | 0 | 181 | 0 | 0 | 0 | +| (i_dev_if) | system_axi_ad9361_0_axi_ad9361_cmos_if | 67 | 67 | 0 | 0 | 181 | 0 | 0 | 0 | +| g_rx_data[0].i_rx_data | system_axi_ad9361_0_ad_data_in | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| g_rx_data[10].i_rx_data | system_axi_ad9361_0_ad_data_in_41 | 8 | 8 | 0 | 0 | 0 | 0 | 0 | 0 | +| g_rx_data[11].i_rx_data | system_axi_ad9361_0_ad_data_in_42 | 12 | 12 | 0 | 0 | 0 | 0 | 0 | 0 | +| g_rx_data[1].i_rx_data | system_axi_ad9361_0_ad_data_in_43 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| g_rx_data[2].i_rx_data | system_axi_ad9361_0_ad_data_in_44 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| g_rx_data[3].i_rx_data | system_axi_ad9361_0_ad_data_in_45 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| g_rx_data[4].i_rx_data | system_axi_ad9361_0_ad_data_in_46 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| g_rx_data[5].i_rx_data | system_axi_ad9361_0_ad_data_in_47 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| g_rx_data[6].i_rx_data | system_axi_ad9361_0_ad_data_in_48 | 7 | 7 | 0 | 0 | 0 | 0 | 0 | 0 | +| g_rx_data[7].i_rx_data | system_axi_ad9361_0_ad_data_in_49 | 13 | 13 | 0 | 0 | 0 | 0 | 0 | 0 | +| g_rx_data[8].i_rx_data | system_axi_ad9361_0_ad_data_in_50 | 5 | 5 | 0 | 0 | 0 | 0 | 0 | 0 | +| g_rx_data[9].i_rx_data | system_axi_ad9361_0_ad_data_in_51 | 8 | 8 | 0 | 0 | 0 | 0 | 0 | 0 | +| g_tx_data[0].i_tx_data | system_axi_ad9361_0_ad_data_out | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| g_tx_data[10].i_tx_data | system_axi_ad9361_0_ad_data_out_52 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| g_tx_data[11].i_tx_data | system_axi_ad9361_0_ad_data_out_53 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| g_tx_data[1].i_tx_data | system_axi_ad9361_0_ad_data_out_54 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| g_tx_data[2].i_tx_data | system_axi_ad9361_0_ad_data_out_55 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| g_tx_data[3].i_tx_data | system_axi_ad9361_0_ad_data_out_56 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| g_tx_data[4].i_tx_data | system_axi_ad9361_0_ad_data_out_57 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| g_tx_data[5].i_tx_data | system_axi_ad9361_0_ad_data_out_58 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| g_tx_data[6].i_tx_data | system_axi_ad9361_0_ad_data_out_59 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| g_tx_data[7].i_tx_data | system_axi_ad9361_0_ad_data_out_60 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| g_tx_data[8].i_tx_data | system_axi_ad9361_0_ad_data_out_61 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| g_tx_data[9].i_tx_data | system_axi_ad9361_0_ad_data_out_62 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| i_clk | system_axi_ad9361_0_ad_data_clk | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| i_enable | system_axi_ad9361_0_ad_data_out_63 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| i_rx_frame | system_axi_ad9361_0_ad_data_in__parameterized0 | 10 | 10 | 0 | 0 | 0 | 0 | 0 | 0 | +| i_tx_clk | system_axi_ad9361_0_ad_data_out_64 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| i_tx_frame | system_axi_ad9361_0_ad_data_out_65 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| i_txnrx | system_axi_ad9361_0_ad_data_out_66 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| i_rx | system_axi_ad9361_0_axi_ad9361_rx | 699 | 699 | 0 | 0 | 1518 | 0 | 0 | 0 | +| (i_rx) | system_axi_ad9361_0_axi_ad9361_rx | 60 | 60 | 0 | 0 | 36 | 0 | 0 | 0 | +| i_delay_cntrl | system_axi_ad9361_0_up_delay_cntrl | 6 | 6 | 0 | 0 | 96 | 0 | 0 | 0 | +| (i_delay_cntrl) | system_axi_ad9361_0_up_delay_cntrl | 6 | 6 | 0 | 0 | 91 | 0 | 0 | 0 | +| i_delay_rst_reg | system_axi_ad9361_0_ad_rst__xdcDup__1 | 0 | 0 | 0 | 0 | 5 | 0 | 0 | 0 | +| i_rx_channel_0 | system_axi_ad9361_0_axi_ad9361_rx_channel | 148 | 148 | 0 | 0 | 252 | 0 | 0 | 0 | +| i_ad_datafmt | system_axi_ad9361_0_ad_datafmt_34 | 0 | 0 | 0 | 0 | 13 | 0 | 0 | 0 | +| i_rx_pnmon | system_axi_ad9361_0_axi_ad9361_rx_pnmon | 61 | 61 | 0 | 0 | 137 | 0 | 0 | 0 | +| (i_rx_pnmon) | system_axi_ad9361_0_axi_ad9361_rx_pnmon | 2 | 2 | 0 | 0 | 128 | 0 | 0 | 0 | +| i_pnmon | system_axi_ad9361_0_ad_pnmon_36 | 59 | 59 | 0 | 0 | 9 | 0 | 0 | 0 | +| i_up_adc_channel | system_axi_ad9361_0_up_adc_channel | 87 | 87 | 0 | 0 | 102 | 0 | 0 | 0 | +| (i_up_adc_channel) | system_axi_ad9361_0_up_adc_channel | 5 | 5 | 0 | 0 | 44 | 0 | 0 | 0 | +| i_xfer_cntrl | system_axi_ad9361_0_up_xfer_cntrl__xdcDup__1 | 71 | 71 | 0 | 0 | 38 | 0 | 0 | 0 | +| i_xfer_status | system_axi_ad9361_0_up_xfer_status__xdcDup__1 | 11 | 11 | 0 | 0 | 20 | 0 | 0 | 0 | +| i_rx_channel_1 | system_axi_ad9361_0_axi_ad9361_rx_channel__parameterized0 | 141 | 141 | 0 | 0 | 277 | 0 | 0 | 0 | +| i_ad_datafmt | system_axi_ad9361_0_ad_datafmt_27 | 0 | 0 | 0 | 0 | 9 | 0 | 0 | 0 | +| i_rx_pnmon | system_axi_ad9361_0_axi_ad9361_rx_pnmon__parameterized0 | 59 | 59 | 0 | 0 | 168 | 0 | 0 | 0 | +| (i_rx_pnmon) | system_axi_ad9361_0_axi_ad9361_rx_pnmon__parameterized0 | 2 | 2 | 0 | 0 | 159 | 0 | 0 | 0 | +| i_pnmon | system_axi_ad9361_0_ad_pnmon_29 | 57 | 57 | 0 | 0 | 9 | 0 | 0 | 0 | +| i_up_adc_channel | system_axi_ad9361_0_up_adc_channel__parameterized0 | 82 | 82 | 0 | 0 | 100 | 0 | 0 | 0 | +| (i_up_adc_channel) | system_axi_ad9361_0_up_adc_channel__parameterized0 | 5 | 5 | 0 | 0 | 44 | 0 | 0 | 0 | +| i_xfer_cntrl | system_axi_ad9361_0_up_xfer_cntrl__xdcDup__2 | 66 | 66 | 0 | 0 | 36 | 0 | 0 | 0 | +| i_xfer_status | system_axi_ad9361_0_up_xfer_status__xdcDup__2 | 11 | 11 | 0 | 0 | 20 | 0 | 0 | 0 | +| i_rx_channel_2 | system_axi_ad9361_0_axi_ad9361_rx_channel__parameterized1 | 129 | 129 | 0 | 0 | 250 | 0 | 0 | 0 | +| i_rx_pnmon | system_axi_ad9361_0_axi_ad9361_rx_pnmon__parameterized1 | 59 | 59 | 0 | 0 | 168 | 0 | 0 | 0 | +| (i_rx_pnmon) | system_axi_ad9361_0_axi_ad9361_rx_pnmon__parameterized1 | 2 | 2 | 0 | 0 | 159 | 0 | 0 | 0 | +| i_pnmon | system_axi_ad9361_0_ad_pnmon_22 | 57 | 57 | 0 | 0 | 9 | 0 | 0 | 0 | +| i_up_adc_channel | system_axi_ad9361_0_up_adc_channel__parameterized1 | 70 | 70 | 0 | 0 | 82 | 0 | 0 | 0 | +| (i_up_adc_channel) | system_axi_ad9361_0_up_adc_channel__parameterized1 | 3 | 3 | 0 | 0 | 40 | 0 | 0 | 0 | +| i_xfer_cntrl | system_axi_ad9361_0_up_xfer_cntrl__xdcDup__3 | 56 | 56 | 0 | 0 | 22 | 0 | 0 | 0 | +| i_xfer_status | system_axi_ad9361_0_up_xfer_status__xdcDup__3 | 11 | 11 | 0 | 0 | 20 | 0 | 0 | 0 | +| i_rx_channel_3 | system_axi_ad9361_0_axi_ad9361_rx_channel__parameterized2 | 138 | 138 | 0 | 0 | 218 | 0 | 0 | 0 | +| i_rx_pnmon | system_axi_ad9361_0_axi_ad9361_rx_pnmon__parameterized2 | 66 | 66 | 0 | 0 | 136 | 0 | 0 | 0 | +| (i_rx_pnmon) | system_axi_ad9361_0_axi_ad9361_rx_pnmon__parameterized2 | 2 | 2 | 0 | 0 | 127 | 0 | 0 | 0 | +| i_pnmon | system_axi_ad9361_0_ad_pnmon | 64 | 64 | 0 | 0 | 9 | 0 | 0 | 0 | +| i_up_adc_channel | system_axi_ad9361_0_up_adc_channel__parameterized2 | 72 | 72 | 0 | 0 | 82 | 0 | 0 | 0 | +| (i_up_adc_channel) | system_axi_ad9361_0_up_adc_channel__parameterized2 | 4 | 4 | 0 | 0 | 40 | 0 | 0 | 0 | +| i_xfer_cntrl | system_axi_ad9361_0_up_xfer_cntrl | 57 | 57 | 0 | 0 | 22 | 0 | 0 | 0 | +| i_xfer_status | system_axi_ad9361_0_up_xfer_status | 11 | 11 | 0 | 0 | 20 | 0 | 0 | 0 | +| i_up_adc_common | system_axi_ad9361_0_up_adc_common | 78 | 78 | 0 | 0 | 389 | 0 | 0 | 0 | +| (i_up_adc_common) | system_axi_ad9361_0_up_adc_common | 17 | 17 | 0 | 0 | 257 | 0 | 0 | 0 | +| i_clock_mon | system_axi_ad9361_0_up_clock_mon__xdcDup__1 | 41 | 41 | 0 | 0 | 88 | 0 | 0 | 0 | +| i_core_rst_reg | system_axi_ad9361_0_ad_rst__xdcDup__2 | 0 | 0 | 0 | 0 | 5 | 0 | 0 | 0 | +| i_xfer_cntrl | system_axi_ad9361_0_up_xfer_cntrl__parameterized0 | 9 | 9 | 0 | 0 | 19 | 0 | 0 | 0 | +| i_xfer_status | system_axi_ad9361_0_up_xfer_status__parameterized0 | 11 | 11 | 0 | 0 | 20 | 0 | 0 | 0 | +| i_tx | system_axi_ad9361_0_axi_ad9361_tx | 388 | 388 | 0 | 0 | 1285 | 0 | 0 | 0 | +| (i_tx) | system_axi_ad9361_0_axi_ad9361_tx | 53 | 53 | 0 | 0 | 54 | 0 | 0 | 0 | +| i_tx_channel_0 | system_axi_ad9361_0_axi_ad9361_tx_channel | 65 | 65 | 0 | 0 | 222 | 0 | 0 | 0 | +| (i_tx_channel_0) | system_axi_ad9361_0_axi_ad9361_tx_channel | 22 | 22 | 0 | 0 | 74 | 0 | 0 | 0 | +| i_up_dac_channel | system_axi_ad9361_0_up_dac_channel | 43 | 43 | 0 | 0 | 148 | 0 | 0 | 0 | +| (i_up_dac_channel) | system_axi_ad9361_0_up_dac_channel | 3 | 3 | 0 | 0 | 78 | 0 | 0 | 0 | +| i_xfer_cntrl | system_axi_ad9361_0_up_xfer_cntrl__parameterized1__xdcDup__1 | 40 | 40 | 0 | 0 | 70 | 0 | 0 | 0 | +| i_tx_channel_1 | system_axi_ad9361_0_axi_ad9361_tx_channel__parameterized0 | 64 | 64 | 0 | 0 | 221 | 0 | 0 | 0 | +| (i_tx_channel_1) | system_axi_ad9361_0_axi_ad9361_tx_channel__parameterized0 | 21 | 21 | 0 | 0 | 73 | 0 | 0 | 0 | +| i_up_dac_channel | system_axi_ad9361_0_up_dac_channel__parameterized0 | 43 | 43 | 0 | 0 | 148 | 0 | 0 | 0 | +| (i_up_dac_channel) | system_axi_ad9361_0_up_dac_channel__parameterized0 | 3 | 3 | 0 | 0 | 78 | 0 | 0 | 0 | +| i_xfer_cntrl | system_axi_ad9361_0_up_xfer_cntrl__parameterized1__xdcDup__2 | 40 | 40 | 0 | 0 | 70 | 0 | 0 | 0 | +| i_tx_channel_2 | system_axi_ad9361_0_axi_ad9361_tx_channel__parameterized1 | 63 | 63 | 0 | 0 | 221 | 0 | 0 | 0 | +| (i_tx_channel_2) | system_axi_ad9361_0_axi_ad9361_tx_channel__parameterized1 | 21 | 21 | 0 | 0 | 73 | 0 | 0 | 0 | +| i_up_dac_channel | system_axi_ad9361_0_up_dac_channel__parameterized1 | 42 | 42 | 0 | 0 | 148 | 0 | 0 | 0 | +| (i_up_dac_channel) | system_axi_ad9361_0_up_dac_channel__parameterized1 | 3 | 3 | 0 | 0 | 78 | 0 | 0 | 0 | +| i_xfer_cntrl | system_axi_ad9361_0_up_xfer_cntrl__parameterized1__xdcDup__3 | 39 | 39 | 0 | 0 | 70 | 0 | 0 | 0 | +| i_tx_channel_3 | system_axi_ad9361_0_axi_ad9361_tx_channel__parameterized2 | 65 | 65 | 0 | 0 | 221 | 0 | 0 | 0 | +| (i_tx_channel_3) | system_axi_ad9361_0_axi_ad9361_tx_channel__parameterized2 | 23 | 23 | 0 | 0 | 73 | 0 | 0 | 0 | +| i_up_dac_channel | system_axi_ad9361_0_up_dac_channel__parameterized2 | 42 | 42 | 0 | 0 | 148 | 0 | 0 | 0 | +| (i_up_dac_channel) | system_axi_ad9361_0_up_dac_channel__parameterized2 | 3 | 3 | 0 | 0 | 78 | 0 | 0 | 0 | +| i_xfer_cntrl | system_axi_ad9361_0_up_xfer_cntrl__parameterized1 | 39 | 39 | 0 | 0 | 70 | 0 | 0 | 0 | +| i_up_dac_common | system_axi_ad9361_0_up_dac_common | 96 | 96 | 0 | 0 | 346 | 0 | 0 | 0 | +| (i_up_dac_common) | system_axi_ad9361_0_up_dac_common | 16 | 16 | 0 | 0 | 178 | 0 | 0 | 0 | +| i_clock_mon | system_axi_ad9361_0_up_clock_mon | 42 | 42 | 0 | 0 | 88 | 0 | 0 | 0 | +| i_core_rst_reg | system_axi_ad9361_0_ad_rst__xdcDup__4 | 0 | 0 | 0 | 0 | 5 | 0 | 0 | 0 | +| i_xfer_cntrl | system_axi_ad9361_0_up_xfer_cntrl__parameterized2 | 29 | 29 | 0 | 0 | 55 | 0 | 0 | 0 | +| i_xfer_status | system_axi_ad9361_0_up_xfer_status__parameterized1 | 10 | 10 | 0 | 0 | 20 | 0 | 0 | 0 | +| i_up_axi | system_axi_ad9361_0_up_axi | 760 | 760 | 0 | 0 | 153 | 0 | 0 | 0 | +| axi_ad9361_adc_dma | system_axi_ad9361_adc_dma_0 | 487 | 453 | 34 | 0 | 727 | 1 | 0 | 0 | +| (axi_ad9361_adc_dma) | system_axi_ad9361_adc_dma_0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| inst | system_axi_ad9361_adc_dma_0_axi_dmac | 487 | 453 | 34 | 0 | 727 | 1 | 0 | 0 | +| i_regmap | system_axi_ad9361_adc_dma_0_axi_dmac_regmap | 276 | 258 | 18 | 0 | 330 | 0 | 0 | 0 | +| (i_regmap) | system_axi_ad9361_adc_dma_0_axi_dmac_regmap | 2 | 2 | 0 | 0 | 73 | 0 | 0 | 0 | +| i_regmap_request | system_axi_ad9361_adc_dma_0_axi_dmac_regmap_request | 63 | 45 | 18 | 0 | 122 | 0 | 0 | 0 | +| (i_regmap_request) | system_axi_ad9361_adc_dma_0_axi_dmac_regmap_request | 33 | 33 | 0 | 0 | 89 | 0 | 0 | 0 | +| i_transfer_lenghts_fifo | system_axi_ad9361_adc_dma_0_util_axis_fifo | 30 | 12 | 18 | 0 | 33 | 0 | 0 | 0 | +| (i_transfer_lenghts_fifo) | system_axi_ad9361_adc_dma_0_util_axis_fifo | 20 | 2 | 18 | 0 | 27 | 0 | 0 | 0 | +| fifo.i_address_gray | system_axi_ad9361_adc_dma_0_util_axis_fifo_address_generator | 10 | 10 | 0 | 0 | 6 | 0 | 0 | 0 | +| i_up_axi | system_axi_ad9361_adc_dma_0_up_axi | 212 | 212 | 0 | 0 | 135 | 0 | 0 | 0 | +| i_transfer | system_axi_ad9361_adc_dma_0_axi_dmac_transfer | 211 | 195 | 16 | 0 | 397 | 1 | 0 | 0 | +| i_request_arb | system_axi_ad9361_adc_dma_0_request_arb | 201 | 185 | 16 | 0 | 360 | 1 | 0 | 0 | +| (i_request_arb) | system_axi_ad9361_adc_dma_0_request_arb | 6 | 0 | 6 | 0 | 32 | 0 | 0 | 0 | +| i_dest_dma_mm | system_axi_ad9361_adc_dma_0_dest_axi_mm | 43 | 37 | 6 | 0 | 49 | 0 | 0 | 0 | +| (i_dest_dma_mm) | system_axi_ad9361_adc_dma_0_dest_axi_mm | 6 | 0 | 6 | 0 | 0 | 0 | 0 | 0 | +| i_addr_gen | system_axi_ad9361_adc_dma_0_address_generator | 32 | 32 | 0 | 0 | 44 | 0 | 0 | 0 | +| i_response_handler | system_axi_ad9361_adc_dma_0_response_handler | 5 | 5 | 0 | 0 | 5 | 0 | 0 | 0 | +| i_dest_req_fifo | system_axi_ad9361_adc_dma_0_util_axis_fifo__parameterized2 | 3 | 3 | 0 | 0 | 32 | 0 | 0 | 0 | +| (i_dest_req_fifo) | system_axi_ad9361_adc_dma_0_util_axis_fifo__parameterized2 | 0 | 0 | 0 | 0 | 28 | 0 | 0 | 0 | +| zerodeep.i_raddr_sync | system_axi_ad9361_adc_dma_0_sync_bits__parameterized0__xdcDup__1 | 2 | 2 | 0 | 0 | 2 | 0 | 0 | 0 | +| zerodeep.i_waddr_sync | system_axi_ad9361_adc_dma_0_sync_bits__parameterized0__xdcDup__2 | 1 | 1 | 0 | 0 | 2 | 0 | 0 | 0 | +| i_req_gen | system_axi_ad9361_adc_dma_0_request_generator | 57 | 57 | 0 | 0 | 52 | 0 | 0 | 0 | +| i_response_manager | system_axi_ad9361_adc_dma_0_axi_dmac_response_manager | 23 | 23 | 0 | 0 | 34 | 0 | 0 | 0 | +| (i_response_manager) | system_axi_ad9361_adc_dma_0_axi_dmac_response_manager | 14 | 14 | 0 | 0 | 25 | 0 | 0 | 0 | +| i_dest_response_fifo | system_axi_ad9361_adc_dma_0_util_axis_fifo__parameterized4 | 9 | 9 | 0 | 0 | 9 | 0 | 0 | 0 | +| i_rewind_req_fifo | system_axi_ad9361_adc_dma_0_util_axis_fifo__parameterized1 | 3 | 3 | 0 | 0 | 13 | 0 | 0 | 0 | +| (i_rewind_req_fifo) | system_axi_ad9361_adc_dma_0_util_axis_fifo__parameterized1 | 0 | 0 | 0 | 0 | 9 | 0 | 0 | 0 | +| zerodeep.i_raddr_sync | system_axi_ad9361_adc_dma_0_sync_bits__parameterized0__xdcDup__3 | 2 | 2 | 0 | 0 | 2 | 0 | 0 | 0 | +| zerodeep.i_waddr_sync | system_axi_ad9361_adc_dma_0_sync_bits__parameterized0__xdcDup__4 | 1 | 1 | 0 | 0 | 2 | 0 | 0 | 0 | +| i_src_dest_bl_fifo | system_axi_ad9361_adc_dma_0_util_axis_fifo__parameterized0 | 3 | 3 | 0 | 0 | 10 | 0 | 0 | 0 | +| (i_src_dest_bl_fifo) | system_axi_ad9361_adc_dma_0_util_axis_fifo__parameterized0 | 0 | 0 | 0 | 0 | 6 | 0 | 0 | 0 | +| zerodeep.i_raddr_sync | system_axi_ad9361_adc_dma_0_sync_bits__parameterized0__xdcDup__5 | 1 | 1 | 0 | 0 | 2 | 0 | 0 | 0 | +| zerodeep.i_waddr_sync | system_axi_ad9361_adc_dma_0_sync_bits__parameterized0__xdcDup__6 | 2 | 2 | 0 | 0 | 2 | 0 | 0 | 0 | +| i_src_dma_stream | system_axi_ad9361_adc_dma_0_src_axi_stream | 28 | 28 | 0 | 0 | 32 | 0 | 0 | 0 | +| i_data_mover | system_axi_ad9361_adc_dma_0_data_mover | 28 | 28 | 0 | 0 | 32 | 0 | 0 | 0 | +| i_src_req_fifo | system_axi_ad9361_adc_dma_0_util_axis_fifo__parameterized3 | 2 | 2 | 0 | 0 | 39 | 0 | 0 | 0 | +| (i_src_req_fifo) | system_axi_ad9361_adc_dma_0_util_axis_fifo__parameterized3 | 1 | 1 | 0 | 0 | 35 | 0 | 0 | 0 | +| zerodeep.i_raddr_sync | system_axi_ad9361_adc_dma_0_sync_bits__parameterized0__xdcDup__7 | 1 | 1 | 0 | 0 | 2 | 0 | 0 | 0 | +| zerodeep.i_waddr_sync | system_axi_ad9361_adc_dma_0_sync_bits__parameterized0__xdcDup__8 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| i_store_and_forward | system_axi_ad9361_adc_dma_0_axi_dmac_burst_memory | 28 | 24 | 4 | 0 | 51 | 1 | 0 | 0 | +| (i_store_and_forward) | system_axi_ad9361_adc_dma_0_axi_dmac_burst_memory | 24 | 20 | 4 | 0 | 35 | 0 | 0 | 0 | +| i_dest_sync_id | system_axi_ad9361_adc_dma_0_sync_bits__parameterized2__xdcDup__1 | 2 | 2 | 0 | 0 | 8 | 0 | 0 | 0 | +| i_mem | system_axi_ad9361_adc_dma_0_ad_mem_asym | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | +| i_src_sync_id | system_axi_ad9361_adc_dma_0_sync_bits__parameterized2__xdcDup__2 | 2 | 2 | 0 | 0 | 8 | 0 | 0 | 0 | +| i_sync_src_request_id | system_axi_ad9361_adc_dma_0_sync_bits__parameterized2 | 2 | 2 | 0 | 0 | 8 | 0 | 0 | 0 | +| sync_rewind | system_axi_ad9361_adc_dma_0_sync_event | 3 | 3 | 0 | 0 | 8 | 0 | 0 | 0 | +| (sync_rewind) | system_axi_ad9361_adc_dma_0_sync_event | 1 | 1 | 0 | 0 | 4 | 0 | 0 | 0 | +| i_sync_in | system_axi_ad9361_adc_dma_0_sync_bits__parameterized1__xdcDup__1 | 1 | 1 | 0 | 0 | 2 | 0 | 0 | 0 | +| i_sync_out | system_axi_ad9361_adc_dma_0_sync_bits__parameterized1 | 1 | 1 | 0 | 0 | 2 | 0 | 0 | 0 | +| i_reset_manager | system_axi_ad9361_adc_dma_0_axi_dmac_reset_manager | 10 | 10 | 0 | 0 | 37 | 0 | 0 | 0 | +| (i_reset_manager) | system_axi_ad9361_adc_dma_0_axi_dmac_reset_manager | 7 | 7 | 0 | 0 | 33 | 0 | 0 | 0 | +| i_sync_control_src | system_axi_ad9361_adc_dma_0_sync_bits__parameterized0__xdcDup__9 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| i_sync_status_src | system_axi_ad9361_adc_dma_0_sync_bits__parameterized0 | 3 | 3 | 0 | 0 | 2 | 0 | 0 | 0 | +| axi_ad9361_dac_dma | system_axi_ad9361_dac_dma_0 | 437 | 405 | 32 | 0 | 576 | 1 | 0 | 0 | +| (axi_ad9361_dac_dma) | system_axi_ad9361_dac_dma_0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| inst | system_axi_ad9361_dac_dma_0_axi_dmac | 437 | 405 | 32 | 0 | 576 | 1 | 0 | 0 | +| i_regmap | system_axi_ad9361_dac_dma_0_axi_dmac_regmap | 254 | 236 | 18 | 0 | 331 | 0 | 0 | 0 | +| (i_regmap) | system_axi_ad9361_dac_dma_0_axi_dmac_regmap | 2 | 2 | 0 | 0 | 73 | 0 | 0 | 0 | +| i_regmap_request | system_axi_ad9361_dac_dma_0_axi_dmac_regmap_request | 79 | 61 | 18 | 0 | 123 | 0 | 0 | 0 | +| (i_regmap_request) | system_axi_ad9361_dac_dma_0_axi_dmac_regmap_request | 21 | 21 | 0 | 0 | 90 | 0 | 0 | 0 | +| i_transfer_lenghts_fifo | system_axi_ad9361_dac_dma_0_util_axis_fifo | 58 | 40 | 18 | 0 | 33 | 0 | 0 | 0 | +| (i_transfer_lenghts_fifo) | system_axi_ad9361_dac_dma_0_util_axis_fifo | 48 | 30 | 18 | 0 | 27 | 0 | 0 | 0 | +| fifo.i_address_gray | system_axi_ad9361_dac_dma_0_util_axis_fifo_address_generator | 10 | 10 | 0 | 0 | 6 | 0 | 0 | 0 | +| i_up_axi | system_axi_ad9361_dac_dma_0_up_axi | 175 | 175 | 0 | 0 | 135 | 0 | 0 | 0 | +| i_transfer | system_axi_ad9361_dac_dma_0_axi_dmac_transfer | 186 | 172 | 14 | 0 | 245 | 1 | 0 | 0 | +| i_request_arb | system_axi_ad9361_dac_dma_0_request_arb | 175 | 161 | 14 | 0 | 215 | 1 | 0 | 0 | +| (i_request_arb) | system_axi_ad9361_dac_dma_0_request_arb | 8 | 2 | 6 | 0 | 6 | 0 | 0 | 0 | +| i_dest_dma_stream | system_axi_ad9361_dac_dma_0_dest_axi_stream | 11 | 11 | 0 | 0 | 12 | 0 | 0 | 0 | +| (i_dest_dma_stream) | system_axi_ad9361_dac_dma_0_dest_axi_stream | 4 | 4 | 0 | 0 | 7 | 0 | 0 | 0 | +| i_response_generator | system_axi_ad9361_dac_dma_0_response_generator | 7 | 7 | 0 | 0 | 5 | 0 | 0 | 0 | +| i_dest_req_fifo | system_axi_ad9361_dac_dma_0_util_axis_fifo__parameterized0 | 4 | 4 | 0 | 0 | 7 | 0 | 0 | 0 | +| (i_dest_req_fifo) | system_axi_ad9361_dac_dma_0_util_axis_fifo__parameterized0 | 0 | 0 | 0 | 0 | 3 | 0 | 0 | 0 | +| zerodeep.i_raddr_sync | system_axi_ad9361_dac_dma_0_sync_bits__xdcDup__1 | 2 | 2 | 0 | 0 | 2 | 0 | 0 | 0 | +| zerodeep.i_waddr_sync | system_axi_ad9361_dac_dma_0_sync_bits__xdcDup__2 | 2 | 2 | 0 | 0 | 2 | 0 | 0 | 0 | +| i_req_gen | system_axi_ad9361_dac_dma_0_request_generator | 40 | 40 | 0 | 0 | 23 | 0 | 0 | 0 | +| i_response_manager | system_axi_ad9361_dac_dma_0_axi_dmac_response_manager | 25 | 25 | 0 | 0 | 24 | 0 | 0 | 0 | +| (i_response_manager) | system_axi_ad9361_dac_dma_0_axi_dmac_response_manager | 14 | 14 | 0 | 0 | 17 | 0 | 0 | 0 | +| i_dest_response_fifo | system_axi_ad9361_dac_dma_0_util_axis_fifo__parameterized2 | 11 | 11 | 0 | 0 | 7 | 0 | 0 | 0 | +| (i_dest_response_fifo) | system_axi_ad9361_dac_dma_0_util_axis_fifo__parameterized2 | 1 | 1 | 0 | 0 | 3 | 0 | 0 | 0 | +| zerodeep.i_raddr_sync | system_axi_ad9361_dac_dma_0_sync_bits__xdcDup__3 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| zerodeep.i_waddr_sync | system_axi_ad9361_dac_dma_0_sync_bits__xdcDup__4 | 10 | 10 | 0 | 0 | 2 | 0 | 0 | 0 | +| i_src_dma_mm | system_axi_ad9361_dac_dma_0_src_axi_mm | 55 | 51 | 4 | 0 | 53 | 0 | 0 | 0 | +| (i_src_dma_mm) | system_axi_ad9361_dac_dma_0_src_axi_mm | 13 | 9 | 4 | 0 | 7 | 0 | 0 | 0 | +| i_addr_gen | system_axi_ad9361_dac_dma_0_address_generator | 42 | 42 | 0 | 0 | 44 | 0 | 0 | 0 | +| i_req_splitter | system_axi_ad9361_dac_dma_0_splitter | 1 | 1 | 0 | 0 | 2 | 0 | 0 | 0 | +| i_src_req_fifo | system_axi_ad9361_dac_dma_0_util_axis_fifo__parameterized1 | 0 | 0 | 0 | 0 | 34 | 0 | 0 | 0 | +| i_store_and_forward | system_axi_ad9361_dac_dma_0_axi_dmac_burst_memory | 32 | 28 | 4 | 0 | 48 | 1 | 0 | 0 | +| (i_store_and_forward) | system_axi_ad9361_dac_dma_0_axi_dmac_burst_memory | 25 | 21 | 4 | 0 | 32 | 0 | 0 | 0 | +| i_dest_sync_id | system_axi_ad9361_dac_dma_0_sync_bits__parameterized2__xdcDup__1 | 4 | 4 | 0 | 0 | 8 | 0 | 0 | 0 | +| i_mem | system_axi_ad9361_dac_dma_0_ad_mem_asym | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | +| i_src_sync_id | system_axi_ad9361_dac_dma_0_sync_bits__parameterized2__xdcDup__2 | 3 | 3 | 0 | 0 | 8 | 0 | 0 | 0 | +| i_sync_req_response_id | system_axi_ad9361_dac_dma_0_sync_bits__parameterized2 | 0 | 0 | 0 | 0 | 8 | 0 | 0 | 0 | +| i_reset_manager | system_axi_ad9361_dac_dma_0_axi_dmac_reset_manager | 12 | 12 | 0 | 0 | 30 | 0 | 0 | 0 | +| (i_reset_manager) | system_axi_ad9361_dac_dma_0_axi_dmac_reset_manager | 9 | 9 | 0 | 0 | 26 | 0 | 0 | 0 | +| i_sync_control_dest | system_axi_ad9361_dac_dma_0_sync_bits__xdcDup__5 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| i_sync_status_dest | system_axi_ad9361_dac_dma_0_sync_bits | 3 | 3 | 0 | 0 | 2 | 0 | 0 | 0 | +| axi_cpu_interconnect | system_axi_cpu_interconnect_0 | 654 | 593 | 0 | 61 | 683 | 0 | 0 | 0 | +| s00_couplers | s00_couplers_imp_WZLZH6 | 409 | 348 | 0 | 61 | 550 | 0 | 0 | 0 | +| auto_pc | system_auto_pc_0 | 409 | 348 | 0 | 61 | 550 | 0 | 0 | 0 | +| inst | system_auto_pc_0_axi_protocol_converter_v2_1_27_axi_protocol_converter | 409 | 348 | 0 | 61 | 550 | 0 | 0 | 0 | +| gen_axilite.gen_b2s_conv.axilite_b2s | system_auto_pc_0_axi_protocol_converter_v2_1_27_b2s | 409 | 348 | 0 | 61 | 550 | 0 | 0 | 0 | +| (gen_axilite.gen_b2s_conv.axilite_b2s) | system_auto_pc_0_axi_protocol_converter_v2_1_27_b2s | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | +| RD.ar_channel_0 | system_auto_pc_0_axi_protocol_converter_v2_1_27_b2s_ar_channel | 68 | 68 | 0 | 0 | 82 | 0 | 0 | 0 | +| (RD.ar_channel_0) | system_auto_pc_0_axi_protocol_converter_v2_1_27_b2s_ar_channel | 0 | 0 | 0 | 0 | 12 | 0 | 0 | 0 | +| ar_cmd_fsm_0 | system_auto_pc_0_axi_protocol_converter_v2_1_27_b2s_rd_cmd_fsm | 36 | 36 | 0 | 0 | 2 | 0 | 0 | 0 | +| cmd_translator_0 | system_auto_pc_0_axi_protocol_converter_v2_1_27_b2s_cmd_translator_1 | 32 | 32 | 0 | 0 | 68 | 0 | 0 | 0 | +| (cmd_translator_0) | system_auto_pc_0_axi_protocol_converter_v2_1_27_b2s_cmd_translator_1 | 1 | 1 | 0 | 0 | 3 | 0 | 0 | 0 | +| incr_cmd_0 | system_auto_pc_0_axi_protocol_converter_v2_1_27_b2s_incr_cmd_2 | 21 | 21 | 0 | 0 | 22 | 0 | 0 | 0 | +| wrap_cmd_0 | system_auto_pc_0_axi_protocol_converter_v2_1_27_b2s_wrap_cmd_3 | 10 | 10 | 0 | 0 | 43 | 0 | 0 | 0 | +| RD.r_channel_0 | system_auto_pc_0_axi_protocol_converter_v2_1_27_b2s_r_channel | 61 | 14 | 0 | 47 | 24 | 0 | 0 | 0 | +| (RD.r_channel_0) | system_auto_pc_0_axi_protocol_converter_v2_1_27_b2s_r_channel | 0 | 0 | 0 | 0 | 14 | 0 | 0 | 0 | +| rd_data_fifo_0 | system_auto_pc_0_axi_protocol_converter_v2_1_27_b2s_simple_fifo__parameterized1 | 43 | 9 | 0 | 34 | 5 | 0 | 0 | 0 | +| transaction_fifo_0 | system_auto_pc_0_axi_protocol_converter_v2_1_27_b2s_simple_fifo__parameterized2 | 19 | 6 | 0 | 13 | 5 | 0 | 0 | 0 | +| SI_REG | system_auto_pc_0_axi_register_slice_v2_1_27_axi_register_slice | 173 | 173 | 0 | 0 | 340 | 0 | 0 | 0 | +| ar.ar_pipe | system_auto_pc_0_axi_register_slice_v2_1_27_axic_register_slice | 65 | 65 | 0 | 0 | 107 | 0 | 0 | 0 | +| aw.aw_pipe | system_auto_pc_0_axi_register_slice_v2_1_27_axic_register_slice_0 | 71 | 71 | 0 | 0 | 107 | 0 | 0 | 0 | +| b.b_pipe | system_auto_pc_0_axi_register_slice_v2_1_27_axic_register_slice__parameterized1 | 10 | 10 | 0 | 0 | 30 | 0 | 0 | 0 | +| r.r_pipe | system_auto_pc_0_axi_register_slice_v2_1_27_axic_register_slice__parameterized2 | 27 | 27 | 0 | 0 | 96 | 0 | 0 | 0 | +| WR.aw_channel_0 | system_auto_pc_0_axi_protocol_converter_v2_1_27_b2s_aw_channel | 77 | 77 | 0 | 0 | 86 | 0 | 0 | 0 | +| (WR.aw_channel_0) | system_auto_pc_0_axi_protocol_converter_v2_1_27_b2s_aw_channel | 0 | 0 | 0 | 0 | 16 | 0 | 0 | 0 | +| aw_cmd_fsm_0 | system_auto_pc_0_axi_protocol_converter_v2_1_27_b2s_wr_cmd_fsm | 44 | 44 | 0 | 0 | 2 | 0 | 0 | 0 | +| cmd_translator_0 | system_auto_pc_0_axi_protocol_converter_v2_1_27_b2s_cmd_translator | 33 | 33 | 0 | 0 | 68 | 0 | 0 | 0 | +| (cmd_translator_0) | system_auto_pc_0_axi_protocol_converter_v2_1_27_b2s_cmd_translator | 1 | 1 | 0 | 0 | 3 | 0 | 0 | 0 | +| incr_cmd_0 | system_auto_pc_0_axi_protocol_converter_v2_1_27_b2s_incr_cmd | 22 | 22 | 0 | 0 | 22 | 0 | 0 | 0 | +| wrap_cmd_0 | system_auto_pc_0_axi_protocol_converter_v2_1_27_b2s_wrap_cmd | 10 | 10 | 0 | 0 | 43 | 0 | 0 | 0 | +| WR.b_channel_0 | system_auto_pc_0_axi_protocol_converter_v2_1_27_b2s_b_channel | 35 | 21 | 0 | 14 | 17 | 0 | 0 | 0 | +| (WR.b_channel_0) | system_auto_pc_0_axi_protocol_converter_v2_1_27_b2s_b_channel | 8 | 8 | 0 | 0 | 13 | 0 | 0 | 0 | +| bid_fifo_0 | system_auto_pc_0_axi_protocol_converter_v2_1_27_b2s_simple_fifo | 21 | 9 | 0 | 12 | 2 | 0 | 0 | 0 | +| bresp_fifo_0 | system_auto_pc_0_axi_protocol_converter_v2_1_27_b2s_simple_fifo__parameterized0 | 6 | 4 | 0 | 2 | 2 | 0 | 0 | 0 | +| xbar | system_xbar_0 | 245 | 245 | 0 | 0 | 133 | 0 | 0 | 0 | +| inst | system_xbar_0_axi_crossbar_v2_1_28_axi_crossbar | 245 | 245 | 0 | 0 | 133 | 0 | 0 | 0 | +| gen_sasd.crossbar_sasd_0 | system_xbar_0_axi_crossbar_v2_1_28_crossbar_sasd | 245 | 245 | 0 | 0 | 133 | 0 | 0 | 0 | +| (gen_sasd.crossbar_sasd_0) | system_xbar_0_axi_crossbar_v2_1_28_crossbar_sasd | 7 | 7 | 0 | 0 | 12 | 0 | 0 | 0 | +| addr_arbiter_inst | system_xbar_0_axi_crossbar_v2_1_28_addr_arbiter_sasd | 102 | 102 | 0 | 0 | 38 | 0 | 0 | 0 | +| gen_decerr.decerr_slave_inst | system_xbar_0_axi_crossbar_v2_1_28_decerr_slave | 11 | 11 | 0 | 0 | 4 | 0 | 0 | 0 | +| reg_slice_r | system_xbar_0_axi_register_slice_v2_1_27_axic_register_slice | 114 | 114 | 0 | 0 | 74 | 0 | 0 | 0 | +| splitter_ar | system_xbar_0_axi_crossbar_v2_1_28_splitter__parameterized0 | 2 | 2 | 0 | 0 | 2 | 0 | 0 | 0 | +| splitter_aw | system_xbar_0_axi_crossbar_v2_1_28_splitter | 12 | 12 | 0 | 0 | 3 | 0 | 0 | 0 | +| axi_iic_main | system_axi_iic_main_0 | 381 | 371 | 0 | 10 | 374 | 0 | 0 | 0 | +| (axi_iic_main) | system_axi_iic_main_0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| U0 | system_axi_iic_main_0_axi_iic | 381 | 371 | 0 | 10 | 374 | 0 | 0 | 0 | +| X_IIC | system_axi_iic_main_0_iic | 381 | 371 | 0 | 10 | 374 | 0 | 0 | 0 | +| (X_IIC) | system_axi_iic_main_0_iic | 0 | 0 | 0 | 0 | 4 | 0 | 0 | 0 | +| DYN_MASTER_I | system_axi_iic_main_0_dynamic_master | 15 | 15 | 0 | 0 | 16 | 0 | 0 | 0 | +| FILTER_I | system_axi_iic_main_0_filter | 2 | 2 | 0 | 0 | 8 | 0 | 0 | 0 | +| SCL_DEBOUNCE | system_axi_iic_main_0_debounce | 1 | 1 | 0 | 0 | 4 | 0 | 0 | 0 | +| INPUT_DOUBLE_REGS | system_axi_iic_main_0_cdc_sync_4 | 1 | 1 | 0 | 0 | 4 | 0 | 0 | 0 | +| SDA_DEBOUNCE | system_axi_iic_main_0_debounce_3 | 1 | 1 | 0 | 0 | 4 | 0 | 0 | 0 | +| INPUT_DOUBLE_REGS | system_axi_iic_main_0_cdc_sync | 1 | 1 | 0 | 0 | 4 | 0 | 0 | 0 | +| IIC_CONTROL_I | system_axi_iic_main_0_iic_control | 135 | 135 | 0 | 0 | 115 | 0 | 0 | 0 | +| (IIC_CONTROL_I) | system_axi_iic_main_0_iic_control | 61 | 61 | 0 | 0 | 75 | 0 | 0 | 0 | +| BITCNT | system_axi_iic_main_0_upcnt_n__parameterized0 | 11 | 11 | 0 | 0 | 4 | 0 | 0 | 0 | +| CLKCNT | system_axi_iic_main_0_upcnt_n | 32 | 32 | 0 | 0 | 10 | 0 | 0 | 0 | +| I2CDATA_REG | system_axi_iic_main_0_shift8 | 7 | 7 | 0 | 0 | 8 | 0 | 0 | 0 | +| I2CHEADER_REG | system_axi_iic_main_0_shift8_1 | 16 | 16 | 0 | 0 | 8 | 0 | 0 | 0 | +| SETUP_CNT | system_axi_iic_main_0_upcnt_n_2 | 11 | 11 | 0 | 0 | 10 | 0 | 0 | 0 | +| READ_FIFO_I | system_axi_iic_main_0_SRL_FIFO | 12 | 8 | 0 | 4 | 5 | 0 | 0 | 0 | +| REG_INTERFACE_I | system_axi_iic_main_0_reg_interface | 65 | 65 | 0 | 0 | 124 | 0 | 0 | 0 | +| WRITE_FIFO_CTRL_I | system_axi_iic_main_0_SRL_FIFO__parameterized0 | 9 | 7 | 0 | 2 | 5 | 0 | 0 | 0 | +| WRITE_FIFO_I | system_axi_iic_main_0_SRL_FIFO_0 | 16 | 12 | 0 | 4 | 5 | 0 | 0 | 0 | +| X_AXI_IPIF_SSP1 | system_axi_iic_main_0_axi_ipif_ssp1 | 134 | 134 | 0 | 0 | 92 | 0 | 0 | 0 | +| (X_AXI_IPIF_SSP1) | system_axi_iic_main_0_axi_ipif_ssp1 | 0 | 0 | 0 | 0 | 4 | 0 | 0 | 0 | +| AXI_LITE_IPIF_I | system_axi_iic_main_0_axi_lite_ipif | 117 | 117 | 0 | 0 | 64 | 0 | 0 | 0 | +| I_SLAVE_ATTACHMENT | system_axi_iic_main_0_slave_attachment | 117 | 117 | 0 | 0 | 64 | 0 | 0 | 0 | +| (I_SLAVE_ATTACHMENT) | system_axi_iic_main_0_slave_attachment | 59 | 59 | 0 | 0 | 39 | 0 | 0 | 0 | +| I_DECODER | system_axi_iic_main_0_address_decoder | 59 | 59 | 0 | 0 | 25 | 0 | 0 | 0 | +| X_INTERRUPT_CONTROL | system_axi_iic_main_0_interrupt_control | 13 | 13 | 0 | 0 | 18 | 0 | 0 | 0 | +| X_SOFT_RESET | system_axi_iic_main_0_soft_reset | 4 | 4 | 0 | 0 | 6 | 0 | 0 | 0 | +| axi_spi | system_axi_spi_0 | 359 | 347 | 12 | 0 | 535 | 0 | 0 | 0 | +| U0 | system_axi_spi_0_axi_quad_spi | 359 | 347 | 12 | 0 | 535 | 0 | 0 | 0 | +| NO_DUAL_QUAD_MODE.QSPI_NORMAL | system_axi_spi_0_axi_quad_spi_top | 359 | 347 | 12 | 0 | 535 | 0 | 0 | 0 | +| (NO_DUAL_QUAD_MODE.QSPI_NORMAL) | system_axi_spi_0_axi_quad_spi_top | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | +| QSPI_LEGACY_MD_GEN.AXI_LITE_IPIF_I | system_axi_spi_0_axi_lite_ipif | 95 | 95 | 0 | 0 | 70 | 0 | 0 | 0 | +| I_SLAVE_ATTACHMENT | system_axi_spi_0_slave_attachment | 95 | 95 | 0 | 0 | 70 | 0 | 0 | 0 | +| (I_SLAVE_ATTACHMENT) | system_axi_spi_0_slave_attachment | 23 | 23 | 0 | 0 | 37 | 0 | 0 | 0 | +| I_DECODER | system_axi_spi_0_address_decoder | 72 | 72 | 0 | 0 | 33 | 0 | 0 | 0 | +| (I_DECODER) | system_axi_spi_0_address_decoder | 53 | 53 | 0 | 0 | 33 | 0 | 0 | 0 | +| MEM_DECODE_GEN[0].PER_CE_GEN[0].MULTIPLE_CES_THIS_CS_GEN.CE_I | system_axi_spi_0_axi_lite_ipif_v3_0_4_pselect_f__parameterized0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | +| MEM_DECODE_GEN[0].PER_CE_GEN[10].MULTIPLE_CES_THIS_CS_GEN.CE_I | system_axi_spi_0_axi_lite_ipif_v3_0_4_pselect_f__parameterized10 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | +| MEM_DECODE_GEN[0].PER_CE_GEN[11].MULTIPLE_CES_THIS_CS_GEN.CE_I | system_axi_spi_0_axi_lite_ipif_v3_0_4_pselect_f__parameterized11 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | +| MEM_DECODE_GEN[0].PER_CE_GEN[12].MULTIPLE_CES_THIS_CS_GEN.CE_I | system_axi_spi_0_axi_lite_ipif_v3_0_4_pselect_f__parameterized12 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | +| MEM_DECODE_GEN[0].PER_CE_GEN[13].MULTIPLE_CES_THIS_CS_GEN.CE_I | system_axi_spi_0_axi_lite_ipif_v3_0_4_pselect_f__parameterized13 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | +| MEM_DECODE_GEN[0].PER_CE_GEN[14].MULTIPLE_CES_THIS_CS_GEN.CE_I | system_axi_spi_0_axi_lite_ipif_v3_0_4_pselect_f__parameterized14 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | +| MEM_DECODE_GEN[0].PER_CE_GEN[1].MULTIPLE_CES_THIS_CS_GEN.CE_I | system_axi_spi_0_axi_lite_ipif_v3_0_4_pselect_f__parameterized1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | +| MEM_DECODE_GEN[0].PER_CE_GEN[2].MULTIPLE_CES_THIS_CS_GEN.CE_I | system_axi_spi_0_axi_lite_ipif_v3_0_4_pselect_f__parameterized2 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | +| MEM_DECODE_GEN[0].PER_CE_GEN[3].MULTIPLE_CES_THIS_CS_GEN.CE_I | system_axi_spi_0_axi_lite_ipif_v3_0_4_pselect_f__parameterized3 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | +| MEM_DECODE_GEN[0].PER_CE_GEN[4].MULTIPLE_CES_THIS_CS_GEN.CE_I | system_axi_spi_0_axi_lite_ipif_v3_0_4_pselect_f__parameterized4 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | +| MEM_DECODE_GEN[0].PER_CE_GEN[5].MULTIPLE_CES_THIS_CS_GEN.CE_I | system_axi_spi_0_axi_lite_ipif_v3_0_4_pselect_f__parameterized5 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | +| MEM_DECODE_GEN[0].PER_CE_GEN[6].MULTIPLE_CES_THIS_CS_GEN.CE_I | system_axi_spi_0_axi_lite_ipif_v3_0_4_pselect_f__parameterized6 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | +| MEM_DECODE_GEN[0].PER_CE_GEN[7].MULTIPLE_CES_THIS_CS_GEN.CE_I | system_axi_spi_0_axi_lite_ipif_v3_0_4_pselect_f__parameterized7 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | +| MEM_DECODE_GEN[0].PER_CE_GEN[8].MULTIPLE_CES_THIS_CS_GEN.CE_I | system_axi_spi_0_axi_lite_ipif_v3_0_4_pselect_f__parameterized8 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | +| MEM_DECODE_GEN[0].PER_CE_GEN[9].MULTIPLE_CES_THIS_CS_GEN.CE_I | system_axi_spi_0_axi_lite_ipif_v3_0_4_pselect_f__parameterized9 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | +| MEM_DECODE_GEN[1].PER_CE_GEN[2].MULTIPLE_CES_THIS_CS_GEN.CE_I | system_axi_spi_0_axi_lite_ipif_v3_0_4_pselect_f__parameterized19 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | +| MEM_DECODE_GEN[1].PER_CE_GEN[6].MULTIPLE_CES_THIS_CS_GEN.CE_I | system_axi_spi_0_axi_lite_ipif_v3_0_4_pselect_f__parameterized23 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | +| MEM_DECODE_GEN[2].PER_CE_GEN[2].MULTIPLE_CES_THIS_CS_GEN.CE_I | system_axi_spi_0_axi_lite_ipif_v3_0_4_pselect_f__parameterized19_17 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | +| MEM_DECODE_GEN[2].PER_CE_GEN[6].MULTIPLE_CES_THIS_CS_GEN.CE_I | system_axi_spi_0_axi_lite_ipif_v3_0_4_pselect_f__parameterized23_18 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | +| QSPI_LEGACY_MD_GEN.QSPI_CORE_INTERFACE_I | system_axi_spi_0_qspi_core_interface | 265 | 253 | 12 | 0 | 464 | 0 | 0 | 0 | +| (QSPI_LEGACY_MD_GEN.QSPI_CORE_INTERFACE_I) | system_axi_spi_0_qspi_core_interface | 8 | 8 | 0 | 0 | 44 | 0 | 0 | 0 | +| CONTROL_REG_I | system_axi_spi_0_qspi_cntrl_reg | 3 | 3 | 0 | 0 | 10 | 0 | 0 | 0 | +| FIFO_EXISTS.CLK_CROSS_I | system_axi_spi_0_cross_clk_sync_fifo_1 | 17 | 17 | 0 | 0 | 34 | 0 | 0 | 0 | +| FIFO_EXISTS.FIFO_IF_MODULE_I | system_axi_spi_0_qspi_fifo_ifmodule | 1 | 1 | 0 | 0 | 4 | 0 | 0 | 0 | +| FIFO_EXISTS.RX_FIFO_EMPTY_SYNC_AXI_2_SPI_CDC | system_axi_spi_0_cdc_sync | 1 | 1 | 0 | 0 | 2 | 0 | 0 | 0 | +| FIFO_EXISTS.RX_FIFO_FULL_SYNCED_SPI_2_AXI_CDC | system_axi_spi_0_cdc_sync_0 | 1 | 1 | 0 | 0 | 2 | 0 | 0 | 0 | +| FIFO_EXISTS.RX_FIFO_II | system_axi_spi_0_xpm_fifo_async | 79 | 73 | 6 | 0 | 135 | 0 | 0 | 0 | +| gnuram_async_fifo.xpm_fifo_base_inst | system_axi_spi_0_xpm_fifo_base | 79 | 73 | 6 | 0 | 135 | 0 | 0 | 0 | +| (gnuram_async_fifo.xpm_fifo_base_inst) | system_axi_spi_0_xpm_fifo_base | 3 | 3 | 0 | 0 | 11 | 0 | 0 | 0 | +| gaf_wptr_p3.wrpp3_inst | system_axi_spi_0_xpm_counter_updn_5 | 2 | 2 | 0 | 0 | 4 | 0 | 0 | 0 | +| gen_cdc_pntr.rd_pntr_cdc_inst | system_axi_spi_0_xpm_cdc_gray__2 | 5 | 5 | 0 | 0 | 12 | 0 | 0 | 0 | +| gen_cdc_pntr.rpw_gray_reg | system_axi_spi_0_xpm_fifo_reg_vec_6 | 6 | 6 | 0 | 0 | 4 | 0 | 0 | 0 | +| gen_cdc_pntr.wpr_gray_reg | system_axi_spi_0_xpm_fifo_reg_vec_8 | 3 | 3 | 0 | 0 | 4 | 0 | 0 | 0 | +| gen_cdc_pntr.wpr_gray_reg_dc | system_axi_spi_0_xpm_fifo_reg_vec__parameterized0_9 | 2 | 2 | 0 | 0 | 5 | 0 | 0 | 0 | +| gen_cdc_pntr.wr_pntr_cdc_dc_inst | system_axi_spi_0_xpm_cdc_gray__parameterized0__1 | 6 | 6 | 0 | 0 | 25 | 0 | 0 | 0 | +| gen_cdc_pntr.wr_pntr_cdc_inst | system_axi_spi_0_xpm_cdc_gray__1 | 5 | 5 | 0 | 0 | 12 | 0 | 0 | 0 | +| gen_fwft.rdpp1_inst | system_axi_spi_0_xpm_counter_updn__parameterized1_10 | 5 | 5 | 0 | 0 | 2 | 0 | 0 | 0 | +| gen_sdpram.xpm_memory_base_inst | system_axi_spi_0_xpm_memory_base__1 | 6 | 0 | 6 | 0 | 16 | 0 | 0 | 0 | +| rdp_inst | system_axi_spi_0_xpm_counter_updn__parameterized2_11 | 8 | 8 | 0 | 0 | 5 | 0 | 0 | 0 | +| rdpp1_inst | system_axi_spi_0_xpm_counter_updn__parameterized3_12 | 3 | 3 | 0 | 0 | 4 | 0 | 0 | 0 | +| rst_d1_inst | system_axi_spi_0_xpm_fifo_reg_bit_13 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | +| wrp_inst | system_axi_spi_0_xpm_counter_updn__parameterized2_14 | 3 | 3 | 0 | 0 | 5 | 0 | 0 | 0 | +| wrpp1_inst | system_axi_spi_0_xpm_counter_updn__parameterized3_15 | 3 | 3 | 0 | 0 | 4 | 0 | 0 | 0 | +| wrpp2_inst | system_axi_spi_0_xpm_counter_updn__parameterized0_16 | 3 | 3 | 0 | 0 | 4 | 0 | 0 | 0 | +| xpm_fifo_rst_inst | system_axi_spi_0_xpm_fifo_rst__xdcDup__1 | 17 | 17 | 0 | 0 | 17 | 0 | 0 | 0 | +| (xpm_fifo_rst_inst) | system_axi_spi_0_xpm_fifo_rst__xdcDup__1 | 17 | 17 | 0 | 0 | 13 | 0 | 0 | 0 | +| gen_rst_ic.rrst_wr_inst | system_axi_spi_0_xpm_cdc_sync_rst__5 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| gen_rst_ic.wrst_rd_inst | system_axi_spi_0_xpm_cdc_sync_rst__4 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| FIFO_EXISTS.TX_FIFO_EMPTY_CNTR_I | system_axi_spi_0_counter_f | 5 | 5 | 0 | 0 | 4 | 0 | 0 | 0 | +| FIFO_EXISTS.TX_FIFO_II | system_axi_spi_0_async_fifo_fg | 88 | 82 | 6 | 0 | 125 | 0 | 0 | 0 | +| (FIFO_EXISTS.TX_FIFO_II) | system_axi_spi_0_async_fifo_fg | 9 | 9 | 0 | 0 | 0 | 0 | 0 | 0 | +| xpm_fifo_instance.xpm_fifo_async_inst | system_axi_spi_0_xpm_fifo_async__parameterized1 | 79 | 73 | 6 | 0 | 125 | 0 | 0 | 0 | +| gnuram_async_fifo.xpm_fifo_base_inst | system_axi_spi_0_xpm_fifo_base__parameterized0 | 79 | 73 | 6 | 0 | 125 | 0 | 0 | 0 | +| (gnuram_async_fifo.xpm_fifo_base_inst) | system_axi_spi_0_xpm_fifo_base__parameterized0 | 3 | 3 | 0 | 0 | 11 | 0 | 0 | 0 | +| gaf_wptr_p3.wrpp3_inst | system_axi_spi_0_xpm_counter_updn | 2 | 2 | 0 | 0 | 4 | 0 | 0 | 0 | +| gen_cdc_pntr.rd_pntr_cdc_dc_inst | system_axi_spi_0_xpm_cdc_gray__parameterized1 | 6 | 6 | 0 | 0 | 15 | 0 | 0 | 0 | +| gen_cdc_pntr.rd_pntr_cdc_inst | system_axi_spi_0_xpm_cdc_gray | 5 | 5 | 0 | 0 | 12 | 0 | 0 | 0 | +| gen_cdc_pntr.rpw_gray_reg | system_axi_spi_0_xpm_fifo_reg_vec | 7 | 7 | 0 | 0 | 4 | 0 | 0 | 0 | +| gen_cdc_pntr.rpw_gray_reg_dc | system_axi_spi_0_xpm_fifo_reg_vec__parameterized0 | 3 | 3 | 0 | 0 | 5 | 0 | 0 | 0 | +| gen_cdc_pntr.wpr_gray_reg | system_axi_spi_0_xpm_fifo_reg_vec_1 | 3 | 3 | 0 | 0 | 4 | 0 | 0 | 0 | +| gen_cdc_pntr.wr_pntr_cdc_inst | system_axi_spi_0_xpm_cdc_gray__3 | 5 | 5 | 0 | 0 | 12 | 0 | 0 | 0 | +| gen_fwft.rdpp1_inst | system_axi_spi_0_xpm_counter_updn__parameterized1 | 4 | 4 | 0 | 0 | 2 | 0 | 0 | 0 | +| gen_sdpram.xpm_memory_base_inst | system_axi_spi_0_xpm_memory_base | 6 | 0 | 6 | 0 | 16 | 0 | 0 | 0 | +| rdp_inst | system_axi_spi_0_xpm_counter_updn__parameterized2 | 8 | 8 | 0 | 0 | 5 | 0 | 0 | 0 | +| rdpp1_inst | system_axi_spi_0_xpm_counter_updn__parameterized3 | 3 | 3 | 0 | 0 | 4 | 0 | 0 | 0 | +| rst_d1_inst | system_axi_spi_0_xpm_fifo_reg_bit | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | +| wrp_inst | system_axi_spi_0_xpm_counter_updn__parameterized2_3 | 4 | 4 | 0 | 0 | 5 | 0 | 0 | 0 | +| wrpp1_inst | system_axi_spi_0_xpm_counter_updn__parameterized3_4 | 3 | 3 | 0 | 0 | 4 | 0 | 0 | 0 | +| wrpp2_inst | system_axi_spi_0_xpm_counter_updn__parameterized0 | 3 | 3 | 0 | 0 | 4 | 0 | 0 | 0 | +| xpm_fifo_rst_inst | system_axi_spi_0_xpm_fifo_rst | 16 | 16 | 0 | 0 | 17 | 0 | 0 | 0 | +| (xpm_fifo_rst_inst) | system_axi_spi_0_xpm_fifo_rst | 16 | 16 | 0 | 0 | 13 | 0 | 0 | 0 | +| gen_rst_ic.rrst_wr_inst | system_axi_spi_0_xpm_cdc_sync_rst | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| gen_rst_ic.wrst_rd_inst | system_axi_spi_0_xpm_cdc_sync_rst__6 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| INTERRUPT_CONTROL_I | system_axi_spi_0_interrupt_control | 12 | 12 | 0 | 0 | 23 | 0 | 0 | 0 | +| LOGIC_FOR_MD_0_GEN.SPI_MODULE_I | system_axi_spi_0_qspi_mode_0_module | 40 | 40 | 0 | 0 | 59 | 0 | 0 | 0 | +| RESET_SYNC_AXI_SPI_CLK_INST | system_axi_spi_0_reset_sync_module | 1 | 1 | 0 | 0 | 2 | 0 | 0 | 0 | +| SOFT_RESET_I | system_axi_spi_0_soft_reset | 9 | 9 | 0 | 0 | 19 | 0 | 0 | 0 | +| STATUS_REG_MODE_0_GEN.STATUS_SLAVE_SEL_REG_I | system_axi_spi_0_qspi_status_slave_sel_reg | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | +| axi_tdd_0 | axi_tdd_0_imp_PE8F36 | 418 | 418 | 0 | 0 | 761 | 0 | 0 | 0 | +| tdd_ch_slice_0 | system_tdd_ch_slice_0_0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| tdd_core | system_tdd_core_0 | 418 | 418 | 0 | 0 | 761 | 0 | 0 | 0 | +| inst | system_tdd_core_0_axi_tdd | 418 | 418 | 0 | 0 | 761 | 0 | 0 | 0 | +| genblk1[0].i_channel | system_tdd_core_0_axi_tdd_channel | 20 | 20 | 0 | 0 | 69 | 0 | 0 | 0 | +| i_counter | system_tdd_core_0_axi_tdd_counter | 166 | 166 | 0 | 0 | 166 | 0 | 0 | 0 | +| i_regmap | system_tdd_core_0_axi_tdd_regmap | 94 | 94 | 0 | 0 | 390 | 0 | 0 | 0 | +| (i_regmap) | system_tdd_core_0_axi_tdd_regmap | 85 | 85 | 0 | 0 | 364 | 0 | 0 | 0 | +| i_tdd_ch_en_sync | system_tdd_core_0_sync_bits__parameterized1 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| i_tdd_control_sync | system_tdd_core_0_sync_bits | 1 | 1 | 0 | 0 | 6 | 0 | 0 | 0 | +| i_tdd_cstate_sync | system_tdd_core_0_sync_data | 5 | 5 | 0 | 0 | 10 | 0 | 0 | 0 | +| (i_tdd_cstate_sync) | system_tdd_core_0_sync_data | 4 | 4 | 0 | 0 | 6 | 0 | 0 | 0 | +| i_sync_in | system_tdd_core_0_sync_bits__parameterized0__xdcDup__1 | 1 | 1 | 0 | 0 | 2 | 0 | 0 | 0 | +| i_sync_out | system_tdd_core_0_sync_bits__parameterized0__xdcDup__2 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| i_tdd_soft_sync | system_tdd_core_0_sync_event | 3 | 3 | 0 | 0 | 8 | 0 | 0 | 0 | +| (i_tdd_soft_sync) | system_tdd_core_0_sync_event | 1 | 1 | 0 | 0 | 4 | 0 | 0 | 0 | +| i_sync_in | system_tdd_core_0_sync_bits__parameterized0__xdcDup__3 | 1 | 1 | 0 | 0 | 2 | 0 | 0 | 0 | +| i_sync_out | system_tdd_core_0_sync_bits__parameterized0 | 1 | 1 | 0 | 0 | 2 | 0 | 0 | 0 | +| i_sync_gen | system_tdd_core_0_axi_tdd_sync_gen | 0 | 0 | 0 | 0 | 3 | 0 | 0 | 0 | +| i_up_axi | system_tdd_core_0_up_axi | 138 | 138 | 0 | 0 | 133 | 0 | 0 | 0 | +| logic_inv | system_logic_inv_0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| logic_or | system_logic_or_0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | +| msk_top | system_msk_top_0 | 9416 | 8944 | 472 | 0 | 13740 | 0 | 4 | 20 | +| (msk_top) | system_msk_top_0 | 2 | 2 | 0 | 0 | 3 | 0 | 2 | 0 | +| U0 | system_msk_top_0_msk_top | 9414 | 8942 | 472 | 0 | 13737 | 0 | 2 | 20 | +| (U0) | system_msk_top_0_msk_top | 34 | 34 | 0 | 0 | 86 | 0 | 0 | 0 | +| u_async_fifo | system_msk_top_0_axis_async_fifo__1 | 359 | 135 | 224 | 0 | 127 | 0 | 0 | 0 | +| u_dem | system_msk_top_0_msk_demodulator | 2181 | 2181 | 0 | 0 | 1130 | 0 | 0 | 16 | +| (u_dem) | system_msk_top_0_msk_demodulator | 65 | 65 | 0 | 0 | 82 | 0 | 0 | 4 | +| U_f1 | system_msk_top_0_costas_loop | 1052 | 1052 | 0 | 0 | 524 | 0 | 0 | 6 | +| (U_f1) | system_msk_top_0_costas_loop | 329 | 329 | 0 | 0 | 280 | 0 | 0 | 2 | +| U_carrier_nco | system_msk_top_0_nco__parameterized1_56 | 111 | 111 | 0 | 0 | 114 | 0 | 0 | 0 | +| U_carrier_sin_cos_lut | system_msk_top_0_sin_cos_lut_57 | 275 | 275 | 0 | 0 | 0 | 0 | 0 | 0 | +| u_loopfilter | system_msk_top_0_pi_controller_58 | 337 | 337 | 0 | 0 | 130 | 0 | 0 | 4 | +| U_f2 | system_msk_top_0_costas_loop_55 | 1066 | 1066 | 0 | 0 | 524 | 0 | 0 | 6 | +| (U_f2) | system_msk_top_0_costas_loop_55 | 346 | 346 | 0 | 0 | 280 | 0 | 0 | 2 | +| U_carrier_nco | system_msk_top_0_nco__parameterized1 | 111 | 111 | 0 | 0 | 114 | 0 | 0 | 0 | +| U_carrier_sin_cos_lut | system_msk_top_0_sin_cos_lut | 278 | 278 | 0 | 0 | 0 | 0 | 0 | 0 | +| u_loopfilter | system_msk_top_0_pi_controller | 331 | 331 | 0 | 0 | 130 | 0 | 0 | 4 | +| u_deserializer | system_msk_top_0_byte_to_bit_deserializer | 24 | 24 | 0 | 0 | 20 | 0 | 0 | 0 | +| u_mod | system_msk_top_0_msk_modulator | 305 | 305 | 0 | 0 | 394 | 0 | 0 | 0 | +| (u_mod) | system_msk_top_0_msk_modulator | 176 | 176 | 0 | 0 | 199 | 0 | 0 | 0 | +| U_f1_nco | system_msk_top_0_nco__parameterized0 | 32 | 32 | 0 | 0 | 64 | 0 | 0 | 0 | +| U_f2_nco | system_msk_top_0_nco__parameterized0_54 | 32 | 32 | 0 | 0 | 64 | 0 | 0 | 0 | +| U_tclk_nco | system_msk_top_0_nco | 65 | 65 | 0 | 0 | 67 | 0 | 0 | 0 | +| u_msk_top_csr | system_msk_top_0_msk_top_csr | 2299 | 2299 | 0 | 0 | 1618 | 0 | 0 | 0 | +| (u_msk_top_csr) | system_msk_top_0_msk_top_csr | 9 | 9 | 0 | 0 | 2 | 0 | 0 | 0 | +| u01s | system_msk_top_0_cdc_resync | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| u02s | system_msk_top_0_cdc_resync_0 | 2 | 2 | 0 | 0 | 2 | 0 | 0 | 0 | +| u03s | system_msk_top_0_cdc_resync_1 | 2 | 2 | 0 | 0 | 2 | 0 | 0 | 0 | +| u04s | system_msk_top_0_cdc_resync_2 | 1 | 1 | 0 | 0 | 2 | 0 | 0 | 0 | +| u05s | system_msk_top_0_cdc_resync_3 | 31 | 31 | 0 | 0 | 2 | 0 | 0 | 0 | +| u06s | system_msk_top_0_cdc_resync_4 | 2 | 2 | 0 | 0 | 2 | 0 | 0 | 0 | +| u07s | system_msk_top_0_cdc_resync_5 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| u09s | system_msk_top_0_cdc_resync_6 | 2 | 2 | 0 | 0 | 2 | 0 | 0 | 0 | +| u10s | system_msk_top_0_cdc_resync_7 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| u11s | system_msk_top_0_cdc_resync_8 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| u12s | system_msk_top_0_cdc_resync_9 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| u13s | system_msk_top_0_cdc_resync_10 | 1 | 1 | 0 | 0 | 2 | 0 | 0 | 0 | +| u14s | system_msk_top_0_cdc_resync_11 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| u15s | system_msk_top_0_cdc_resync_12 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| u16s | system_msk_top_0_cdc_resync_13 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| u_msk_regs | system_msk_top_0_msk_top_regs | 2166 | 2166 | 0 | 0 | 1091 | 0 | 0 | 0 | +| urfl_s | system_msk_top_0_cdc_resync_14 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| urxe_s | system_msk_top_0_cdc_resync_15 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| utatc_a | system_msk_top_0_pulse_detect | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utatc_c | system_msk_top_0_data_capture | 0 | 0 | 0 | 0 | 32 | 0 | 0 | 0 | +| utatc_r | system_msk_top_0_pulse_detect_16 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utbc_a | system_msk_top_0_pulse_detect_17 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utbc_c | system_msk_top_0_data_capture_18 | 0 | 0 | 0 | 0 | 32 | 0 | 0 | 0 | +| utbc_r | system_msk_top_0_pulse_detect_19 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utbe_a | system_msk_top_0_pulse_detect_20 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utbe_c | system_msk_top_0_data_capture_21 | 0 | 0 | 0 | 0 | 32 | 0 | 0 | 0 | +| utbe_r | system_msk_top_0_pulse_detect_22 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utf1a_a | system_msk_top_0_pulse_detect_23 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utf1a_c | system_msk_top_0_data_capture_24 | 0 | 0 | 0 | 0 | 32 | 0 | 0 | 0 | +| utf1a_r | system_msk_top_0_pulse_detect_25 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utf1e_a | system_msk_top_0_pulse_detect_26 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utf1e_c | system_msk_top_0_data_capture_27 | 0 | 0 | 0 | 0 | 32 | 0 | 0 | 0 | +| utf1e_r | system_msk_top_0_pulse_detect_28 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utf2a_a | system_msk_top_0_pulse_detect_29 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utf2a_c | system_msk_top_0_data_capture_30 | 0 | 0 | 0 | 0 | 32 | 0 | 0 | 0 | +| utf2a_r | system_msk_top_0_pulse_detect_31 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utf2e_a | system_msk_top_0_pulse_detect_32 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utf2e_c | system_msk_top_0_data_capture_33 | 0 | 0 | 0 | 0 | 32 | 0 | 0 | 0 | +| utf2e_r | system_msk_top_0_pulse_detect_34 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utfsc_c | system_msk_top_0_data_capture__parameterized4 | 0 | 0 | 0 | 0 | 24 | 0 | 0 | 0 | +| utfse_c | system_msk_top_0_data_capture__parameterized6 | 0 | 0 | 0 | 0 | 6 | 0 | 0 | 0 | +| utfsr_a | system_msk_top_0_pulse_detect_35 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utfsr_r | system_msk_top_0_pulse_detect_36 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utfss_a | system_msk_top_0_pulse_detect_37 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utfss_r | system_msk_top_0_pulse_detect_38 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utlp1_a | system_msk_top_0_pulse_detect_39 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utlp1_c | system_msk_top_0_data_capture_40 | 0 | 0 | 0 | 0 | 32 | 0 | 0 | 0 | +| utlp1_r | system_msk_top_0_pulse_detect_41 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utlp2_a | system_msk_top_0_pulse_detect_42 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utlp2_c | system_msk_top_0_data_capture_43 | 0 | 0 | 0 | 0 | 32 | 0 | 0 | 0 | +| utlp2_r | system_msk_top_0_pulse_detect_44 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utprb_a | system_msk_top_0_pulse_detect_45 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utprb_c | system_msk_top_0_data_capture_46 | 0 | 0 | 0 | 0 | 32 | 0 | 0 | 0 | +| utprb_r | system_msk_top_0_pulse_detect_47 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utpre_a | system_msk_top_0_pulse_detect_48 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utpre_c | system_msk_top_0_data_capture_49 | 0 | 0 | 0 | 0 | 32 | 0 | 0 | 0 | +| utpre_r | system_msk_top_0_pulse_detect_50 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utpwr_a | system_msk_top_0_pulse_detect_51 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utpwr_c | system_msk_top_0_data_capture__parameterized2 | 0 | 0 | 0 | 0 | 23 | 0 | 0 | 0 | +| utpwr_r | system_msk_top_0_pulse_detect_52 | 2 | 2 | 0 | 0 | 3 | 0 | 0 | 0 | +| utxe_s | system_msk_top_0_cdc_resync_53 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| u_ov_decoder | system_msk_top_0_ov_frame_decoder | 73 | 73 | 0 | 0 | 60 | 0 | 1 | 0 | +| (u_ov_decoder) | system_msk_top_0_ov_frame_decoder | 66 | 66 | 0 | 0 | 57 | 0 | 1 | 0 | +| U_DECODER | system_msk_top_0_viterbi_decoder_k7_simple | 7 | 7 | 0 | 0 | 3 | 0 | 0 | 0 | +| u_ov_encoder | system_msk_top_0_ov_frame_encoder | 3598 | 3574 | 24 | 0 | 9822 | 0 | 0 | 0 | +| (u_ov_encoder) | system_msk_top_0_ov_frame_encoder | 1382 | 1358 | 24 | 0 | 4394 | 0 | 0 | 0 | +| U_ENCODER | system_msk_top_0_conv_encoder_k7 | 2216 | 2216 | 0 | 0 | 5428 | 0 | 0 | 0 | +| u_power_det | system_msk_top_0_power_detector | 54 | 54 | 0 | 0 | 41 | 0 | 0 | 4 | +| (u_power_det) | system_msk_top_0_power_detector | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | +| u_ema_1 | system_msk_top_0_lowpass_ema | 54 | 54 | 0 | 0 | 41 | 0 | 0 | 2 | +| u_prbs_gen | system_msk_top_0_prbs_gen | 2 | 2 | 0 | 0 | 34 | 0 | 0 | 0 | +| u_prbs_mon | system_msk_top_0_prbs_mon | 26 | 26 | 0 | 0 | 105 | 0 | 0 | 0 | +| u_rx_async_fifo | system_msk_top_0_axis_async_fifo | 360 | 136 | 224 | 0 | 127 | 0 | 0 | 0 | +| u_rx_frame_sync | system_msk_top_0_frame_sync_detector | 123 | 123 | 0 | 0 | 173 | 0 | 1 | 0 | +| sys_concat_intc | system_sys_concat_intc_0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| sys_ps7 | system_sys_ps7_0 | 11 | 11 | 0 | 0 | 0 | 0 | 0 | 0 | +| inst | system_sys_ps7_0_processing_system7_v5_5_processing_system7 | 11 | 11 | 0 | 0 | 0 | 0 | 0 | 0 | +| sys_rstgen | system_sys_rstgen_0 | 16 | 15 | 0 | 1 | 30 | 0 | 0 | 0 | +| U0 | system_sys_rstgen_0_proc_sys_reset | 16 | 15 | 0 | 1 | 30 | 0 | 0 | 0 | +| (U0) | system_sys_rstgen_0_proc_sys_reset | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | +| EXT_LPF | system_sys_rstgen_0_lpf | 4 | 3 | 0 | 1 | 14 | 0 | 0 | 0 | +| (EXT_LPF) | system_sys_rstgen_0_lpf | 2 | 1 | 0 | 1 | 6 | 0 | 0 | 0 | +| ACTIVE_LOW_AUX.ACT_LO_AUX | system_sys_rstgen_0_cdc_sync | 1 | 1 | 0 | 0 | 4 | 0 | 0 | 0 | +| ACTIVE_LOW_EXT.ACT_LO_EXT | system_sys_rstgen_0_cdc_sync_0 | 1 | 1 | 0 | 0 | 4 | 0 | 0 | 0 | +| SEQ | system_sys_rstgen_0_sequence_psr | 12 | 12 | 0 | 0 | 15 | 0 | 0 | 0 | +| (SEQ) | system_sys_rstgen_0_sequence_psr | 7 | 7 | 0 | 0 | 9 | 0 | 0 | 0 | +| SEQ_COUNTER | system_sys_rstgen_0_upcnt_n | 5 | 5 | 0 | 0 | 6 | 0 | 0 | 0 | +| tx_upack | system_tx_upack_0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | +| inst | system_tx_upack_0_util_upack2 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | +| i_upack | system_tx_upack_0_util_upack2_impl | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | +| (i_upack) | system_tx_upack_0_util_upack2_impl | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | +| i_pack_shell | system_tx_upack_0_pack_shell | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ++----------------------------------------------------------------------------------+---------------------------------------------------------------------------------+------------+------------+---------+------+-------+--------+--------+------------+ +* Note: The sum of lower-level cells may be larger than their parent cells total, due to cross-hierarchy LUT combining + + diff --git a/projects/pluto/resource_utilization.csv b/projects/pluto/resource_utilization.csv new file mode 100644 index 0000000..2ce846c --- /dev/null +++ b/projects/pluto/resource_utilization.csv @@ -0,0 +1,2 @@ +"Description","Part","Top","PR (Cell)","PR (Pblock)","SLR-Level Analysis","Clock Regions","LUT(#)","FD(#)","RAMB/FIFO(#)","URAM(#)","DSP(#)","Criteria to review","LUT(%)","FD(%)","LUTRAM+SRL(%)","CARRY8(%)","LOOKAHEAD8(%)","MUXF7(%)","MUXF8(%)","LUT Combining(%)","DSP(%)","RAMB/FIFO(%)","URAM(%)","DSP+RAMB+URAM (Avg)(%)","BUFGCE* + BUFGCTRL","Control Sets","DONT_TOUCH(#)","MARK_DEBUG(#)","Average Fanout for modules > 100k cells","Non-FD high fanout nets > 10k loads","TIMING-6","TIMING-7","TIMING-8","TIMING-14","TIMING-35","Number of paths above max LUT budgeting 0.575ns","Number of paths above max Net budgeting 0.403ns",MMCM*,PLL*,Worst_Setup_Slack,Worst_Hold_Slack +"Value","xc7z010clg225-1","system_top","","","","","12925","18887","4","n/a","20","5","73.44","53.66","10.00","n/a","n/a","7.91","6.95","24.56","25.00","6.67","n/a","15.84","3","705","29","0","0","0","0","0","0","0","0","0","0",0,0,0.613,0.014 diff --git a/projects/pluto/system_bd.tcl b/projects/pluto/system_bd.tcl index 28244b3..0a50606 100644 --- a/projects/pluto/system_bd.tcl +++ b/projects/pluto/system_bd.tcl @@ -1,13 +1,28 @@ # create board design +# LibreSDR with MSK Modem Integration +# Based on pluto MSK design adapted for LibreSDR LVDS interface +# +############################################################################## +# CLOCK DIVIDER MODIFICATION +############################################################################## +# In LVDS mode, AD9361 DATA_CLK (l_clk) runs at 245.76 MHz (4x sample rate). +# The MSK modem expects to run at the sample rate (61.44 MHz). +# This design uses a BUFR-based clock divider to create the correct clock. +# +# Changes from original: +# 1. Added clk_div_by4 module instantiation +# 2. msk_top/clk connected to divided clock (61.44 MHz) +# 3. msk_top/s_axis_aclk stays at l_clk (245 MHz) for DMA interface +# 4. tx_valid and rx_svalid tied to VCC (every divided clock cycle is valid) +# +# To revert: Search for "CLOCK_DIVIDER" comments +############################################################################## -#set_property FILE_TYPE {VHDL 2008} [get_files *.vhd] source $ad_hdl_dir/projects/common/xilinx/adi_fir_filter_bd.tcl -source $ad_hdl_dir/library/axi_tdd/scripts/axi_tdd.tcl - -set_property ip_repo_paths [list $ad_hdl_dir/library ../../library] [current_fileset] +# Add MSK IP repository +set_property ip_repo_paths [list $ad_hdl_dir/library ../../library] [current_fileset] update_ip_catalog -#source ../../library/msk_top_ip.tcl # default ports @@ -24,9 +39,9 @@ create_bd_port -dir I spi0_sdo_i create_bd_port -dir O spi0_sdo_o create_bd_port -dir I spi0_sdi_i -create_bd_port -dir I -from 17 -to 0 gpio_i -create_bd_port -dir O -from 17 -to 0 gpio_o -create_bd_port -dir O -from 17 -to 0 gpio_t +create_bd_port -dir I -from 24 -to 0 gpio_i +create_bd_port -dir O -from 24 -to 0 gpio_o +create_bd_port -dir O -from 24 -to 0 gpio_t create_bd_port -dir O spi_csn_o create_bd_port -dir I spi_csn_i @@ -36,34 +51,41 @@ create_bd_port -dir I spi_sdo_i create_bd_port -dir O spi_sdo_o create_bd_port -dir I spi_sdi_i -create_bd_port -dir O txdata_o -create_bd_port -dir I tdd_ext_sync - # instance: sys_ps7 ad_ip_instance processing_system7 sys_ps7 # ps7 settings -ad_ip_parameter sys_ps7 CONFIG.PCW_PRESET_BANK0_VOLTAGE {LVCMOS 1.8V} -ad_ip_parameter sys_ps7 CONFIG.PCW_PRESET_BANK1_VOLTAGE {LVCMOS 1.8V} -ad_ip_parameter sys_ps7 CONFIG.PCW_PACKAGE_NAME clg225 +ad_ip_parameter sys_ps7 CONFIG.PCW_PRESET_BANK0_VOLTAGE {LVCMOS 3.3V} +ad_ip_parameter sys_ps7 CONFIG.PCW_PRESET_BANK1_VOLTAGE {LVCMOS 2.5V} +ad_ip_parameter sys_ps7 CONFIG.PCW_PACKAGE_NAME clg400 +ad_ip_parameter sys_ps7 CONFIG.PCW_GPIO_MIO_GPIO_ENABLE 1 +ad_ip_parameter sys_ps7 CONFIG.PCW_ENET0_PERIPHERAL_ENABLE 1 +ad_ip_parameter sys_ps7 CONFIG.PCW_ENET0_ENET0_IO "MIO 16 .. 27" +ad_ip_parameter sys_ps7 CONFIG.PCW_ENET0_GRP_MDIO_ENABLE 1 +ad_ip_parameter sys_ps7 CONFIG.PCW_ENET0_GRP_MDIO_IO "MIO 52 .. 53" +ad_ip_parameter sys_ps7 CONFIG.PCW_ENET_RESET_SELECT "Separate reset pins" +ad_ip_parameter sys_ps7 CONFIG.PCW_ENET0_RESET_ENABLE 1 +ad_ip_parameter sys_ps7 CONFIG.PCW_ENET0_RESET_IO "MIO 46" ad_ip_parameter sys_ps7 CONFIG.PCW_USE_S_AXI_HP1 1 ad_ip_parameter sys_ps7 CONFIG.PCW_USE_S_AXI_HP2 1 ad_ip_parameter sys_ps7 CONFIG.PCW_EN_CLK1_PORT 1 ad_ip_parameter sys_ps7 CONFIG.PCW_EN_RST1_PORT 1 ad_ip_parameter sys_ps7 CONFIG.PCW_FPGA0_PERIPHERAL_FREQMHZ 100.0 ad_ip_parameter sys_ps7 CONFIG.PCW_FPGA1_PERIPHERAL_FREQMHZ 200.0 +ad_ip_parameter sys_ps7 CONFIG.PCW_CRYSTAL_PERIPHERAL_FREQMHZ 50 ad_ip_parameter sys_ps7 CONFIG.PCW_GPIO_EMIO_GPIO_ENABLE 1 -ad_ip_parameter sys_ps7 CONFIG.PCW_GPIO_EMIO_GPIO_IO 18 +ad_ip_parameter sys_ps7 CONFIG.PCW_GPIO_EMIO_GPIO_IO 25 ad_ip_parameter sys_ps7 CONFIG.PCW_SPI1_PERIPHERAL_ENABLE 0 ad_ip_parameter sys_ps7 CONFIG.PCW_I2C0_PERIPHERAL_ENABLE 0 -ad_ip_parameter sys_ps7 CONFIG.PCW_UART1_PERIPHERAL_ENABLE 1 -ad_ip_parameter sys_ps7 CONFIG.PCW_UART1_UART1_IO {MIO 12 .. 13} +ad_ip_parameter sys_ps7 CONFIG.PCW_SD0_PERIPHERAL_ENABLE 1 +ad_ip_parameter sys_ps7 CONFIG.PCW_SDIO_PERIPHERAL_FREQMHZ 50 +ad_ip_parameter sys_ps7 CONFIG.PCW_UART0_PERIPHERAL_ENABLE 1 +ad_ip_parameter sys_ps7 CONFIG.PCW_UART0_UART0_IO {MIO 14 .. 15} ad_ip_parameter sys_ps7 CONFIG.PCW_I2C1_PERIPHERAL_ENABLE 0 ad_ip_parameter sys_ps7 CONFIG.PCW_QSPI_PERIPHERAL_ENABLE 1 ad_ip_parameter sys_ps7 CONFIG.PCW_QSPI_GRP_SINGLE_SS_ENABLE 1 -ad_ip_parameter sys_ps7 CONFIG.PCW_SD0_PERIPHERAL_ENABLE 0 ad_ip_parameter sys_ps7 CONFIG.PCW_SPI0_PERIPHERAL_ENABLE 1 ad_ip_parameter sys_ps7 CONFIG.PCW_SPI0_SPI0_IO EMIO ad_ip_parameter sys_ps7 CONFIG.PCW_TTC0_PERIPHERAL_ENABLE 0 @@ -71,7 +93,7 @@ ad_ip_parameter sys_ps7 CONFIG.PCW_USE_FABRIC_INTERRUPT 1 ad_ip_parameter sys_ps7 CONFIG.PCW_USB0_PERIPHERAL_ENABLE 1 ad_ip_parameter sys_ps7 CONFIG.PCW_GPIO_MIO_GPIO_ENABLE 1 ad_ip_parameter sys_ps7 CONFIG.PCW_GPIO_MIO_GPIO_IO MIO -ad_ip_parameter sys_ps7 CONFIG.PCW_USB0_RESET_IO {MIO 52} +ad_ip_parameter sys_ps7 CONFIG.PCW_USB0_RESET_IO {MIO 47} ad_ip_parameter sys_ps7 CONFIG.PCW_USB0_RESET_ENABLE 1 ad_ip_parameter sys_ps7 CONFIG.PCW_IRQ_F2P_INTR 1 ad_ip_parameter sys_ps7 CONFIG.PCW_IRQ_F2P_MODE REVERSE @@ -82,19 +104,35 @@ ad_ip_parameter sys_ps7 CONFIG.PCW_MIO_11_PULLUP {enabled} ad_ip_parameter sys_ps7 CONFIG.PCW_MIO_48_PULLUP {enabled} ad_ip_parameter sys_ps7 CONFIG.PCW_MIO_49_PULLUP {disabled} ad_ip_parameter sys_ps7 CONFIG.PCW_MIO_53_PULLUP {enabled} +ad_ip_parameter sys_ps7 CONFIG.PCW_APU_PERIPHERAL_FREQMHZ 750 # DDR MT41K256M16 HA-125 (32M, 16bit, 8banks) -ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_PARTNO {MT41K256M16 RE-125} -ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_BUS_WIDTH {16 Bit} -ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_USE_INTERNAL_VREF 0 -ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_TRAIN_WRITE_LEVEL 1 -ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_TRAIN_READ_GATE 1 -ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_TRAIN_DATA_EYE 1 -ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_0 0.048 -ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_1 0.050 -ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY0 0.241 -ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY1 0.240 +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_ACT_DDR_FREQ_MHZ 525 +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_PARTNO {Custom} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_BANK_ADDR_COUNT {3} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_ROW_ADDR_COUNT {15} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_COL_ADDR_COUNT {10} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_CL {7} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_CWL {5} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_T_RCD {7} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_T_RP {7} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_T_RC {48.91} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_T_RAS_MIN {35.0} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_T_FAW {40.0} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_0 {0.048} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_DQS_TO_CLK_DELAY_1 {0.050} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY0 {0.241} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_BOARD_DELAY1 {0.240} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_ECC {Disabled} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_BUS_WIDTH {32 Bit} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_DRAM_WIDTH {16 Bits} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_DEVICE_CAPACITY {4096 MBits} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_SPEED_BIN {DDR3_1066F} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_TRAIN_WRITE_LEVEL {1} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_TRAIN_READ_GATE {1} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_TRAIN_DATA_EYE {1} +ad_ip_parameter sys_ps7 CONFIG.PCW_UIPARAM_DDR_USE_INTERNAL_VREF {0} ad_ip_instance xlconcat sys_concat_intc ad_ip_parameter sys_concat_intc CONFIG.NUM_PORTS 16 @@ -181,51 +219,55 @@ ad_cpu_interrupt ps-15 mb-15 axi_iic_main/iic2intc_irpt # ad9361 -create_bd_port -dir I rx_clk_in -create_bd_port -dir I rx_frame_in -create_bd_port -dir I -from 11 -to 0 rx_data_in +create_bd_port -dir I rx_clk_in_p +create_bd_port -dir I rx_clk_in_n +create_bd_port -dir I rx_frame_in_p +create_bd_port -dir I rx_frame_in_n +create_bd_port -dir I -from 5 -to 0 rx_data_in_p +create_bd_port -dir I -from 5 -to 0 rx_data_in_n -create_bd_port -dir O tx_clk_out -create_bd_port -dir O tx_frame_out -create_bd_port -dir O -from 11 -to 0 tx_data_out +create_bd_port -dir O tx_clk_out_p +create_bd_port -dir O tx_clk_out_n +create_bd_port -dir O tx_frame_out_p +create_bd_port -dir O tx_frame_out_n +create_bd_port -dir O -from 5 -to 0 tx_data_out_p +create_bd_port -dir O -from 5 -to 0 tx_data_out_n create_bd_port -dir O enable create_bd_port -dir O txnrx create_bd_port -dir I up_enable create_bd_port -dir I up_txnrx -# ad9361 core(s) - +# ad9361 core ad_ip_instance axi_ad9361 axi_ad9361 ad_ip_parameter axi_ad9361 CONFIG.ID 0 -ad_ip_parameter axi_ad9361 CONFIG.CMOS_OR_LVDS_N 1 -ad_ip_parameter axi_ad9361 CONFIG.MODE_1R1T 0 -ad_ip_parameter axi_ad9361 CONFIG.ADC_INIT_DELAY 21 +ad_ip_parameter axi_ad9361 CONFIG.CMOS_OR_LVDS_N 0 +# CLOCK_DIVIDER: Using 1R1T mode as required by LibreSDR device tree +ad_ip_parameter axi_ad9361 CONFIG.MODE_1R1T 1 +ad_ip_parameter axi_ad9361 CONFIG.ADC_INIT_DELAY 30 +# TDD, DDS, and more ad_ip_parameter axi_ad9361 CONFIG.TDD_DISABLE 1 ad_ip_parameter axi_ad9361 CONFIG.DAC_DDS_DISABLE 1 -ad_ip_parameter axi_ad9361 CONFIG.ADC_USERPORTS_DISABLE 1 ad_ip_parameter axi_ad9361 CONFIG.ADC_DCFILTER_DISABLE 1 ad_ip_parameter axi_ad9361 CONFIG.ADC_IQCORRECTION_DISABLE 1 -ad_ip_parameter axi_ad9361 CONFIG.DAC_USERPORTS_DISABLE 1 ad_ip_parameter axi_ad9361 CONFIG.DAC_IQCORRECTION_DISABLE 1 +# Enable user ports for direct MSK connection +ad_ip_parameter axi_ad9361 CONFIG.DAC_USERPORTS_DISABLE 0 +ad_ip_parameter axi_ad9361 CONFIG.ADC_USERPORTS_DISABLE 0 + +# DAC DMA - TX data from PS to MSK ad_ip_instance axi_dmac axi_ad9361_dac_dma ad_ip_parameter axi_ad9361_dac_dma CONFIG.DMA_TYPE_SRC 0 ad_ip_parameter axi_ad9361_dac_dma CONFIG.DMA_TYPE_DEST 1 -ad_ip_parameter axi_ad9361_dac_dma CONFIG.CYCLIC 1 +ad_ip_parameter axi_ad9361_dac_dma CONFIG.CYCLIC 0 ad_ip_parameter axi_ad9361_dac_dma CONFIG.AXI_SLICE_SRC 0 ad_ip_parameter axi_ad9361_dac_dma CONFIG.AXI_SLICE_DEST 0 ad_ip_parameter axi_ad9361_dac_dma CONFIG.DMA_2D_TRANSFER 0 -# Abraxas3d changed below parameter from 64 to 32 ad_ip_parameter axi_ad9361_dac_dma CONFIG.DMA_DATA_WIDTH_DEST 32 -#ad_add_interpolation_filter "tx_fir_interpolator" 8 2 1 {61.44} {7.68} \ -# "$ad_hdl_dir/library/util_fir_int/coefile_int.coe" -ad_ip_instance xlslice interp_slice -ad_ip_instance util_upack2 tx_upack - -# changed DMA_TYPE_SRC from 2 (FIFO) to 1 (AXIS) +# ADC DMA - RX data from MSK to PS (AXIS interface) ad_ip_instance axi_dmac axi_ad9361_adc_dma ad_ip_parameter axi_ad9361_adc_dma CONFIG.DMA_TYPE_SRC 1 ad_ip_parameter axi_ad9361_adc_dma CONFIG.DMA_TYPE_DEST 0 @@ -234,23 +276,22 @@ ad_ip_parameter axi_ad9361_adc_dma CONFIG.SYNC_TRANSFER_START 0 ad_ip_parameter axi_ad9361_adc_dma CONFIG.AXI_SLICE_SRC 0 ad_ip_parameter axi_ad9361_adc_dma CONFIG.AXI_SLICE_DEST 0 ad_ip_parameter axi_ad9361_adc_dma CONFIG.DMA_2D_TRANSFER 0 -# Abraxas3d changed below parameter from 64 to 32 ad_ip_parameter axi_ad9361_adc_dma CONFIG.DMA_DATA_WIDTH_SRC 32 -ad_ip_parameter axi_ad9361_adc_dma CONFIG.SYNC_TRANSFER_START {true} - -#ad_add_decimation_filter "rx_fir_decimator" 8 2 1 {61.44} {61.44} \ -# "$ad_hdl_dir/library/util_fir_int/coefile_int.coe" -ad_ip_instance xlslice decim_slice -ad_ip_instance util_cpack2 cpack # connections -ad_connect rx_clk_in axi_ad9361/rx_clk_in -ad_connect rx_frame_in axi_ad9361/rx_frame_in -ad_connect rx_data_in axi_ad9361/rx_data_in -ad_connect tx_clk_out axi_ad9361/tx_clk_out -ad_connect tx_frame_out axi_ad9361/tx_frame_out -ad_connect tx_data_out axi_ad9361/tx_data_out +ad_connect rx_clk_in_p axi_ad9361/rx_clk_in_p +ad_connect rx_clk_in_n axi_ad9361/rx_clk_in_n +ad_connect rx_frame_in_p axi_ad9361/rx_frame_in_p +ad_connect rx_frame_in_n axi_ad9361/rx_frame_in_n +ad_connect rx_data_in_p axi_ad9361/rx_data_in_p +ad_connect rx_data_in_n axi_ad9361/rx_data_in_n +ad_connect tx_clk_out_p axi_ad9361/tx_clk_out_p +ad_connect tx_clk_out_n axi_ad9361/tx_clk_out_n +ad_connect tx_frame_out_p axi_ad9361/tx_frame_out_p +ad_connect tx_frame_out_n axi_ad9361/tx_frame_out_n +ad_connect tx_data_out_p axi_ad9361/tx_data_out_p +ad_connect tx_data_out_n axi_ad9361/tx_data_out_n ad_connect enable axi_ad9361/enable ad_connect txnrx axi_ad9361/txnrx ad_connect up_enable axi_ad9361/up_enable @@ -260,123 +301,21 @@ ad_connect axi_ad9361/tdd_sync GND ad_connect sys_200m_clk axi_ad9361/delay_clk ad_connect axi_ad9361/l_clk axi_ad9361/clk -#ad_connect axi_ad9361/l_clk rx_fir_decimator/aclk - -#ad_connect axi_ad9361/adc_valid_i0 rx_fir_decimator/valid_in_0 -#ad_connect axi_ad9361/adc_enable_i0 rx_fir_decimator/enable_in_0 -#ad_connect axi_ad9361/adc_data_i0 rx_fir_decimator/data_in_0 -#ad_connect axi_ad9361/adc_valid_q0 rx_fir_decimator/valid_in_1 -#ad_connect axi_ad9361/adc_enable_q0 rx_fir_decimator/enable_in_1 -#ad_connect axi_ad9361/adc_data_q0 rx_fir_decimator/data_in_1 - -ad_connect axi_ad9361/l_clk cpack/clk -ad_connect axi_ad9361/rst cpack/reset - -ad_connect axi_ad9361/adc_enable_i1 cpack/enable_2 -ad_connect axi_ad9361/adc_data_i1 cpack/fifo_wr_data_2 -ad_connect axi_ad9361/adc_enable_q1 cpack/enable_3 -ad_connect axi_ad9361/adc_data_q1 cpack/fifo_wr_data_3 - -#ad_connect cpack/enable_0 rx_fir_decimator/enable_out_0 -#ad_connect cpack/enable_1 rx_fir_decimator/enable_out_1 -#ad_connect cpack/fifo_wr_data_0 rx_fir_decimator/data_out_0 -#ad_connect cpack/fifo_wr_data_1 rx_fir_decimator/data_out_1 -#ad_connect rx_fir_decimator/valid_out_0 cpack/fifo_wr_en - -#ad_connect axi_ad9361_adc_dma/fifo_wr cpack/packed_fifo_wr -ad_connect axi_ad9361/up_adc_gpio_out decim_slice/Din -#ad_connect rx_fir_decimator/active decim_slice/Dout - -#ad_connect axi_ad9361/l_clk tx_fir_interpolator/aclk - -#ad_connect axi_ad9361/dac_enable_i0 tx_fir_interpolator/dac_enable_0 -#ad_connect axi_ad9361/dac_valid_i0 tx_fir_interpolator/dac_valid_0 -#ad_connect axi_ad9361/dac_data_i0 tx_fir_interpolator/data_out_0 -#ad_connect axi_ad9361/dac_enable_q0 tx_fir_interpolator/dac_enable_1 -#ad_connect axi_ad9361/dac_valid_q0 tx_fir_interpolator/dac_valid_1 -#ad_connect axi_ad9361/dac_data_q0 tx_fir_interpolator/data_out_1 - -ad_connect axi_ad9361/l_clk tx_upack/clk - -#ad_connect tx_upack/fifo_rd_data_0 tx_fir_interpolator/data_in_0 -#ad_connect tx_upack/enable_0 tx_fir_interpolator/enable_out_0 -#ad_connect tx_upack/fifo_rd_data_1 tx_fir_interpolator/data_in_1 -#ad_connect tx_upack/enable_1 tx_fir_interpolator/enable_out_1 - -ad_connect axi_ad9361/dac_enable_i1 tx_upack/enable_2 -ad_connect axi_ad9361/dac_data_i1 tx_upack/fifo_rd_data_2 -ad_connect axi_ad9361/dac_enable_q1 tx_upack/enable_3 -ad_connect axi_ad9361/dac_data_q1 tx_upack/fifo_rd_data_3 - -#ad_connect tx_upack/s_axis axi_ad9361_dac_dma/m_axis - -ad_ip_instance util_vector_logic logic_or [list \ +# Logic OR for reset +ad_ip_instance util_vector_logic logic_or_1 [list \ C_OPERATION {or} \ C_SIZE 1] -#ad_connect logic_or/Op1 tx_fir_interpolator/valid_out_0 -ad_connect logic_or/Op1 axi_ad9361/dac_valid_i0 -ad_connect logic_or/Op2 axi_ad9361/dac_valid_i1 -ad_connect logic_or/Res tx_upack/fifo_rd_en -ad_connect tx_upack/fifo_rd_underflow axi_ad9361/dac_dunf - -ad_connect axi_ad9361/up_dac_gpio_out interp_slice/Din -#ad_connect tx_fir_interpolator/active interp_slice/Dout +ad_connect logic_or_1/Op1 axi_ad9361/rst +ad_connect logic_or_1/Op2 GND -# Old FIFO connection -#ad_connect axi_ad9361/l_clk axi_ad9361_adc_dma/fifo_wr_clk -# New AXIS connection +# DMA clock connections - these stay at l_clk (245 MHz) ad_connect axi_ad9361/l_clk axi_ad9361_adc_dma/s_axis_aclk - ad_connect axi_ad9361/l_clk axi_ad9361_dac_dma/m_axis_aclk -#ad_connect sys_cpu_clk axi_ad9361_dac_dma/m_axis_aclk -# removied and replaced with direct connection -#ad_connect cpack/fifo_wr_overflow axi_ad9361/adc_dovf +# Tie off unused signals ad_connect GND axi_ad9361/adc_dovf - -# External TDD -set TDD_CHANNEL_CNT 3 -set TDD_DEFAULT_POL 0b010 -set TDD_REG_WIDTH 32 -set TDD_BURST_WIDTH 32 -set TDD_SYNC_WIDTH 0 -set TDD_SYNC_INT 0 -set TDD_SYNC_EXT 1 -set TDD_SYNC_EXT_CDC 1 -ad_tdd_gen_create axi_tdd_0 $TDD_CHANNEL_CNT \ - $TDD_DEFAULT_POL \ - $TDD_REG_WIDTH \ - $TDD_BURST_WIDTH \ - $TDD_SYNC_WIDTH \ - $TDD_SYNC_INT \ - $TDD_SYNC_EXT \ - $TDD_SYNC_EXT_CDC - -ad_ip_instance util_vector_logic logic_inv [list \ - C_OPERATION {not} \ - C_SIZE 1] - -ad_ip_instance util_vector_logic logic_or_1 [list \ - C_OPERATION {or} \ - C_SIZE 1] - -ad_connect logic_inv/Op1 axi_ad9361/rst -ad_connect logic_inv/Res axi_tdd_0/resetn -ad_connect axi_ad9361/l_clk axi_tdd_0/clk -ad_connect axi_tdd_0/sync_in tdd_ext_sync -ad_connect axi_tdd_0/tdd_channel_0 txdata_o -# remove this for FIFO to AXIS conversion -#ad_connect axi_tdd_0/tdd_channel_1 axi_ad9361_adc_dma/fifo_wr_sync - -# Replace with (sync not needed for now) -# ad_connect axi_tdd_0/tdd_channel_1 GND -# Or connect to frame sync if you want TDD control: -# ad_connect axi_tdd_0/tdd_channel_1 msk_top/sync_locked - -ad_connect logic_or_1/Op1 axi_ad9361/rst -ad_connect logic_or_1/Op2 axi_tdd_0/tdd_channel_2 -ad_connect logic_or_1/Res tx_upack/reset +ad_connect GND axi_ad9361/dac_dunf # interconnects @@ -384,14 +323,12 @@ ad_cpu_interconnect 0x79020000 axi_ad9361 ad_cpu_interconnect 0x7C400000 axi_ad9361_adc_dma ad_cpu_interconnect 0x7C420000 axi_ad9361_dac_dma ad_cpu_interconnect 0x7C430000 axi_spi -ad_cpu_interconnect 0x7C440000 axi_tdd_0 - ad_ip_parameter sys_ps7 CONFIG.PCW_USE_S_AXI_HP1 {1} ad_connect sys_cpu_clk sys_ps7/S_AXI_HP1_ACLK ad_connect axi_ad9361_adc_dma/m_dest_axi sys_ps7/S_AXI_HP1 -create_bd_addr_seg -range 0x20000000 -offset 0x00000000 \ +create_bd_addr_seg -range 0x40000000 -offset 0x00000000 \ [get_bd_addr_spaces axi_ad9361_adc_dma/m_dest_axi] \ [get_bd_addr_segs sys_ps7/S_AXI_HP1/HP1_DDR_LOWOCM] \ SEG_sys_ps7_HP1_DDR_LOWOCM @@ -400,7 +337,7 @@ ad_ip_parameter sys_ps7 CONFIG.PCW_USE_S_AXI_HP2 {1} ad_connect sys_cpu_clk sys_ps7/S_AXI_HP2_ACLK ad_connect axi_ad9361_dac_dma/m_src_axi sys_ps7/S_AXI_HP2 -create_bd_addr_seg -range 0x20000000 -offset 0x00000000 \ +create_bd_addr_seg -range 0x40000000 -offset 0x00000000 \ [get_bd_addr_spaces axi_ad9361_dac_dma/m_src_axi] \ [get_bd_addr_segs sys_ps7/S_AXI_HP2/HP2_DDR_LOWOCM] \ SEG_sys_ps7_HP2_DDR_LOWOCM @@ -416,51 +353,143 @@ ad_cpu_interrupt ps-13 mb-13 axi_ad9361_adc_dma/irq ad_cpu_interrupt ps-12 mb-12 axi_ad9361_dac_dma/irq ad_cpu_interrupt ps-11 mb-11 axi_spi/ip2intc_irpt -## msk interpose ad_ip_instance -ad_ip_instance msk_top msk_top -#MSK Connects +############################################################################## +# CLOCK_DIVIDER: Clock divider for MSK modem (245.76 MHz -> 61.44 MHz) +############################################################################## +# Uses BUFR primitive to divide l_clk by 4. +# This provides a phase-aligned 61.44 MHz clock for the MSK modem. +# The BUFR output edges align with every 4th l_clk edge, ensuring proper +# timing for DAC/ADC data which is stable for 4 l_clk cycles per sample. +############################################################################## -ad_connect msk_top/clk axi_ad9361/clk -ad_connect msk_top/s_axis_aclk axi_ad9361/clk -ad_connect msk_top/s_axi_aclk sys_cpu_clk +# Add the clock divider source file to the project before creating the BD cell +add_files -norecurse ../../src/clk_div_by4.vhd +update_compile_order -fileset sources_1 -ad_connect msk_top/s_axis_aresetn sys_cpu_resetn -ad_connect msk_top/s_axi_aresetn sys_cpu_resetn -#ad_cpu_interconnect 0x7C450000 msk_top -ad_cpu_interconnect 0x43C00000 msk_top +create_bd_cell -type module -reference clk_div_by4 clk_divider +ad_connect axi_ad9361/l_clk clk_divider/clk_in -#MSK Connects TX +############################################################################## +# MSK Modem Integration +############################################################################## -ad_connect msk_top/tx_samples_I axi_ad9361/dac_data_i0 -ad_connect msk_top/tx_samples_Q axi_ad9361/dac_data_q0 -ad_connect msk_top/tx_enable axi_ad9361/dac_enable_i0 -ad_connect msk_top/tx_valid axi_ad9361/dac_valid_i0 +ad_ip_instance msk_top msk_top -# instead of this command, we connect everything explicitly -#ad_connect axi_ad9361_dac_dma/m_axis msk_top/s_axis +# CLOCK_DIVIDER: MSK processing clock - use divided clock (61.44 MHz) +# This is where the NCO, modulator, demodulator all run +ad_connect msk_top/clk clk_divider/clk_out -# EXPLICIT AXIS CONNECTIONS - Wire each signal individually -ad_connect axi_ad9361_dac_dma/m_axis_data msk_top/s_axis_tdata -ad_connect axi_ad9361_dac_dma/m_axis_valid msk_top/s_axis_tvalid -ad_connect msk_top/s_axis_tready axi_ad9361_dac_dma/m_axis_ready -ad_connect axi_ad9361_dac_dma/m_axis_last msk_top/s_axis_tlast -ad_connect axi_ad9361_dac_dma/m_axis_keep msk_top/s_axis_tkeep +# CLOCK_DIVIDER: MSK AXIS clock - keep at l_clk (245 MHz) for DMA interface +# The async FIFO inside msk_top handles CDC between s_axis_aclk and clk +ad_connect msk_top/s_axis_aclk axi_ad9361/l_clk +# MSK AXI-Lite register interface (100 MHz CPU clock) +ad_connect msk_top/s_axi_aclk sys_cpu_clk +ad_connect msk_top/s_axis_aresetn sys_cpu_resetn +ad_connect msk_top/s_axi_aresetn sys_cpu_resetn +# MSK AXI-Lite register interface +ad_cpu_interconnect 0x43C00000 msk_top -#MSK Connects RX +# MSK TX Connects - Channel 0 I/Q to AD9361 +# CLOCK_DIVIDER: TX samples need to be synchronized from clk_div4 to l_clk domain +# The msk_top outputs change on clk_div4 edges, but AD9361 samples on l_clk. +# Without sync, the DAC might catch glitches during transitions. + +# Create sync registers for TX I/Q (resample clk_div4 outputs to l_clk) +create_bd_cell -type ip -vlnv xilinx.com:ip:c_shift_ram:12.0 tx_i_sync +set_property -dict [list \ + CONFIG.Width {16} \ + CONFIG.Depth {1} \ + CONFIG.DefaultData {0000000000000000} \ + CONFIG.AsyncInitVal {0000000000000000} \ +] [get_bd_cells tx_i_sync] + +create_bd_cell -type ip -vlnv xilinx.com:ip:c_shift_ram:12.0 tx_q_sync +set_property -dict [list \ + CONFIG.Width {16} \ + CONFIG.Depth {1} \ + CONFIG.DefaultData {0000000000000000} \ + CONFIG.AsyncInitVal {0000000000000000} \ +] [get_bd_cells tx_q_sync] + +# Clock sync registers with l_clk (245 MHz) +ad_connect axi_ad9361/l_clk tx_i_sync/CLK +ad_connect axi_ad9361/l_clk tx_q_sync/CLK + +# MSK outputs -> sync registers +ad_connect msk_top/tx_samples_I tx_i_sync/D +ad_connect msk_top/tx_samples_Q tx_q_sync/D + +# Sync registers -> AD9361 +ad_connect tx_i_sync/Q axi_ad9361/dac_data_i0 +ad_connect tx_q_sync/Q axi_ad9361/dac_data_q0 +ad_connect msk_top/tx_enable axi_ad9361/dac_enable_i0 + +# CLOCK_DIVIDER: tx_valid tied HIGH - every 61.44 MHz clock cycle is a valid sample +# (Previously connected to dac_valid_i0 which pulses in l_clk domain) +ad_connect msk_top/tx_valid VCC + +# TX DMA Connections +ad_connect axi_ad9361_dac_dma/m_axis_data msk_top/s_axis_tdata +ad_connect axi_ad9361_dac_dma/m_axis_valid msk_top/s_axis_tvalid +ad_connect axi_ad9361_dac_dma/m_axis_ready msk_top/s_axis_tready +ad_connect axi_ad9361_dac_dma/m_axis_last msk_top/s_axis_tlast +ad_connect axi_ad9361_dac_dma/m_axis_keep msk_top/s_axis_tkeep + +# MSK RX Connects - Channel 0 I/Q from AD9361 ad_connect msk_top/rx_samples_I axi_ad9361/adc_data_i0 ad_connect msk_top/rx_samples_Q axi_ad9361/adc_data_q0 ad_connect msk_top/rx_enable axi_ad9361/adc_enable_i0 -ad_connect msk_top/rx_svalid axi_ad9361/adc_valid_i0 -# FIFO to AXIS conversion: -#ad_connect msk_top/rx_data axi_ad9361_adc_dma/fifo_wr_din -#ad_connect msk_top/rx_dvalid axi_ad9361_adc_dma/fifo_wr_en -#ad_connect msk_top/m_axis axi_ad9361_adc_dma/s_axis +# CLOCK_DIVIDER: rx_svalid tied HIGH - every 61.44 MHz clock cycle is a valid sample +# (Previously connected to adc_valid_i0 which pulses in l_clk domain) +ad_connect msk_top/rx_svalid VCC -# RX AXIS - Use interface connection (DMA doesn't expose individual pins) +# MSK RX AXIS to DMA - interface connection ad_connect msk_top/m_axis axi_ad9361_adc_dma/s_axis + +############################################################################## +# ILA Debug Core - Modulator Output Monitoring +############################################################################## +# Captures TX I/Q samples to verify modulator is producing correct waveforms. +# Clock: clk_div4 (61.44 MHz) - same domain as modulator +# Trigger: probe0 (I samples) != 0 +# +# To use in Vivado: +# 1. Program FPGA +# 2. Open Hardware Manager +# 3. Click "Refresh" to see ILA core +# 4. Set trigger: probe0 != 0 +# 5. Click "Run Trigger" +# 6. Transmit a frame - ILA captures the waveforms +############################################################################## + +create_bd_cell -type ip -vlnv xilinx.com:ip:ila:6.2 ila_msk_tx +set_property -dict [list \ + CONFIG.C_PROBE0_WIDTH {16} \ + CONFIG.C_PROBE1_WIDTH {16} \ + CONFIG.C_PROBE2_WIDTH {1} \ + CONFIG.C_NUM_OF_PROBES {3} \ + CONFIG.C_DATA_DEPTH {16384} \ + CONFIG.C_TRIGIN_EN {false} \ + CONFIG.C_EN_STRG_QUAL {1} \ + CONFIG.ALL_PROBE_SAME_MU_CNT {2} \ +] [get_bd_cells ila_msk_tx] + +# Clock ILA with divided clock (same as modulator) +ad_connect clk_divider/clk_out ila_msk_tx/clk + +# Probe 0: TX I samples (16 bits) - also used as trigger +ad_connect msk_top/tx_samples_I ila_msk_tx/probe0 + +# Probe 1: TX Q samples (16 bits) +ad_connect msk_top/tx_samples_Q ila_msk_tx/probe1 + +# Probe 2: dac_valid_i0 from AD9361 (in l_clk domain, sampled by clk_div4) +# This shows when AD9361 expects new data - should pulse once per clk_div4 cycle +ad_connect axi_ad9361/dac_valid_i0 ila_msk_tx/probe2 + diff --git a/projects/pluto/system_top.v b/projects/pluto/system_top.v index e491027..53ba9ad 100644 --- a/projects/pluto/system_top.v +++ b/projects/pluto/system_top.v @@ -166,8 +166,9 @@ module system_top ( .gpio_i (gpio_i), .gpio_o (gpio_o), .gpio_t (gpio_t), - .iic_main_scl_io (iic_scl), - .iic_main_sda_io (iic_sda), + // REMOVED axi_iic_main + //.iic_main_scl_io (iic_scl), + //.iic_main_sda_io (iic_sda), .rx_clk_in (rx_clk_in), .rx_data_in (rx_data_in), .rx_frame_in (rx_frame_in), @@ -182,15 +183,17 @@ module system_top ( .spi0_sdo_i (1'b0), .spi0_sdo_o (spi_mosi), - .spi_clk_i(1'b0), - .spi_clk_o(pl_spi_clk_o), - .spi_csn_i(1'b1), - .spi_csn_o(), - .spi_sdi_i(pl_spi_miso), - .spi_sdo_i(1'b0), - .spi_sdo_o(pl_spi_mosi), - - .tdd_ext_sync(pl_burst), + // REMOVED axi_spi + //.spi_clk_i(1'b0), + //.spi_clk_o(pl_spi_clk_o), + //.spi_csn_i(1'b1), + //.spi_csn_o(), + //.spi_sdi_i(pl_spi_miso), + //.spi_sdo_i(1'b0), + //.spi_sdo_o(pl_spi_mosi), + + // REMOVED axi_tdd + //.tdd_ext_sync(pl_burst), .txdata_o(pl_txdata), .tx_clk_out (tx_clk_out), diff --git a/projects/pluto/util_deep.txt b/projects/pluto/util_deep.txt new file mode 100644 index 0000000..d32fab3 --- /dev/null +++ b/projects/pluto/util_deep.txt @@ -0,0 +1,505 @@ +Copyright 1986-2022 Xilinx, Inc. All Rights Reserved. +---------------------------------------------------------------------------------------------------------------------- +| Tool Version : Vivado v.2022.2 (lin64) Build 3671981 Fri Oct 14 04:59:54 MDT 2022 +| Date : Sun Nov 30 20:40:42 2025 +| Host : mymelody running 64-bit Ubuntu 22.04.5 LTS +| Command : report_utilization -hierarchical -hierarchical_depth 8 -hierarchical_percentages -file util_deep.txt +| Design : system_top +| Device : xc7z010clg225-1 +| Speed File : -1 +| Design State : Synthesized +---------------------------------------------------------------------------------------------------------------------- + +Utilization Design Information + +Table of Contents +----------------- +1. Utilization by Hierarchy + +1. Utilization by Hierarchy +--------------------------- + ++-------------------------------------------------------------+------------------------------------------------------------------------+---------------+---------------+-------------+-----------+---------------+----------+----------+------------+ +| Instance | Module | Total LUTs | Logic LUTs | LUTRAMs | SRLs | FFs | RAMB36 | RAMB18 | DSP Blocks | ++-------------------------------------------------------------+------------------------------------------------------------------------+---------------+---------------+-------------+-----------+---------------+----------+----------+------------+ +| system_top | (top) | 16980(96.48%) | 16294(92.58%) | 602(10.03%) | 84(1.40%) | 20832(59.18%) | 2(3.33%) | 4(3.33%) | 36(45.00%) | +| (system_top) | (top) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_system_wrapper | system_wrapper | 16980(96.48%) | 16294(92.58%) | 602(10.03%) | 84(1.40%) | 20832(59.18%) | 2(3.33%) | 4(3.33%) | 36(45.00%) | +| (i_system_wrapper) | system_wrapper | 2(0.01%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| system_i | system | 16978(96.47%) | 16292(92.57%) | 602(10.03%) | 84(1.40%) | 20832(59.18%) | 2(3.33%) | 4(3.33%) | 36(45.00%) | +| (system_i) | system | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| axi_ad9361 | system_axi_ad9361_0 | 2048(11.64%) | 2048(11.64%) | 0(0.00%) | 0(0.00%) | 3301(9.38%) | 0(0.00%) | 0(0.00%) | 16(20.00%) | +| (axi_ad9361) | system_axi_ad9361_0 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| inst | system_axi_ad9361_0_axi_ad9361 | 2048(11.64%) | 2048(11.64%) | 0(0.00%) | 0(0.00%) | 3301(9.38%) | 0(0.00%) | 0(0.00%) | 16(20.00%) | +| (inst) | system_axi_ad9361_0_axi_ad9361 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 89(0.25%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_dev_if | system_axi_ad9361_0_axi_ad9361_cmos_if | 130(0.74%) | 130(0.74%) | 0(0.00%) | 0(0.00%) | 181(0.51%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_dev_if) | system_axi_ad9361_0_axi_ad9361_cmos_if | 67(0.38%) | 67(0.38%) | 0(0.00%) | 0(0.00%) | 181(0.51%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| g_rx_data[0].i_rx_data | system_axi_ad9361_0_ad_data_in | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| g_rx_data[10].i_rx_data | system_axi_ad9361_0_ad_data_in_41 | 8(0.05%) | 8(0.05%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| g_rx_data[11].i_rx_data | system_axi_ad9361_0_ad_data_in_42 | 12(0.07%) | 12(0.07%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| g_rx_data[1].i_rx_data | system_axi_ad9361_0_ad_data_in_43 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| g_rx_data[2].i_rx_data | system_axi_ad9361_0_ad_data_in_44 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| g_rx_data[3].i_rx_data | system_axi_ad9361_0_ad_data_in_45 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| g_rx_data[4].i_rx_data | system_axi_ad9361_0_ad_data_in_46 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| g_rx_data[5].i_rx_data | system_axi_ad9361_0_ad_data_in_47 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| g_rx_data[6].i_rx_data | system_axi_ad9361_0_ad_data_in_48 | 7(0.04%) | 7(0.04%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| g_rx_data[7].i_rx_data | system_axi_ad9361_0_ad_data_in_49 | 13(0.07%) | 13(0.07%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| g_rx_data[8].i_rx_data | system_axi_ad9361_0_ad_data_in_50 | 5(0.03%) | 5(0.03%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| g_rx_data[9].i_rx_data | system_axi_ad9361_0_ad_data_in_51 | 8(0.05%) | 8(0.05%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| g_tx_data[0].i_tx_data | system_axi_ad9361_0_ad_data_out | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| g_tx_data[10].i_tx_data | system_axi_ad9361_0_ad_data_out_52 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| g_tx_data[11].i_tx_data | system_axi_ad9361_0_ad_data_out_53 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| g_tx_data[1].i_tx_data | system_axi_ad9361_0_ad_data_out_54 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| g_tx_data[2].i_tx_data | system_axi_ad9361_0_ad_data_out_55 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| g_tx_data[3].i_tx_data | system_axi_ad9361_0_ad_data_out_56 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| g_tx_data[4].i_tx_data | system_axi_ad9361_0_ad_data_out_57 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| g_tx_data[5].i_tx_data | system_axi_ad9361_0_ad_data_out_58 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| g_tx_data[6].i_tx_data | system_axi_ad9361_0_ad_data_out_59 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| g_tx_data[7].i_tx_data | system_axi_ad9361_0_ad_data_out_60 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| g_tx_data[8].i_tx_data | system_axi_ad9361_0_ad_data_out_61 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| g_tx_data[9].i_tx_data | system_axi_ad9361_0_ad_data_out_62 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_clk | system_axi_ad9361_0_ad_data_clk | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_enable | system_axi_ad9361_0_ad_data_out_63 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_rx_frame | system_axi_ad9361_0_ad_data_in__parameterized0 | 10(0.06%) | 10(0.06%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_tx_clk | system_axi_ad9361_0_ad_data_out_64 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_tx_frame | system_axi_ad9361_0_ad_data_out_65 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_txnrx | system_axi_ad9361_0_ad_data_out_66 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_rx | system_axi_ad9361_0_axi_ad9361_rx | 740(4.20%) | 740(4.20%) | 0(0.00%) | 0(0.00%) | 1590(4.52%) | 0(0.00%) | 0(0.00%) | 8(10.00%) | +| (i_rx) | system_axi_ad9361_0_axi_ad9361_rx | 60(0.34%) | 60(0.34%) | 0(0.00%) | 0(0.00%) | 36(0.10%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_delay_cntrl | system_axi_ad9361_0_up_delay_cntrl | 7(0.04%) | 7(0.04%) | 0(0.00%) | 0(0.00%) | 96(0.27%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_delay_cntrl) | system_axi_ad9361_0_up_delay_cntrl | 7(0.04%) | 7(0.04%) | 0(0.00%) | 0(0.00%) | 91(0.26%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_delay_rst_reg | system_axi_ad9361_0_ad_rst__xdcDup__1 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 5(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_rx_channel_0 | system_axi_ad9361_0_axi_ad9361_rx_channel | 148(0.84%) | 148(0.84%) | 0(0.00%) | 0(0.00%) | 252(0.72%) | 0(0.00%) | 0(0.00%) | 2(2.50%) | +| i_ad_datafmt | system_axi_ad9361_0_ad_datafmt_34 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 13(0.04%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_ad_iqcor | system_axi_ad9361_0_ad_iqcor_35 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 2(2.50%) | +| g_loop[0].i_mul_i | system_axi_ad9361_0_ad_mul__parameterized0_37 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 1(1.25%) | +| g_loop[0].i_mul_q | system_axi_ad9361_0_ad_mul_38 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 1(1.25%) | +| i_rx_pnmon | system_axi_ad9361_0_axi_ad9361_rx_pnmon | 61(0.35%) | 61(0.35%) | 0(0.00%) | 0(0.00%) | 137(0.39%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_rx_pnmon) | system_axi_ad9361_0_axi_ad9361_rx_pnmon | 2(0.01%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 128(0.36%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_pnmon | system_axi_ad9361_0_ad_pnmon_36 | 59(0.34%) | 59(0.34%) | 0(0.00%) | 0(0.00%) | 9(0.03%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_up_adc_channel | system_axi_ad9361_0_up_adc_channel | 87(0.49%) | 87(0.49%) | 0(0.00%) | 0(0.00%) | 102(0.29%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_up_adc_channel) | system_axi_ad9361_0_up_adc_channel | 5(0.03%) | 5(0.03%) | 0(0.00%) | 0(0.00%) | 44(0.13%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_xfer_cntrl | system_axi_ad9361_0_up_xfer_cntrl__xdcDup__1 | 71(0.40%) | 71(0.40%) | 0(0.00%) | 0(0.00%) | 38(0.11%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_xfer_status | system_axi_ad9361_0_up_xfer_status__xdcDup__1 | 11(0.06%) | 11(0.06%) | 0(0.00%) | 0(0.00%) | 20(0.06%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_rx_channel_1 | system_axi_ad9361_0_axi_ad9361_rx_channel__parameterized0 | 145(0.82%) | 145(0.82%) | 0(0.00%) | 0(0.00%) | 283(0.80%) | 0(0.00%) | 0(0.00%) | 2(2.50%) | +| i_ad_datafmt | system_axi_ad9361_0_ad_datafmt_27 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 13(0.04%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_ad_iqcor | system_axi_ad9361_0_ad_iqcor__parameterized0_28 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 2(2.50%) | +| g_loop[0].i_mul_i | system_axi_ad9361_0_ad_mul__parameterized0_30 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 1(1.25%) | +| g_loop[0].i_mul_q | system_axi_ad9361_0_ad_mul_31 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 1(1.25%) | +| i_rx_pnmon | system_axi_ad9361_0_axi_ad9361_rx_pnmon__parameterized0 | 59(0.34%) | 59(0.34%) | 0(0.00%) | 0(0.00%) | 168(0.48%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_rx_pnmon) | system_axi_ad9361_0_axi_ad9361_rx_pnmon__parameterized0 | 2(0.01%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 159(0.45%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_pnmon | system_axi_ad9361_0_ad_pnmon_29 | 57(0.32%) | 57(0.32%) | 0(0.00%) | 0(0.00%) | 9(0.03%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_up_adc_channel | system_axi_ad9361_0_up_adc_channel__parameterized0 | 86(0.49%) | 86(0.49%) | 0(0.00%) | 0(0.00%) | 102(0.29%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_up_adc_channel) | system_axi_ad9361_0_up_adc_channel__parameterized0 | 5(0.03%) | 5(0.03%) | 0(0.00%) | 0(0.00%) | 44(0.13%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_xfer_cntrl | system_axi_ad9361_0_up_xfer_cntrl__xdcDup__2 | 70(0.40%) | 70(0.40%) | 0(0.00%) | 0(0.00%) | 38(0.11%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_xfer_status | system_axi_ad9361_0_up_xfer_status__xdcDup__2 | 11(0.06%) | 11(0.06%) | 0(0.00%) | 0(0.00%) | 20(0.06%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_rx_channel_2 | system_axi_ad9361_0_axi_ad9361_rx_channel__parameterized1 | 146(0.83%) | 146(0.83%) | 0(0.00%) | 0(0.00%) | 283(0.80%) | 0(0.00%) | 0(0.00%) | 2(2.50%) | +| i_ad_datafmt | system_axi_ad9361_0_ad_datafmt_20 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 13(0.04%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_ad_iqcor | system_axi_ad9361_0_ad_iqcor_21 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 2(2.50%) | +| g_loop[0].i_mul_i | system_axi_ad9361_0_ad_mul__parameterized0_23 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 1(1.25%) | +| g_loop[0].i_mul_q | system_axi_ad9361_0_ad_mul_24 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 1(1.25%) | +| i_rx_pnmon | system_axi_ad9361_0_axi_ad9361_rx_pnmon__parameterized1 | 59(0.34%) | 59(0.34%) | 0(0.00%) | 0(0.00%) | 168(0.48%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_rx_pnmon) | system_axi_ad9361_0_axi_ad9361_rx_pnmon__parameterized1 | 2(0.01%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 159(0.45%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_pnmon | system_axi_ad9361_0_ad_pnmon_22 | 57(0.32%) | 57(0.32%) | 0(0.00%) | 0(0.00%) | 9(0.03%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_up_adc_channel | system_axi_ad9361_0_up_adc_channel__parameterized1 | 87(0.49%) | 87(0.49%) | 0(0.00%) | 0(0.00%) | 102(0.29%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_up_adc_channel) | system_axi_ad9361_0_up_adc_channel__parameterized1 | 6(0.03%) | 6(0.03%) | 0(0.00%) | 0(0.00%) | 44(0.13%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_xfer_cntrl | system_axi_ad9361_0_up_xfer_cntrl__xdcDup__3 | 70(0.40%) | 70(0.40%) | 0(0.00%) | 0(0.00%) | 38(0.11%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_xfer_status | system_axi_ad9361_0_up_xfer_status__xdcDup__3 | 11(0.06%) | 11(0.06%) | 0(0.00%) | 0(0.00%) | 20(0.06%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_rx_channel_3 | system_axi_ad9361_0_axi_ad9361_rx_channel__parameterized2 | 155(0.88%) | 155(0.88%) | 0(0.00%) | 0(0.00%) | 251(0.71%) | 0(0.00%) | 0(0.00%) | 2(2.50%) | +| i_ad_datafmt | system_axi_ad9361_0_ad_datafmt | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 13(0.04%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_ad_iqcor | system_axi_ad9361_0_ad_iqcor__parameterized0_15 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 2(2.50%) | +| g_loop[0].i_mul_i | system_axi_ad9361_0_ad_mul__parameterized0_16 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 1(1.25%) | +| g_loop[0].i_mul_q | system_axi_ad9361_0_ad_mul_17 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 1(1.25%) | +| i_rx_pnmon | system_axi_ad9361_0_axi_ad9361_rx_pnmon__parameterized2 | 66(0.38%) | 66(0.38%) | 0(0.00%) | 0(0.00%) | 136(0.39%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_rx_pnmon) | system_axi_ad9361_0_axi_ad9361_rx_pnmon__parameterized2 | 2(0.01%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 127(0.36%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_pnmon | system_axi_ad9361_0_ad_pnmon | 64(0.36%) | 64(0.36%) | 0(0.00%) | 0(0.00%) | 9(0.03%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_up_adc_channel | system_axi_ad9361_0_up_adc_channel__parameterized2 | 89(0.51%) | 89(0.51%) | 0(0.00%) | 0(0.00%) | 102(0.29%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_up_adc_channel) | system_axi_ad9361_0_up_adc_channel__parameterized2 | 7(0.04%) | 7(0.04%) | 0(0.00%) | 0(0.00%) | 44(0.13%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_xfer_cntrl | system_axi_ad9361_0_up_xfer_cntrl | 71(0.40%) | 71(0.40%) | 0(0.00%) | 0(0.00%) | 38(0.11%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_xfer_status | system_axi_ad9361_0_up_xfer_status | 11(0.06%) | 11(0.06%) | 0(0.00%) | 0(0.00%) | 20(0.06%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_up_adc_common | system_axi_ad9361_0_up_adc_common | 79(0.45%) | 79(0.45%) | 0(0.00%) | 0(0.00%) | 389(1.11%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_up_adc_common) | system_axi_ad9361_0_up_adc_common | 17(0.10%) | 17(0.10%) | 0(0.00%) | 0(0.00%) | 257(0.73%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_clock_mon | system_axi_ad9361_0_up_clock_mon__xdcDup__1 | 42(0.24%) | 42(0.24%) | 0(0.00%) | 0(0.00%) | 88(0.25%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_core_rst_reg | system_axi_ad9361_0_ad_rst__xdcDup__2 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 5(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_xfer_cntrl | system_axi_ad9361_0_up_xfer_cntrl__parameterized0 | 9(0.05%) | 9(0.05%) | 0(0.00%) | 0(0.00%) | 19(0.05%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_xfer_status | system_axi_ad9361_0_up_xfer_status__parameterized0 | 11(0.06%) | 11(0.06%) | 0(0.00%) | 0(0.00%) | 20(0.06%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_tx | system_axi_ad9361_0_axi_ad9361_tx | 396(2.25%) | 396(2.25%) | 0(0.00%) | 0(0.00%) | 1288(3.66%) | 0(0.00%) | 0(0.00%) | 8(10.00%) | +| (i_tx) | system_axi_ad9361_0_axi_ad9361_tx | 53(0.30%) | 53(0.30%) | 0(0.00%) | 0(0.00%) | 54(0.15%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_tx_channel_0 | system_axi_ad9361_0_axi_ad9361_tx_channel | 65(0.37%) | 65(0.37%) | 0(0.00%) | 0(0.00%) | 222(0.63%) | 0(0.00%) | 0(0.00%) | 2(2.50%) | +| (i_tx_channel_0) | system_axi_ad9361_0_axi_ad9361_tx_channel | 22(0.13%) | 22(0.13%) | 0(0.00%) | 0(0.00%) | 74(0.21%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_ad_iqcor | system_axi_ad9361_0_ad_iqcor_10 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 2(2.50%) | +| g_loop[0].i_mul_i | system_axi_ad9361_0_ad_mul__parameterized0_11 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 1(1.25%) | +| g_loop[0].i_mul_q | system_axi_ad9361_0_ad_mul_12 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 1(1.25%) | +| i_up_dac_channel | system_axi_ad9361_0_up_dac_channel | 43(0.24%) | 43(0.24%) | 0(0.00%) | 0(0.00%) | 148(0.42%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_up_dac_channel) | system_axi_ad9361_0_up_dac_channel | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 78(0.22%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_xfer_cntrl | system_axi_ad9361_0_up_xfer_cntrl__parameterized1__xdcDup__1 | 40(0.23%) | 40(0.23%) | 0(0.00%) | 0(0.00%) | 70(0.20%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_tx_channel_1 | system_axi_ad9361_0_axi_ad9361_tx_channel__parameterized0 | 64(0.36%) | 64(0.36%) | 0(0.00%) | 0(0.00%) | 222(0.63%) | 0(0.00%) | 0(0.00%) | 2(2.50%) | +| (i_tx_channel_1) | system_axi_ad9361_0_axi_ad9361_tx_channel__parameterized0 | 21(0.12%) | 21(0.12%) | 0(0.00%) | 0(0.00%) | 74(0.21%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_ad_iqcor | system_axi_ad9361_0_ad_iqcor__parameterized0_5 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 2(2.50%) | +| g_loop[0].i_mul_i | system_axi_ad9361_0_ad_mul__parameterized0_6 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 1(1.25%) | +| g_loop[0].i_mul_q | system_axi_ad9361_0_ad_mul_7 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 1(1.25%) | +| i_up_dac_channel | system_axi_ad9361_0_up_dac_channel__parameterized0 | 43(0.24%) | 43(0.24%) | 0(0.00%) | 0(0.00%) | 148(0.42%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_up_dac_channel) | system_axi_ad9361_0_up_dac_channel__parameterized0 | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 78(0.22%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_xfer_cntrl | system_axi_ad9361_0_up_xfer_cntrl__parameterized1__xdcDup__2 | 40(0.23%) | 40(0.23%) | 0(0.00%) | 0(0.00%) | 70(0.20%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_tx_channel_2 | system_axi_ad9361_0_axi_ad9361_tx_channel__parameterized1 | 64(0.36%) | 64(0.36%) | 0(0.00%) | 0(0.00%) | 222(0.63%) | 0(0.00%) | 0(0.00%) | 2(2.50%) | +| (i_tx_channel_2) | system_axi_ad9361_0_axi_ad9361_tx_channel__parameterized1 | 21(0.12%) | 21(0.12%) | 0(0.00%) | 0(0.00%) | 74(0.21%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_ad_iqcor | system_axi_ad9361_0_ad_iqcor | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 2(2.50%) | +| g_loop[0].i_mul_i | system_axi_ad9361_0_ad_mul__parameterized0_1 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 1(1.25%) | +| g_loop[0].i_mul_q | system_axi_ad9361_0_ad_mul_2 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 1(1.25%) | +| i_up_dac_channel | system_axi_ad9361_0_up_dac_channel__parameterized1 | 43(0.24%) | 43(0.24%) | 0(0.00%) | 0(0.00%) | 148(0.42%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_up_dac_channel) | system_axi_ad9361_0_up_dac_channel__parameterized1 | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 78(0.22%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_xfer_cntrl | system_axi_ad9361_0_up_xfer_cntrl__parameterized1__xdcDup__3 | 40(0.23%) | 40(0.23%) | 0(0.00%) | 0(0.00%) | 70(0.20%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_tx_channel_3 | system_axi_ad9361_0_axi_ad9361_tx_channel__parameterized2 | 66(0.38%) | 66(0.38%) | 0(0.00%) | 0(0.00%) | 222(0.63%) | 0(0.00%) | 0(0.00%) | 2(2.50%) | +| (i_tx_channel_3) | system_axi_ad9361_0_axi_ad9361_tx_channel__parameterized2 | 23(0.13%) | 23(0.13%) | 0(0.00%) | 0(0.00%) | 74(0.21%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_ad_iqcor | system_axi_ad9361_0_ad_iqcor__parameterized0 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 2(2.50%) | +| g_loop[0].i_mul_i | system_axi_ad9361_0_ad_mul__parameterized0 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 1(1.25%) | +| g_loop[0].i_mul_q | system_axi_ad9361_0_ad_mul | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 1(1.25%) | +| i_up_dac_channel | system_axi_ad9361_0_up_dac_channel__parameterized2 | 43(0.24%) | 43(0.24%) | 0(0.00%) | 0(0.00%) | 148(0.42%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_up_dac_channel) | system_axi_ad9361_0_up_dac_channel__parameterized2 | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 78(0.22%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_xfer_cntrl | system_axi_ad9361_0_up_xfer_cntrl__parameterized1 | 40(0.23%) | 40(0.23%) | 0(0.00%) | 0(0.00%) | 70(0.20%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_up_dac_common | system_axi_ad9361_0_up_dac_common | 99(0.56%) | 99(0.56%) | 0(0.00%) | 0(0.00%) | 346(0.98%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_up_dac_common) | system_axi_ad9361_0_up_dac_common | 17(0.10%) | 17(0.10%) | 0(0.00%) | 0(0.00%) | 178(0.51%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_clock_mon | system_axi_ad9361_0_up_clock_mon | 43(0.24%) | 43(0.24%) | 0(0.00%) | 0(0.00%) | 88(0.25%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_core_rst_reg | system_axi_ad9361_0_ad_rst__xdcDup__4 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 5(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_xfer_cntrl | system_axi_ad9361_0_up_xfer_cntrl__parameterized2 | 29(0.16%) | 29(0.16%) | 0(0.00%) | 0(0.00%) | 55(0.16%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_xfer_status | system_axi_ad9361_0_up_xfer_status__parameterized1 | 10(0.06%) | 10(0.06%) | 0(0.00%) | 0(0.00%) | 20(0.06%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_up_axi | system_axi_ad9361_0_up_axi | 782(4.44%) | 782(4.44%) | 0(0.00%) | 0(0.00%) | 153(0.43%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| axi_ad9361_adc_dma | system_axi_ad9361_adc_dma_0 | 506(2.88%) | 468(2.66%) | 38(0.63%) | 0(0.00%) | 787(2.24%) | 1(1.67%) | 0(0.00%) | 0(0.00%) | +| (axi_ad9361_adc_dma) | system_axi_ad9361_adc_dma_0 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| inst | system_axi_ad9361_adc_dma_0_axi_dmac | 506(2.88%) | 468(2.66%) | 38(0.63%) | 0(0.00%) | 787(2.24%) | 1(1.67%) | 0(0.00%) | 0(0.00%) | +| (inst) | system_axi_ad9361_adc_dma_0_axi_dmac | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_regmap | system_axi_ad9361_adc_dma_0_axi_dmac_regmap | 281(1.60%) | 261(1.48%) | 20(0.33%) | 0(0.00%) | 357(1.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_regmap) | system_axi_ad9361_adc_dma_0_axi_dmac_regmap | 2(0.01%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 73(0.21%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_regmap_request | system_axi_ad9361_adc_dma_0_axi_dmac_regmap_request | 66(0.38%) | 46(0.26%) | 20(0.33%) | 0(0.00%) | 149(0.42%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_regmap_request) | system_axi_ad9361_adc_dma_0_axi_dmac_regmap_request | 34(0.19%) | 34(0.19%) | 0(0.00%) | 0(0.00%) | 116(0.33%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_transfer_lenghts_fifo | system_axi_ad9361_adc_dma_0_util_axis_fifo | 32(0.18%) | 12(0.07%) | 20(0.33%) | 0(0.00%) | 33(0.09%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_transfer_lenghts_fifo) | system_axi_ad9361_adc_dma_0_util_axis_fifo | 22(0.13%) | 2(0.01%) | 20(0.33%) | 0(0.00%) | 27(0.08%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| fifo.i_address_gray | system_axi_ad9361_adc_dma_0_util_axis_fifo_address_generator | 10(0.06%) | 10(0.06%) | 0(0.00%) | 0(0.00%) | 6(0.02%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_up_axi | system_axi_ad9361_adc_dma_0_up_axi | 213(1.21%) | 213(1.21%) | 0(0.00%) | 0(0.00%) | 135(0.38%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_transfer | system_axi_ad9361_adc_dma_0_axi_dmac_transfer | 225(1.28%) | 207(1.18%) | 18(0.30%) | 0(0.00%) | 430(1.22%) | 1(1.67%) | 0(0.00%) | 0(0.00%) | +| i_request_arb | system_axi_ad9361_adc_dma_0_request_arb | 215(1.22%) | 197(1.12%) | 18(0.30%) | 0(0.00%) | 393(1.12%) | 1(1.67%) | 0(0.00%) | 0(0.00%) | +| (i_request_arb) | system_axi_ad9361_adc_dma_0_request_arb | 6(0.03%) | 0(0.00%) | 6(0.10%) | 0(0.00%) | 32(0.09%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_dest_dma_mm | system_axi_ad9361_adc_dma_0_dest_axi_mm | 47(0.27%) | 39(0.22%) | 8(0.13%) | 0(0.00%) | 49(0.14%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_dest_dma_mm) | system_axi_ad9361_adc_dma_0_dest_axi_mm | 8(0.05%) | 0(0.00%) | 8(0.13%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_addr_gen | system_axi_ad9361_adc_dma_0_address_generator | 34(0.19%) | 34(0.19%) | 0(0.00%) | 0(0.00%) | 44(0.13%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_response_handler | system_axi_ad9361_adc_dma_0_response_handler | 5(0.03%) | 5(0.03%) | 0(0.00%) | 0(0.00%) | 5(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_dest_req_fifo | system_axi_ad9361_adc_dma_0_util_axis_fifo__parameterized2 | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 33(0.09%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_dest_req_fifo) | system_axi_ad9361_adc_dma_0_util_axis_fifo__parameterized2 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 29(0.08%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| zerodeep.i_raddr_sync | system_axi_ad9361_adc_dma_0_sync_bits__parameterized0__xdcDup__1 | 2(0.01%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| zerodeep.i_waddr_sync | system_axi_ad9361_adc_dma_0_sync_bits__parameterized0__xdcDup__2 | 1(0.01%) | 1(0.01%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_req_gen | system_axi_ad9361_adc_dma_0_request_generator | 59(0.34%) | 59(0.34%) | 0(0.00%) | 0(0.00%) | 52(0.15%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_response_manager | system_axi_ad9361_adc_dma_0_axi_dmac_response_manager | 25(0.14%) | 25(0.14%) | 0(0.00%) | 0(0.00%) | 34(0.10%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_response_manager) | system_axi_ad9361_adc_dma_0_axi_dmac_response_manager | 15(0.09%) | 15(0.09%) | 0(0.00%) | 0(0.00%) | 25(0.07%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_dest_response_fifo | system_axi_ad9361_adc_dma_0_util_axis_fifo__parameterized4 | 10(0.06%) | 10(0.06%) | 0(0.00%) | 0(0.00%) | 9(0.03%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_rewind_req_fifo | system_axi_ad9361_adc_dma_0_util_axis_fifo__parameterized1 | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 13(0.04%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_rewind_req_fifo) | system_axi_ad9361_adc_dma_0_util_axis_fifo__parameterized1 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 9(0.03%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| zerodeep.i_raddr_sync | system_axi_ad9361_adc_dma_0_sync_bits__parameterized0__xdcDup__3 | 2(0.01%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| zerodeep.i_waddr_sync | system_axi_ad9361_adc_dma_0_sync_bits__parameterized0__xdcDup__4 | 1(0.01%) | 1(0.01%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_src_dest_bl_fifo | system_axi_ad9361_adc_dma_0_util_axis_fifo__parameterized0 | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 11(0.03%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_src_dest_bl_fifo) | system_axi_ad9361_adc_dma_0_util_axis_fifo__parameterized0 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 7(0.02%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| zerodeep.i_raddr_sync | system_axi_ad9361_adc_dma_0_sync_bits__parameterized0__xdcDup__5 | 1(0.01%) | 1(0.01%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| zerodeep.i_waddr_sync | system_axi_ad9361_adc_dma_0_sync_bits__parameterized0__xdcDup__6 | 2(0.01%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_src_dma_stream | system_axi_ad9361_adc_dma_0_src_axi_stream | 32(0.18%) | 32(0.18%) | 0(0.00%) | 0(0.00%) | 34(0.10%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_data_mover | system_axi_ad9361_adc_dma_0_data_mover | 32(0.18%) | 32(0.18%) | 0(0.00%) | 0(0.00%) | 34(0.10%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_src_req_fifo | system_axi_ad9361_adc_dma_0_util_axis_fifo__parameterized3 | 2(0.01%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 68(0.19%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_src_req_fifo) | system_axi_ad9361_adc_dma_0_util_axis_fifo__parameterized3 | 1(0.01%) | 1(0.01%) | 0(0.00%) | 0(0.00%) | 64(0.18%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| zerodeep.i_raddr_sync | system_axi_ad9361_adc_dma_0_sync_bits__parameterized0__xdcDup__7 | 1(0.01%) | 1(0.01%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| zerodeep.i_waddr_sync | system_axi_ad9361_adc_dma_0_sync_bits__parameterized0__xdcDup__8 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_store_and_forward | system_axi_ad9361_adc_dma_0_axi_dmac_burst_memory | 30(0.17%) | 26(0.15%) | 4(0.07%) | 0(0.00%) | 51(0.14%) | 1(1.67%) | 0(0.00%) | 0(0.00%) | +| (i_store_and_forward) | system_axi_ad9361_adc_dma_0_axi_dmac_burst_memory | 25(0.14%) | 21(0.12%) | 4(0.07%) | 0(0.00%) | 35(0.10%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_dest_sync_id | system_axi_ad9361_adc_dma_0_sync_bits__parameterized2__xdcDup__1 | 2(0.01%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 8(0.02%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_mem | system_axi_ad9361_adc_dma_0_ad_mem_asym | 1(0.01%) | 1(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 1(1.67%) | 0(0.00%) | 0(0.00%) | +| i_src_sync_id | system_axi_ad9361_adc_dma_0_sync_bits__parameterized2__xdcDup__2 | 2(0.01%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 8(0.02%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_sync_src_request_id | system_axi_ad9361_adc_dma_0_sync_bits__parameterized2 | 2(0.01%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 8(0.02%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| sync_rewind | system_axi_ad9361_adc_dma_0_sync_event | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 8(0.02%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (sync_rewind) | system_axi_ad9361_adc_dma_0_sync_event | 1(0.01%) | 1(0.01%) | 0(0.00%) | 0(0.00%) | 4(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_sync_in | system_axi_ad9361_adc_dma_0_sync_bits__parameterized1__xdcDup__1 | 1(0.01%) | 1(0.01%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_sync_out | system_axi_ad9361_adc_dma_0_sync_bits__parameterized1 | 1(0.01%) | 1(0.01%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_reset_manager | system_axi_ad9361_adc_dma_0_axi_dmac_reset_manager | 10(0.06%) | 10(0.06%) | 0(0.00%) | 0(0.00%) | 37(0.11%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_reset_manager) | system_axi_ad9361_adc_dma_0_axi_dmac_reset_manager | 7(0.04%) | 7(0.04%) | 0(0.00%) | 0(0.00%) | 33(0.09%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_sync_control_src | system_axi_ad9361_adc_dma_0_sync_bits__parameterized0__xdcDup__9 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_sync_status_src | system_axi_ad9361_adc_dma_0_sync_bits__parameterized0 | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| axi_ad9361_dac_dma | system_axi_ad9361_dac_dma_0 | 463(2.63%) | 429(2.44%) | 34(0.57%) | 0(0.00%) | 692(1.97%) | 1(1.67%) | 0(0.00%) | 0(0.00%) | +| (axi_ad9361_dac_dma) | system_axi_ad9361_dac_dma_0 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| inst | system_axi_ad9361_dac_dma_0_axi_dmac | 463(2.63%) | 429(2.44%) | 34(0.57%) | 0(0.00%) | 692(1.97%) | 1(1.67%) | 0(0.00%) | 0(0.00%) | +| (inst) | system_axi_ad9361_dac_dma_0_axi_dmac | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_regmap | system_axi_ad9361_dac_dma_0_axi_dmac_regmap | 260(1.48%) | 240(1.36%) | 20(0.33%) | 0(0.00%) | 358(1.02%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_regmap) | system_axi_ad9361_dac_dma_0_axi_dmac_regmap | 2(0.01%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 73(0.21%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_regmap_request | system_axi_ad9361_dac_dma_0_axi_dmac_regmap_request | 82(0.47%) | 62(0.35%) | 20(0.33%) | 0(0.00%) | 150(0.43%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_regmap_request) | system_axi_ad9361_dac_dma_0_axi_dmac_regmap_request | 22(0.13%) | 22(0.13%) | 0(0.00%) | 0(0.00%) | 117(0.33%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_transfer_lenghts_fifo | system_axi_ad9361_dac_dma_0_util_axis_fifo | 60(0.34%) | 40(0.23%) | 20(0.33%) | 0(0.00%) | 33(0.09%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_transfer_lenghts_fifo) | system_axi_ad9361_dac_dma_0_util_axis_fifo | 50(0.28%) | 30(0.17%) | 20(0.33%) | 0(0.00%) | 27(0.08%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| fifo.i_address_gray | system_axi_ad9361_dac_dma_0_util_axis_fifo_address_generator | 10(0.06%) | 10(0.06%) | 0(0.00%) | 0(0.00%) | 6(0.02%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_up_axi | system_axi_ad9361_dac_dma_0_up_axi | 176(1.00%) | 176(1.00%) | 0(0.00%) | 0(0.00%) | 135(0.38%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_transfer | system_axi_ad9361_dac_dma_0_axi_dmac_transfer | 203(1.15%) | 189(1.07%) | 14(0.23%) | 0(0.00%) | 334(0.95%) | 1(1.67%) | 0(0.00%) | 0(0.00%) | +| i_request_arb | system_axi_ad9361_dac_dma_0_request_arb | 191(1.09%) | 177(1.01%) | 14(0.23%) | 0(0.00%) | 304(0.86%) | 1(1.67%) | 0(0.00%) | 0(0.00%) | +| (i_request_arb) | system_axi_ad9361_dac_dma_0_request_arb | 8(0.05%) | 2(0.01%) | 6(0.10%) | 0(0.00%) | 33(0.09%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_dest_dma_stream | system_axi_ad9361_dac_dma_0_dest_axi_stream | 11(0.06%) | 11(0.06%) | 0(0.00%) | 0(0.00%) | 12(0.03%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_dest_dma_stream) | system_axi_ad9361_dac_dma_0_dest_axi_stream | 4(0.02%) | 4(0.02%) | 0(0.00%) | 0(0.00%) | 7(0.02%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_response_generator | system_axi_ad9361_dac_dma_0_response_generator | 7(0.04%) | 7(0.04%) | 0(0.00%) | 0(0.00%) | 5(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_dest_req_fifo | system_axi_ad9361_dac_dma_0_util_axis_fifo__parameterized0 | 4(0.02%) | 4(0.02%) | 0(0.00%) | 0(0.00%) | 34(0.10%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_dest_req_fifo) | system_axi_ad9361_dac_dma_0_util_axis_fifo__parameterized0 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 30(0.09%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| zerodeep.i_raddr_sync | system_axi_ad9361_dac_dma_0_sync_bits__xdcDup__1 | 2(0.01%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| zerodeep.i_waddr_sync | system_axi_ad9361_dac_dma_0_sync_bits__xdcDup__2 | 2(0.01%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_req_gen | system_axi_ad9361_dac_dma_0_request_generator | 41(0.23%) | 41(0.23%) | 0(0.00%) | 0(0.00%) | 23(0.07%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_response_manager | system_axi_ad9361_dac_dma_0_axi_dmac_response_manager | 35(0.20%) | 35(0.20%) | 0(0.00%) | 0(0.00%) | 32(0.09%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_response_manager) | system_axi_ad9361_dac_dma_0_axi_dmac_response_manager | 16(0.09%) | 16(0.09%) | 0(0.00%) | 0(0.00%) | 25(0.07%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_dest_response_fifo | system_axi_ad9361_dac_dma_0_util_axis_fifo__parameterized2 | 19(0.11%) | 19(0.11%) | 0(0.00%) | 0(0.00%) | 7(0.02%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_src_dma_mm | system_axi_ad9361_dac_dma_0_src_axi_mm | 59(0.34%) | 55(0.31%) | 4(0.07%) | 0(0.00%) | 53(0.15%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_src_dma_mm) | system_axi_ad9361_dac_dma_0_src_axi_mm | 13(0.07%) | 9(0.05%) | 4(0.07%) | 0(0.00%) | 7(0.02%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_addr_gen | system_axi_ad9361_dac_dma_0_address_generator | 45(0.26%) | 45(0.26%) | 0(0.00%) | 0(0.00%) | 44(0.13%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_req_splitter | system_axi_ad9361_dac_dma_0_splitter | 1(0.01%) | 1(0.01%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_src_req_fifo | system_axi_ad9361_dac_dma_0_util_axis_fifo__parameterized1 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 61(0.17%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_store_and_forward | system_axi_ad9361_dac_dma_0_axi_dmac_burst_memory | 33(0.19%) | 29(0.16%) | 4(0.07%) | 0(0.00%) | 48(0.14%) | 1(1.67%) | 0(0.00%) | 0(0.00%) | +| (i_store_and_forward) | system_axi_ad9361_dac_dma_0_axi_dmac_burst_memory | 25(0.14%) | 21(0.12%) | 4(0.07%) | 0(0.00%) | 32(0.09%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_dest_sync_id | system_axi_ad9361_dac_dma_0_sync_bits__parameterized2__xdcDup__1 | 4(0.02%) | 4(0.02%) | 0(0.00%) | 0(0.00%) | 8(0.02%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_mem | system_axi_ad9361_dac_dma_0_ad_mem_asym | 1(0.01%) | 1(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 1(1.67%) | 0(0.00%) | 0(0.00%) | +| i_src_sync_id | system_axi_ad9361_dac_dma_0_sync_bits__parameterized2__xdcDup__2 | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 8(0.02%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_sync_req_response_id | system_axi_ad9361_dac_dma_0_sync_bits__parameterized2 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 8(0.02%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_reset_manager | system_axi_ad9361_dac_dma_0_axi_dmac_reset_manager | 12(0.07%) | 12(0.07%) | 0(0.00%) | 0(0.00%) | 30(0.09%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_reset_manager) | system_axi_ad9361_dac_dma_0_axi_dmac_reset_manager | 9(0.05%) | 9(0.05%) | 0(0.00%) | 0(0.00%) | 26(0.07%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_sync_control_dest | system_axi_ad9361_dac_dma_0_sync_bits__xdcDup__5 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_sync_status_dest | system_axi_ad9361_dac_dma_0_sync_bits | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| axi_cpu_interconnect | system_axi_cpu_interconnect_0 | 688(3.91%) | 623(3.54%) | 0(0.00%) | 65(1.08%) | 698(1.98%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (axi_cpu_interconnect) | system_axi_cpu_interconnect_0 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| s00_couplers | s00_couplers_imp_WZLZH6 | 421(2.39%) | 356(2.02%) | 0(0.00%) | 65(1.08%) | 562(1.60%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| auto_pc | system_auto_pc_0 | 421(2.39%) | 356(2.02%) | 0(0.00%) | 65(1.08%) | 562(1.60%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (auto_pc) | system_auto_pc_0 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| inst | system_auto_pc_0_axi_protocol_converter_v2_1_27_axi_protocol_converter | 421(2.39%) | 356(2.02%) | 0(0.00%) | 65(1.08%) | 562(1.60%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (inst) | system_auto_pc_0_axi_protocol_converter_v2_1_27_axi_protocol_converter | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| gen_axilite.gen_b2s_conv.axilite_b2s | system_auto_pc_0_axi_protocol_converter_v2_1_27_b2s | 421(2.39%) | 356(2.02%) | 0(0.00%) | 65(1.08%) | 562(1.60%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (gen_axilite.gen_b2s_conv.axilite_b2s) | system_auto_pc_0_axi_protocol_converter_v2_1_27_b2s | 1(0.01%) | 1(0.01%) | 0(0.00%) | 0(0.00%) | 1(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| RD.ar_channel_0 | system_auto_pc_0_axi_protocol_converter_v2_1_27_b2s_ar_channel | 68(0.39%) | 68(0.39%) | 0(0.00%) | 0(0.00%) | 82(0.23%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| RD.r_channel_0 | system_auto_pc_0_axi_protocol_converter_v2_1_27_b2s_r_channel | 62(0.35%) | 15(0.09%) | 0(0.00%) | 47(0.78%) | 24(0.07%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| SI_REG | system_auto_pc_0_axi_register_slice_v2_1_27_axi_register_slice | 177(1.01%) | 177(1.01%) | 0(0.00%) | 0(0.00%) | 352(1.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| WR.aw_channel_0 | system_auto_pc_0_axi_protocol_converter_v2_1_27_b2s_aw_channel | 77(0.44%) | 77(0.44%) | 0(0.00%) | 0(0.00%) | 86(0.24%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| WR.b_channel_0 | system_auto_pc_0_axi_protocol_converter_v2_1_27_b2s_b_channel | 39(0.22%) | 21(0.12%) | 0(0.00%) | 18(0.30%) | 17(0.05%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| xbar | system_xbar_0 | 267(1.52%) | 267(1.52%) | 0(0.00%) | 0(0.00%) | 136(0.39%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (xbar) | system_xbar_0 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| inst | system_xbar_0_axi_crossbar_v2_1_28_axi_crossbar | 267(1.52%) | 267(1.52%) | 0(0.00%) | 0(0.00%) | 136(0.39%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (inst) | system_xbar_0_axi_crossbar_v2_1_28_axi_crossbar | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| gen_sasd.crossbar_sasd_0 | system_xbar_0_axi_crossbar_v2_1_28_crossbar_sasd | 267(1.52%) | 267(1.52%) | 0(0.00%) | 0(0.00%) | 136(0.39%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (gen_sasd.crossbar_sasd_0) | system_xbar_0_axi_crossbar_v2_1_28_crossbar_sasd | 9(0.05%) | 9(0.05%) | 0(0.00%) | 0(0.00%) | 12(0.03%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| addr_arbiter_inst | system_xbar_0_axi_crossbar_v2_1_28_addr_arbiter_sasd | 106(0.60%) | 106(0.60%) | 0(0.00%) | 0(0.00%) | 41(0.12%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| gen_decerr.decerr_slave_inst | system_xbar_0_axi_crossbar_v2_1_28_decerr_slave | 11(0.06%) | 11(0.06%) | 0(0.00%) | 0(0.00%) | 4(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| reg_slice_r | system_xbar_0_axi_register_slice_v2_1_27_axic_register_slice | 127(0.72%) | 127(0.72%) | 0(0.00%) | 0(0.00%) | 74(0.21%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| splitter_ar | system_xbar_0_axi_crossbar_v2_1_28_splitter__parameterized0 | 2(0.01%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| splitter_aw | system_xbar_0_axi_crossbar_v2_1_28_splitter | 12(0.07%) | 12(0.07%) | 0(0.00%) | 0(0.00%) | 3(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| axi_iic_main | system_axi_iic_main_0 | 402(2.28%) | 384(2.18%) | 0(0.00%) | 18(0.30%) | 374(1.06%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (axi_iic_main) | system_axi_iic_main_0 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| U0 | system_axi_iic_main_0_axi_iic | 402(2.28%) | 384(2.18%) | 0(0.00%) | 18(0.30%) | 374(1.06%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (U0) | system_axi_iic_main_0_axi_iic | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| X_IIC | system_axi_iic_main_0_iic | 402(2.28%) | 384(2.18%) | 0(0.00%) | 18(0.30%) | 374(1.06%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (X_IIC) | system_axi_iic_main_0_iic | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 4(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| DYN_MASTER_I | system_axi_iic_main_0_dynamic_master | 15(0.09%) | 15(0.09%) | 0(0.00%) | 0(0.00%) | 16(0.05%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| FILTER_I | system_axi_iic_main_0_filter | 2(0.01%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 8(0.02%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| SCL_DEBOUNCE | system_axi_iic_main_0_debounce | 1(0.01%) | 1(0.01%) | 0(0.00%) | 0(0.00%) | 4(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| INPUT_DOUBLE_REGS | system_axi_iic_main_0_cdc_sync_4 | 1(0.01%) | 1(0.01%) | 0(0.00%) | 0(0.00%) | 4(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| SDA_DEBOUNCE | system_axi_iic_main_0_debounce_3 | 1(0.01%) | 1(0.01%) | 0(0.00%) | 0(0.00%) | 4(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| INPUT_DOUBLE_REGS | system_axi_iic_main_0_cdc_sync | 1(0.01%) | 1(0.01%) | 0(0.00%) | 0(0.00%) | 4(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| IIC_CONTROL_I | system_axi_iic_main_0_iic_control | 138(0.78%) | 138(0.78%) | 0(0.00%) | 0(0.00%) | 115(0.33%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (IIC_CONTROL_I) | system_axi_iic_main_0_iic_control | 61(0.35%) | 61(0.35%) | 0(0.00%) | 0(0.00%) | 75(0.21%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| BITCNT | system_axi_iic_main_0_upcnt_n__parameterized0 | 11(0.06%) | 11(0.06%) | 0(0.00%) | 0(0.00%) | 4(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| CLKCNT | system_axi_iic_main_0_upcnt_n | 32(0.18%) | 32(0.18%) | 0(0.00%) | 0(0.00%) | 10(0.03%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| I2CDATA_REG | system_axi_iic_main_0_shift8 | 7(0.04%) | 7(0.04%) | 0(0.00%) | 0(0.00%) | 8(0.02%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| I2CHEADER_REG | system_axi_iic_main_0_shift8_1 | 16(0.09%) | 16(0.09%) | 0(0.00%) | 0(0.00%) | 8(0.02%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| SETUP_CNT | system_axi_iic_main_0_upcnt_n_2 | 11(0.06%) | 11(0.06%) | 0(0.00%) | 0(0.00%) | 10(0.03%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| READ_FIFO_I | system_axi_iic_main_0_SRL_FIFO | 16(0.09%) | 8(0.05%) | 0(0.00%) | 8(0.13%) | 5(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| REG_INTERFACE_I | system_axi_iic_main_0_reg_interface | 65(0.37%) | 65(0.37%) | 0(0.00%) | 0(0.00%) | 124(0.35%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| WRITE_FIFO_CTRL_I | system_axi_iic_main_0_SRL_FIFO__parameterized0 | 9(0.05%) | 7(0.04%) | 0(0.00%) | 2(0.03%) | 5(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| WRITE_FIFO_I | system_axi_iic_main_0_SRL_FIFO_0 | 20(0.11%) | 12(0.07%) | 0(0.00%) | 8(0.13%) | 5(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| X_AXI_IPIF_SSP1 | system_axi_iic_main_0_axi_ipif_ssp1 | 142(0.81%) | 142(0.81%) | 0(0.00%) | 0(0.00%) | 92(0.26%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (X_AXI_IPIF_SSP1) | system_axi_iic_main_0_axi_ipif_ssp1 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 4(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| AXI_LITE_IPIF_I | system_axi_iic_main_0_axi_lite_ipif | 124(0.70%) | 124(0.70%) | 0(0.00%) | 0(0.00%) | 64(0.18%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| I_SLAVE_ATTACHMENT | system_axi_iic_main_0_slave_attachment | 124(0.70%) | 124(0.70%) | 0(0.00%) | 0(0.00%) | 64(0.18%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| X_INTERRUPT_CONTROL | system_axi_iic_main_0_interrupt_control | 13(0.07%) | 13(0.07%) | 0(0.00%) | 0(0.00%) | 18(0.05%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| X_SOFT_RESET | system_axi_iic_main_0_soft_reset | 5(0.03%) | 5(0.03%) | 0(0.00%) | 0(0.00%) | 6(0.02%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| axi_spi | system_axi_spi_0 | 438(2.49%) | 422(2.40%) | 16(0.27%) | 0(0.00%) | 633(1.80%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (axi_spi) | system_axi_spi_0 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| U0 | system_axi_spi_0_axi_quad_spi | 438(2.49%) | 422(2.40%) | 16(0.27%) | 0(0.00%) | 633(1.80%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (U0) | system_axi_spi_0_axi_quad_spi | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| NO_DUAL_QUAD_MODE.QSPI_NORMAL | system_axi_spi_0_axi_quad_spi_top | 438(2.49%) | 422(2.40%) | 16(0.27%) | 0(0.00%) | 633(1.80%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (NO_DUAL_QUAD_MODE.QSPI_NORMAL) | system_axi_spi_0_axi_quad_spi_top | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| QSPI_LEGACY_MD_GEN.AXI_LITE_IPIF_I | system_axi_spi_0_axi_lite_ipif | 99(0.56%) | 99(0.56%) | 0(0.00%) | 0(0.00%) | 70(0.20%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| I_SLAVE_ATTACHMENT | system_axi_spi_0_slave_attachment | 99(0.56%) | 99(0.56%) | 0(0.00%) | 0(0.00%) | 70(0.20%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (I_SLAVE_ATTACHMENT) | system_axi_spi_0_slave_attachment | 27(0.15%) | 27(0.15%) | 0(0.00%) | 0(0.00%) | 37(0.11%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| I_DECODER | system_axi_spi_0_address_decoder | 72(0.41%) | 72(0.41%) | 0(0.00%) | 0(0.00%) | 33(0.09%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| QSPI_LEGACY_MD_GEN.QSPI_CORE_INTERFACE_I | system_axi_spi_0_qspi_core_interface | 339(1.93%) | 323(1.84%) | 16(0.27%) | 0(0.00%) | 561(1.59%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (QSPI_LEGACY_MD_GEN.QSPI_CORE_INTERFACE_I) | system_axi_spi_0_qspi_core_interface | 8(0.05%) | 8(0.05%) | 0(0.00%) | 0(0.00%) | 44(0.13%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| CONTROL_REG_I | system_axi_spi_0_qspi_cntrl_reg | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 12(0.03%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| FIFO_EXISTS.CLK_CROSS_I | system_axi_spi_0_cross_clk_sync_fifo_1 | 19(0.11%) | 19(0.11%) | 0(0.00%) | 0(0.00%) | 40(0.11%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| FIFO_EXISTS.FIFO_IF_MODULE_I | system_axi_spi_0_qspi_fifo_ifmodule | 1(0.01%) | 1(0.01%) | 0(0.00%) | 0(0.00%) | 4(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| FIFO_EXISTS.RX_FIFO_EMPTY_SYNC_AXI_2_SPI_CDC | system_axi_spi_0_cdc_sync | 1(0.01%) | 1(0.01%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| FIFO_EXISTS.RX_FIFO_FULL_SYNCED_SPI_2_AXI_CDC | system_axi_spi_0_cdc_sync_0 | 1(0.01%) | 1(0.01%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| FIFO_EXISTS.RX_FIFO_II | system_axi_spi_0_xpm_fifo_async | 112(0.64%) | 104(0.59%) | 8(0.13%) | 0(0.00%) | 172(0.49%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (FIFO_EXISTS.RX_FIFO_II) | system_axi_spi_0_xpm_fifo_async | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| gnuram_async_fifo.xpm_fifo_base_inst | system_axi_spi_0_xpm_fifo_base | 112(0.64%) | 104(0.59%) | 8(0.13%) | 0(0.00%) | 172(0.49%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| FIFO_EXISTS.TX_FIFO_EMPTY_CNTR_I | system_axi_spi_0_counter_f | 5(0.03%) | 5(0.03%) | 0(0.00%) | 0(0.00%) | 4(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| FIFO_EXISTS.TX_FIFO_II | system_axi_spi_0_async_fifo_fg | 122(0.69%) | 114(0.65%) | 8(0.13%) | 0(0.00%) | 172(0.49%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (FIFO_EXISTS.TX_FIFO_II) | system_axi_spi_0_async_fifo_fg | 9(0.05%) | 9(0.05%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| xpm_fifo_instance.xpm_fifo_async_inst | system_axi_spi_0_xpm_fifo_async__parameterized1 | 113(0.64%) | 105(0.60%) | 8(0.13%) | 0(0.00%) | 172(0.49%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| INTERRUPT_CONTROL_I | system_axi_spi_0_interrupt_control | 12(0.07%) | 12(0.07%) | 0(0.00%) | 0(0.00%) | 23(0.07%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| LOGIC_FOR_MD_0_GEN.SPI_MODULE_I | system_axi_spi_0_qspi_mode_0_module | 44(0.25%) | 44(0.25%) | 0(0.00%) | 0(0.00%) | 64(0.18%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| RESET_SYNC_AXI_SPI_CLK_INST | system_axi_spi_0_reset_sync_module | 1(0.01%) | 1(0.01%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| SOFT_RESET_I | system_axi_spi_0_soft_reset | 9(0.05%) | 9(0.05%) | 0(0.00%) | 0(0.00%) | 19(0.05%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| STATUS_REG_MODE_0_GEN.STATUS_SLAVE_SEL_REG_I | system_axi_spi_0_qspi_status_slave_sel_reg | 1(0.01%) | 1(0.01%) | 0(0.00%) | 0(0.00%) | 1(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| axi_tdd_0 | axi_tdd_0_imp_PE8F36 | 468(2.66%) | 468(2.66%) | 0(0.00%) | 0(0.00%) | 903(2.57%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (axi_tdd_0) | axi_tdd_0_imp_PE8F36 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| tdd_ch_slice_0 | system_tdd_ch_slice_0_0 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| tdd_ch_slice_2 | system_tdd_ch_slice_2_0 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| tdd_core | system_tdd_core_0 | 468(2.66%) | 468(2.66%) | 0(0.00%) | 0(0.00%) | 903(2.57%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (tdd_core) | system_tdd_core_0 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| inst | system_tdd_core_0_axi_tdd | 468(2.66%) | 468(2.66%) | 0(0.00%) | 0(0.00%) | 903(2.57%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (inst) | system_tdd_core_0_axi_tdd | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| genblk1[0].i_channel | system_tdd_core_0_axi_tdd_channel | 20(0.11%) | 20(0.11%) | 0(0.00%) | 0(0.00%) | 69(0.20%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| genblk1[1].i_channel | system_tdd_core_0_axi_tdd_channel__parameterized0 | 23(0.13%) | 23(0.13%) | 0(0.00%) | 0(0.00%) | 69(0.20%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| genblk1[2].i_channel | system_tdd_core_0_axi_tdd_channel_0 | 23(0.13%) | 23(0.13%) | 0(0.00%) | 0(0.00%) | 69(0.20%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_counter | system_tdd_core_0_axi_tdd_counter | 170(0.97%) | 170(0.97%) | 0(0.00%) | 0(0.00%) | 166(0.47%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_regmap | system_tdd_core_0_axi_tdd_regmap | 94(0.53%) | 94(0.53%) | 0(0.00%) | 0(0.00%) | 394(1.12%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_regmap) | system_tdd_core_0_axi_tdd_regmap | 85(0.48%) | 85(0.48%) | 0(0.00%) | 0(0.00%) | 364(1.03%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_tdd_ch_en_sync | system_tdd_core_0_sync_bits__parameterized1 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 6(0.02%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_tdd_control_sync | system_tdd_core_0_sync_bits | 1(0.01%) | 1(0.01%) | 0(0.00%) | 0(0.00%) | 6(0.02%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_tdd_cstate_sync | system_tdd_core_0_sync_data | 5(0.03%) | 5(0.03%) | 0(0.00%) | 0(0.00%) | 10(0.03%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_tdd_cstate_sync) | system_tdd_core_0_sync_data | 4(0.02%) | 4(0.02%) | 0(0.00%) | 0(0.00%) | 6(0.02%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_sync_in | system_tdd_core_0_sync_bits__parameterized0__xdcDup__1 | 1(0.01%) | 1(0.01%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_sync_out | system_tdd_core_0_sync_bits__parameterized0__xdcDup__2 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_tdd_soft_sync | system_tdd_core_0_sync_event | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 8(0.02%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_tdd_soft_sync) | system_tdd_core_0_sync_event | 1(0.01%) | 1(0.01%) | 0(0.00%) | 0(0.00%) | 4(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_sync_in | system_tdd_core_0_sync_bits__parameterized0__xdcDup__3 | 1(0.01%) | 1(0.01%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_sync_out | system_tdd_core_0_sync_bits__parameterized0 | 1(0.01%) | 1(0.01%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_sync_gen | system_tdd_core_0_axi_tdd_sync_gen | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 3(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_up_axi | system_tdd_core_0_up_axi | 138(0.78%) | 138(0.78%) | 0(0.00%) | 0(0.00%) | 133(0.38%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| cpack | system_cpack_0 | 109(0.62%) | 109(0.62%) | 0(0.00%) | 0(0.00%) | 132(0.38%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| inst | system_cpack_0_util_cpack2 | 109(0.62%) | 109(0.62%) | 0(0.00%) | 0(0.00%) | 132(0.38%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_cpack | system_cpack_0_util_cpack2_impl | 109(0.62%) | 109(0.62%) | 0(0.00%) | 0(0.00%) | 132(0.38%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_cpack) | system_cpack_0_util_cpack2_impl | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 66(0.19%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_pack_shell | system_cpack_0_pack_shell | 109(0.62%) | 109(0.62%) | 0(0.00%) | 0(0.00%) | 66(0.19%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_pack_shell) | system_cpack_0_pack_shell | 18(0.10%) | 18(0.10%) | 0(0.00%) | 0(0.00%) | 58(0.16%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| gen_network[0].i_ctrl_interconnect | system_cpack_0_pack_network | 91(0.52%) | 91(0.52%) | 0(0.00%) | 0(0.00%) | 8(0.02%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| logic_inv | system_logic_inv_0 | 1(0.01%) | 1(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| logic_or | system_logic_or_0 | 1(0.01%) | 1(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| logic_or_1 | system_logic_or_1_0 | 1(0.01%) | 1(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| msk_top | system_msk_top_0 | 11674(66.33%) | 11160(63.41%) | 514(8.57%) | 0(0.00%) | 13147(37.35%) | 0(0.00%) | 4(3.33%) | 20(25.00%) | +| (msk_top) | system_msk_top_0 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 2(1.67%) | 0(0.00%) | +| U0 | system_msk_top_0_msk_top | 11674(66.33%) | 11160(63.41%) | 514(8.57%) | 0(0.00%) | 13147(37.35%) | 0(0.00%) | 2(1.67%) | 20(25.00%) | +| (U0) | system_msk_top_0_msk_top | 33(0.19%) | 33(0.19%) | 0(0.00%) | 0(0.00%) | 86(0.24%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| u_async_fifo | system_msk_top_0_axis_async_fifo__1 | 365(2.07%) | 141(0.80%) | 224(3.73%) | 0(0.00%) | 127(0.36%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| u_dem | system_msk_top_0_msk_demodulator | 2215(12.59%) | 2215(12.59%) | 0(0.00%) | 0(0.00%) | 1130(3.21%) | 0(0.00%) | 0(0.00%) | 16(20.00%) | +| (u_dem) | system_msk_top_0_msk_demodulator | 65(0.37%) | 65(0.37%) | 0(0.00%) | 0(0.00%) | 82(0.23%) | 0(0.00%) | 0(0.00%) | 4(5.00%) | +| U_f1 | system_msk_top_0_costas_loop | 1068(6.07%) | 1068(6.07%) | 0(0.00%) | 0(0.00%) | 524(1.49%) | 0(0.00%) | 0(0.00%) | 6(7.50%) | +| (U_f1) | system_msk_top_0_costas_loop | 329(1.87%) | 329(1.87%) | 0(0.00%) | 0(0.00%) | 280(0.80%) | 0(0.00%) | 0(0.00%) | 2(2.50%) | +| U_carrier_nco | system_msk_top_0_nco__parameterized1_56 | 111(0.63%) | 111(0.63%) | 0(0.00%) | 0(0.00%) | 114(0.32%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| U_carrier_sin_cos_lut | system_msk_top_0_sin_cos_lut_57 | 275(1.56%) | 275(1.56%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| u_loopfilter | system_msk_top_0_pi_controller_58 | 353(2.01%) | 353(2.01%) | 0(0.00%) | 0(0.00%) | 130(0.37%) | 0(0.00%) | 0(0.00%) | 4(5.00%) | +| U_f2 | system_msk_top_0_costas_loop_55 | 1082(6.15%) | 1082(6.15%) | 0(0.00%) | 0(0.00%) | 524(1.49%) | 0(0.00%) | 0(0.00%) | 6(7.50%) | +| (U_f2) | system_msk_top_0_costas_loop_55 | 346(1.97%) | 346(1.97%) | 0(0.00%) | 0(0.00%) | 280(0.80%) | 0(0.00%) | 0(0.00%) | 2(2.50%) | +| U_carrier_nco | system_msk_top_0_nco__parameterized1 | 111(0.63%) | 111(0.63%) | 0(0.00%) | 0(0.00%) | 114(0.32%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| U_carrier_sin_cos_lut | system_msk_top_0_sin_cos_lut | 278(1.58%) | 278(1.58%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| u_loopfilter | system_msk_top_0_pi_controller | 347(1.97%) | 347(1.97%) | 0(0.00%) | 0(0.00%) | 130(0.37%) | 0(0.00%) | 0(0.00%) | 4(5.00%) | +| u_deserializer | system_msk_top_0_byte_to_bit_deserializer | 24(0.14%) | 24(0.14%) | 0(0.00%) | 0(0.00%) | 20(0.06%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| u_mod | system_msk_top_0_msk_modulator | 306(1.74%) | 306(1.74%) | 0(0.00%) | 0(0.00%) | 398(1.13%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (u_mod) | system_msk_top_0_msk_modulator | 176(1.00%) | 176(1.00%) | 0(0.00%) | 0(0.00%) | 203(0.58%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| U_f1_nco | system_msk_top_0_nco__parameterized0 | 32(0.18%) | 32(0.18%) | 0(0.00%) | 0(0.00%) | 64(0.18%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| U_f2_nco | system_msk_top_0_nco__parameterized0_54 | 32(0.18%) | 32(0.18%) | 0(0.00%) | 0(0.00%) | 64(0.18%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| U_tclk_nco | system_msk_top_0_nco | 66(0.38%) | 66(0.38%) | 0(0.00%) | 0(0.00%) | 67(0.19%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| u_msk_top_csr | system_msk_top_0_msk_top_csr | 2348(13.34%) | 2348(13.34%) | 0(0.00%) | 0(0.00%) | 1618(4.60%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (u_msk_top_csr) | system_msk_top_0_msk_top_csr | 9(0.05%) | 9(0.05%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| u01s | system_msk_top_0_cdc_resync | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| u02s | system_msk_top_0_cdc_resync_0 | 2(0.01%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| u03s | system_msk_top_0_cdc_resync_1 | 2(0.01%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| u04s | system_msk_top_0_cdc_resync_2 | 1(0.01%) | 1(0.01%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| u05s | system_msk_top_0_cdc_resync_3 | 31(0.18%) | 31(0.18%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| u06s | system_msk_top_0_cdc_resync_4 | 2(0.01%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| u07s | system_msk_top_0_cdc_resync_5 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| u09s | system_msk_top_0_cdc_resync_6 | 2(0.01%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| u10s | system_msk_top_0_cdc_resync_7 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| u11s | system_msk_top_0_cdc_resync_8 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| u12s | system_msk_top_0_cdc_resync_9 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| u13s | system_msk_top_0_cdc_resync_10 | 1(0.01%) | 1(0.01%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| u14s | system_msk_top_0_cdc_resync_11 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| u15s | system_msk_top_0_cdc_resync_12 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| u16s | system_msk_top_0_cdc_resync_13 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| u_msk_regs | system_msk_top_0_msk_top_regs | 2215(12.59%) | 2215(12.59%) | 0(0.00%) | 0(0.00%) | 1091(3.10%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| urfl_s | system_msk_top_0_cdc_resync_14 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| urxe_s | system_msk_top_0_cdc_resync_15 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utatc_a | system_msk_top_0_pulse_detect | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 3(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utatc_c | system_msk_top_0_data_capture | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 32(0.09%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utatc_r | system_msk_top_0_pulse_detect_16 | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 3(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utbc_a | system_msk_top_0_pulse_detect_17 | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 3(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utbc_c | system_msk_top_0_data_capture_18 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 32(0.09%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utbc_r | system_msk_top_0_pulse_detect_19 | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 3(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utbe_a | system_msk_top_0_pulse_detect_20 | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 3(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utbe_c | system_msk_top_0_data_capture_21 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 32(0.09%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utbe_r | system_msk_top_0_pulse_detect_22 | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 3(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utf1a_a | system_msk_top_0_pulse_detect_23 | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 3(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utf1a_c | system_msk_top_0_data_capture_24 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 32(0.09%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utf1a_r | system_msk_top_0_pulse_detect_25 | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 3(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utf1e_a | system_msk_top_0_pulse_detect_26 | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 3(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utf1e_c | system_msk_top_0_data_capture_27 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 32(0.09%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utf1e_r | system_msk_top_0_pulse_detect_28 | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 3(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utf2a_a | system_msk_top_0_pulse_detect_29 | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 3(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utf2a_c | system_msk_top_0_data_capture_30 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 32(0.09%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utf2a_r | system_msk_top_0_pulse_detect_31 | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 3(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utf2e_a | system_msk_top_0_pulse_detect_32 | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 3(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utf2e_c | system_msk_top_0_data_capture_33 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 32(0.09%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utf2e_r | system_msk_top_0_pulse_detect_34 | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 3(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utfsc_c | system_msk_top_0_data_capture__parameterized4 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 24(0.07%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utfse_c | system_msk_top_0_data_capture__parameterized6 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 6(0.02%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utfsr_a | system_msk_top_0_pulse_detect_35 | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 3(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utfsr_r | system_msk_top_0_pulse_detect_36 | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 3(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utfss_a | system_msk_top_0_pulse_detect_37 | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 3(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utfss_r | system_msk_top_0_pulse_detect_38 | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 3(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utlp1_a | system_msk_top_0_pulse_detect_39 | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 3(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utlp1_c | system_msk_top_0_data_capture_40 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 32(0.09%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utlp1_r | system_msk_top_0_pulse_detect_41 | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 3(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utlp2_a | system_msk_top_0_pulse_detect_42 | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 3(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utlp2_c | system_msk_top_0_data_capture_43 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 32(0.09%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utlp2_r | system_msk_top_0_pulse_detect_44 | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 3(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utprb_a | system_msk_top_0_pulse_detect_45 | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 3(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utprb_c | system_msk_top_0_data_capture_46 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 32(0.09%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utprb_r | system_msk_top_0_pulse_detect_47 | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 3(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utpre_a | system_msk_top_0_pulse_detect_48 | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 3(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utpre_c | system_msk_top_0_data_capture_49 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 32(0.09%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utpre_r | system_msk_top_0_pulse_detect_50 | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 3(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utpwr_a | system_msk_top_0_pulse_detect_51 | 3(0.02%) | 3(0.02%) | 0(0.00%) | 0(0.00%) | 3(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utpwr_c | system_msk_top_0_data_capture__parameterized2 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 23(0.07%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utpwr_r | system_msk_top_0_pulse_detect_52 | 2(0.01%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 3(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| utxe_s | system_msk_top_0_cdc_resync_53 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| u_ov_decoder | system_msk_top_0_ov_frame_decoder | 1395(7.93%) | 1353(7.69%) | 42(0.70%) | 0(0.00%) | 2693(7.65%) | 0(0.00%) | 1(0.83%) | 0(0.00%) | +| (u_ov_decoder) | system_msk_top_0_ov_frame_decoder | 151(0.86%) | 109(0.62%) | 42(0.70%) | 0(0.00%) | 70(0.20%) | 0(0.00%) | 1(0.83%) | 0(0.00%) | +| U_DECODER | system_msk_top_0_viterbi_decoder_k7_simple | 1244(7.07%) | 1244(7.07%) | 0(0.00%) | 0(0.00%) | 2623(7.45%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| u_ov_encoder | system_msk_top_0_ov_frame_encoder | 4419(25.11%) | 4395(24.97%) | 24(0.40%) | 0(0.00%) | 6595(18.74%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (u_ov_encoder) | system_msk_top_0_ov_frame_encoder | 1382(7.85%) | 1358(7.72%) | 24(0.40%) | 0(0.00%) | 4393(12.48%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| U_ENCODER | system_msk_top_0_conv_encoder_k7 | 3037(17.26%) | 3037(17.26%) | 0(0.00%) | 0(0.00%) | 2202(6.26%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| u_power_det | system_msk_top_0_power_detector | 57(0.32%) | 57(0.32%) | 0(0.00%) | 0(0.00%) | 41(0.12%) | 0(0.00%) | 0(0.00%) | 4(5.00%) | +| (u_power_det) | system_msk_top_0_power_detector | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 2(2.50%) | +| u_ema_1 | system_msk_top_0_lowpass_ema | 57(0.32%) | 57(0.32%) | 0(0.00%) | 0(0.00%) | 41(0.12%) | 0(0.00%) | 0(0.00%) | 2(2.50%) | +| u_prbs_gen | system_msk_top_0_prbs_gen | 2(0.01%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 34(0.10%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| u_prbs_mon | system_msk_top_0_prbs_mon | 26(0.15%) | 26(0.15%) | 0(0.00%) | 0(0.00%) | 105(0.30%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| u_rx_async_fifo | system_msk_top_0_axis_async_fifo | 365(2.07%) | 141(0.80%) | 224(3.73%) | 0(0.00%) | 127(0.36%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| u_rx_frame_sync | system_msk_top_0_frame_sync_detector | 126(0.72%) | 126(0.72%) | 0(0.00%) | 0(0.00%) | 173(0.49%) | 0(0.00%) | 1(0.83%) | 0(0.00%) | +| sys_concat_intc | system_sys_concat_intc_0 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| sys_ps7 | system_sys_ps7_0 | 46(0.26%) | 46(0.26%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (sys_ps7) | system_sys_ps7_0 | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| inst | system_sys_ps7_0_processing_system7_v5_5_processing_system7 | 46(0.26%) | 46(0.26%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| sys_rstgen | system_sys_rstgen_0 | 18(0.10%) | 17(0.10%) | 0(0.00%) | 1(0.02%) | 37(0.11%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| U0 | system_sys_rstgen_0_proc_sys_reset | 18(0.10%) | 17(0.10%) | 0(0.00%) | 1(0.02%) | 37(0.11%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (U0) | system_sys_rstgen_0_proc_sys_reset | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 5(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| EXT_LPF | system_sys_rstgen_0_lpf | 5(0.03%) | 4(0.02%) | 0(0.00%) | 1(0.02%) | 14(0.04%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (EXT_LPF) | system_sys_rstgen_0_lpf | 2(0.01%) | 1(0.01%) | 0(0.00%) | 1(0.02%) | 6(0.02%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| ACTIVE_LOW_AUX.ACT_LO_AUX | system_sys_rstgen_0_cdc_sync | 2(0.01%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 4(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| ACTIVE_LOW_EXT.ACT_LO_EXT | system_sys_rstgen_0_cdc_sync_0 | 1(0.01%) | 1(0.01%) | 0(0.00%) | 0(0.00%) | 4(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| SEQ | system_sys_rstgen_0_sequence_psr | 13(0.07%) | 13(0.07%) | 0(0.00%) | 0(0.00%) | 18(0.05%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (SEQ) | system_sys_rstgen_0_sequence_psr | 8(0.05%) | 8(0.05%) | 0(0.00%) | 0(0.00%) | 12(0.03%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| SEQ_COUNTER | system_sys_rstgen_0_upcnt_n | 5(0.03%) | 5(0.03%) | 0(0.00%) | 0(0.00%) | 6(0.02%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| tx_upack | system_tx_upack_0 | 115(0.65%) | 115(0.65%) | 0(0.00%) | 0(0.00%) | 128(0.36%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| inst | system_tx_upack_0_util_upack2 | 115(0.65%) | 115(0.65%) | 0(0.00%) | 0(0.00%) | 128(0.36%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_upack | system_tx_upack_0_util_upack2_impl | 115(0.65%) | 115(0.65%) | 0(0.00%) | 0(0.00%) | 128(0.36%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_upack) | system_tx_upack_0_util_upack2_impl | 0(0.00%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | 66(0.19%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| i_pack_shell | system_tx_upack_0_pack_shell | 115(0.65%) | 115(0.65%) | 0(0.00%) | 0(0.00%) | 62(0.18%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| (i_pack_shell) | system_tx_upack_0_pack_shell | 14(0.08%) | 14(0.08%) | 0(0.00%) | 0(0.00%) | 52(0.15%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| gen_input_buffer.i_ext_ctrl_interconnect | system_tx_upack_0_pack_network | 100(0.57%) | 100(0.57%) | 0(0.00%) | 0(0.00%) | 8(0.02%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | +| gen_network[1].i_ctrl_interconnect | system_tx_upack_0_pack_network__parameterized0 | 1(0.01%) | 1(0.01%) | 0(0.00%) | 0(0.00%) | 2(0.01%) | 0(0.00%) | 0(0.00%) | 0(0.00%) | ++-------------------------------------------------------------+------------------------------------------------------------------------+---------------+---------------+-------------+-----------+---------------+----------+----------+------------+ + + diff --git a/projects/pluto/util_hier.txt b/projects/pluto/util_hier.txt new file mode 100644 index 0000000..ca0cecc --- /dev/null +++ b/projects/pluto/util_hier.txt @@ -0,0 +1,73 @@ +Copyright 1986-2022 Xilinx, Inc. All Rights Reserved. +-------------------------------------------------------------------------------------------- +| Tool Version : Vivado v.2022.2 (lin64) Build 3671981 Fri Oct 14 04:59:54 MDT 2022 +| Date : Sun Nov 30 20:37:58 2025 +| Host : mymelody running 64-bit Ubuntu 22.04.5 LTS +| Command : report_utilization -hierarchical -hierarchical_depth 4 -file util_hier.txt +| Design : system_top +| Device : xc7z010clg225-1 +| Speed File : -1 +| Design State : Synthesized +-------------------------------------------------------------------------------------------- + +Utilization Design Information + +Table of Contents +----------------- +1. Utilization by Hierarchy + +1. Utilization by Hierarchy +--------------------------- + ++--------------------------------+-------------------------------------------------------------+------------+------------+---------+------+-------+--------+--------+------------+ +| Instance | Module | Total LUTs | Logic LUTs | LUTRAMs | SRLs | FFs | RAMB36 | RAMB18 | DSP Blocks | ++--------------------------------+-------------------------------------------------------------+------------+------------+---------+------+-------+--------+--------+------------+ +| system_top | (top) | 16980 | 16294 | 602 | 84 | 20832 | 2 | 4 | 36 | +| (system_top) | (top) | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| i_system_wrapper | system_wrapper | 16980 | 16294 | 602 | 84 | 20832 | 2 | 4 | 36 | +| (i_system_wrapper) | system_wrapper | 2 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | +| system_i | system | 16978 | 16292 | 602 | 84 | 20832 | 2 | 4 | 36 | +| (system_i) | system | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| axi_ad9361 | system_axi_ad9361_0 | 2048 | 2048 | 0 | 0 | 3301 | 0 | 0 | 16 | +| (axi_ad9361) | system_axi_ad9361_0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| inst | system_axi_ad9361_0_axi_ad9361 | 2048 | 2048 | 0 | 0 | 3301 | 0 | 0 | 16 | +| axi_ad9361_adc_dma | system_axi_ad9361_adc_dma_0 | 506 | 468 | 38 | 0 | 787 | 1 | 0 | 0 | +| (axi_ad9361_adc_dma) | system_axi_ad9361_adc_dma_0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| inst | system_axi_ad9361_adc_dma_0_axi_dmac | 506 | 468 | 38 | 0 | 787 | 1 | 0 | 0 | +| axi_ad9361_dac_dma | system_axi_ad9361_dac_dma_0 | 463 | 429 | 34 | 0 | 692 | 1 | 0 | 0 | +| (axi_ad9361_dac_dma) | system_axi_ad9361_dac_dma_0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| inst | system_axi_ad9361_dac_dma_0_axi_dmac | 463 | 429 | 34 | 0 | 692 | 1 | 0 | 0 | +| axi_cpu_interconnect | system_axi_cpu_interconnect_0 | 688 | 623 | 0 | 65 | 698 | 0 | 0 | 0 | +| (axi_cpu_interconnect) | system_axi_cpu_interconnect_0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| s00_couplers | s00_couplers_imp_WZLZH6 | 421 | 356 | 0 | 65 | 562 | 0 | 0 | 0 | +| xbar | system_xbar_0 | 267 | 267 | 0 | 0 | 136 | 0 | 0 | 0 | +| axi_iic_main | system_axi_iic_main_0 | 402 | 384 | 0 | 18 | 374 | 0 | 0 | 0 | +| (axi_iic_main) | system_axi_iic_main_0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| U0 | system_axi_iic_main_0_axi_iic | 402 | 384 | 0 | 18 | 374 | 0 | 0 | 0 | +| axi_spi | system_axi_spi_0 | 438 | 422 | 16 | 0 | 633 | 0 | 0 | 0 | +| (axi_spi) | system_axi_spi_0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| U0 | system_axi_spi_0_axi_quad_spi | 438 | 422 | 16 | 0 | 633 | 0 | 0 | 0 | +| axi_tdd_0 | axi_tdd_0_imp_PE8F36 | 468 | 468 | 0 | 0 | 903 | 0 | 0 | 0 | +| (axi_tdd_0) | axi_tdd_0_imp_PE8F36 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| tdd_ch_slice_0 | system_tdd_ch_slice_0_0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| tdd_ch_slice_2 | system_tdd_ch_slice_2_0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| tdd_core | system_tdd_core_0 | 468 | 468 | 0 | 0 | 903 | 0 | 0 | 0 | +| cpack | system_cpack_0 | 109 | 109 | 0 | 0 | 132 | 0 | 0 | 0 | +| inst | system_cpack_0_util_cpack2 | 109 | 109 | 0 | 0 | 132 | 0 | 0 | 0 | +| logic_inv | system_logic_inv_0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | +| logic_or | system_logic_or_0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | +| logic_or_1 | system_logic_or_1_0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | +| msk_top | system_msk_top_0 | 11674 | 11160 | 514 | 0 | 13147 | 0 | 4 | 20 | +| (msk_top) | system_msk_top_0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | +| U0 | system_msk_top_0_msk_top | 11674 | 11160 | 514 | 0 | 13147 | 0 | 2 | 20 | +| sys_concat_intc | system_sys_concat_intc_0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| sys_ps7 | system_sys_ps7_0 | 46 | 46 | 0 | 0 | 0 | 0 | 0 | 0 | +| (sys_ps7) | system_sys_ps7_0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| inst | system_sys_ps7_0_processing_system7_v5_5_processing_system7 | 46 | 46 | 0 | 0 | 0 | 0 | 0 | 0 | +| sys_rstgen | system_sys_rstgen_0 | 18 | 17 | 0 | 1 | 37 | 0 | 0 | 0 | +| U0 | system_sys_rstgen_0_proc_sys_reset | 18 | 17 | 0 | 1 | 37 | 0 | 0 | 0 | +| tx_upack | system_tx_upack_0 | 115 | 115 | 0 | 0 | 128 | 0 | 0 | 0 | +| inst | system_tx_upack_0_util_upack2 | 115 | 115 | 0 | 0 | 128 | 0 | 0 | 0 | ++--------------------------------+-------------------------------------------------------------+------------+------------+---------+------+-------+--------+--------+------------+ + + diff --git a/projects/pluto/util_msk.txt b/projects/pluto/util_msk.txt new file mode 100644 index 0000000..10cb7eb --- /dev/null +++ b/projects/pluto/util_msk.txt @@ -0,0 +1,190 @@ +Copyright 1986-2022 Xilinx, Inc. All Rights Reserved. +---------------------------------------------------------------------------------------------------------------- +| Tool Version : Vivado v.2022.2 (lin64) Build 3671981 Fri Oct 14 04:59:54 MDT 2022 +| Date : Sun Nov 30 20:41:18 2025 +| Host : mymelody running 64-bit Ubuntu 22.04.5 LTS +| Command : report_utilization -cells [get_cells -hierarchical *msk_top*] -hierarchical -file util_msk.txt +| Design : system_top +| Device : xc7z010clg225-1 +| Speed File : -1 +| Design State : Synthesized +---------------------------------------------------------------------------------------------------------------- + +Utilization Design Information + +Table of Contents +----------------- +1. Utilization by Hierarchy + +1. Utilization by Hierarchy +--------------------------- + ++---------------------------------+-----------------------------------------------+------------+------------+---------+------+-------+--------+--------+------------+ +| Instance | Module | Total LUTs | Logic LUTs | LUTRAMs | SRLs | FFs | RAMB36 | RAMB18 | DSP Blocks | ++---------------------------------+-----------------------------------------------+------------+------------+---------+------+-------+--------+--------+------------+ +| msk_top | system_msk_top_0 | 13507 | 12993 | 514 | 0 | 14765 | 0 | 4 | 20 | +| msk_top | system_msk_top_0 | 11674 | 11160 | 514 | 0 | 13147 | 0 | 4 | 20 | +| (msk_top) | system_msk_top_0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | +| U0 | system_msk_top_0_msk_top | 11674 | 11160 | 514 | 0 | 13147 | 0 | 2 | 20 | +| (U0) | system_msk_top_0_msk_top | 33 | 33 | 0 | 0 | 86 | 0 | 0 | 0 | +| u_async_fifo | system_msk_top_0_axis_async_fifo__1 | 365 | 141 | 224 | 0 | 127 | 0 | 0 | 0 | +| u_dem | system_msk_top_0_msk_demodulator | 2215 | 2215 | 0 | 0 | 1130 | 0 | 0 | 16 | +| (u_dem) | system_msk_top_0_msk_demodulator | 65 | 65 | 0 | 0 | 82 | 0 | 0 | 4 | +| U_f1 | system_msk_top_0_costas_loop | 1068 | 1068 | 0 | 0 | 524 | 0 | 0 | 6 | +| (U_f1) | system_msk_top_0_costas_loop | 329 | 329 | 0 | 0 | 280 | 0 | 0 | 2 | +| U_carrier_nco | system_msk_top_0_nco__parameterized1_56 | 111 | 111 | 0 | 0 | 114 | 0 | 0 | 0 | +| U_carrier_sin_cos_lut | system_msk_top_0_sin_cos_lut_57 | 275 | 275 | 0 | 0 | 0 | 0 | 0 | 0 | +| u_loopfilter | system_msk_top_0_pi_controller_58 | 353 | 353 | 0 | 0 | 130 | 0 | 0 | 4 | +| U_f2 | system_msk_top_0_costas_loop_55 | 1082 | 1082 | 0 | 0 | 524 | 0 | 0 | 6 | +| (U_f2) | system_msk_top_0_costas_loop_55 | 346 | 346 | 0 | 0 | 280 | 0 | 0 | 2 | +| U_carrier_nco | system_msk_top_0_nco__parameterized1 | 111 | 111 | 0 | 0 | 114 | 0 | 0 | 0 | +| U_carrier_sin_cos_lut | system_msk_top_0_sin_cos_lut | 278 | 278 | 0 | 0 | 0 | 0 | 0 | 0 | +| u_loopfilter | system_msk_top_0_pi_controller | 347 | 347 | 0 | 0 | 130 | 0 | 0 | 4 | +| u_deserializer | system_msk_top_0_byte_to_bit_deserializer | 24 | 24 | 0 | 0 | 20 | 0 | 0 | 0 | +| u_mod | system_msk_top_0_msk_modulator | 306 | 306 | 0 | 0 | 398 | 0 | 0 | 0 | +| (u_mod) | system_msk_top_0_msk_modulator | 176 | 176 | 0 | 0 | 203 | 0 | 0 | 0 | +| U_f1_nco | system_msk_top_0_nco__parameterized0 | 32 | 32 | 0 | 0 | 64 | 0 | 0 | 0 | +| U_f2_nco | system_msk_top_0_nco__parameterized0_54 | 32 | 32 | 0 | 0 | 64 | 0 | 0 | 0 | +| U_tclk_nco | system_msk_top_0_nco | 66 | 66 | 0 | 0 | 67 | 0 | 0 | 0 | +| u_msk_top_csr | system_msk_top_0_msk_top_csr | 2348 | 2348 | 0 | 0 | 1618 | 0 | 0 | 0 | +| (u_msk_top_csr) | system_msk_top_0_msk_top_csr | 9 | 9 | 0 | 0 | 2 | 0 | 0 | 0 | +| u01s | system_msk_top_0_cdc_resync | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| u02s | system_msk_top_0_cdc_resync_0 | 2 | 2 | 0 | 0 | 2 | 0 | 0 | 0 | +| u03s | system_msk_top_0_cdc_resync_1 | 2 | 2 | 0 | 0 | 2 | 0 | 0 | 0 | +| u04s | system_msk_top_0_cdc_resync_2 | 1 | 1 | 0 | 0 | 2 | 0 | 0 | 0 | +| u05s | system_msk_top_0_cdc_resync_3 | 31 | 31 | 0 | 0 | 2 | 0 | 0 | 0 | +| u06s | system_msk_top_0_cdc_resync_4 | 2 | 2 | 0 | 0 | 2 | 0 | 0 | 0 | +| u07s | system_msk_top_0_cdc_resync_5 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| u09s | system_msk_top_0_cdc_resync_6 | 2 | 2 | 0 | 0 | 2 | 0 | 0 | 0 | +| u10s | system_msk_top_0_cdc_resync_7 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| u11s | system_msk_top_0_cdc_resync_8 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| u12s | system_msk_top_0_cdc_resync_9 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| u13s | system_msk_top_0_cdc_resync_10 | 1 | 1 | 0 | 0 | 2 | 0 | 0 | 0 | +| u14s | system_msk_top_0_cdc_resync_11 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| u15s | system_msk_top_0_cdc_resync_12 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| u16s | system_msk_top_0_cdc_resync_13 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| u_msk_regs | system_msk_top_0_msk_top_regs | 2215 | 2215 | 0 | 0 | 1091 | 0 | 0 | 0 | +| urfl_s | system_msk_top_0_cdc_resync_14 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| urxe_s | system_msk_top_0_cdc_resync_15 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| utatc_a | system_msk_top_0_pulse_detect | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utatc_c | system_msk_top_0_data_capture | 0 | 0 | 0 | 0 | 32 | 0 | 0 | 0 | +| utatc_r | system_msk_top_0_pulse_detect_16 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utbc_a | system_msk_top_0_pulse_detect_17 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utbc_c | system_msk_top_0_data_capture_18 | 0 | 0 | 0 | 0 | 32 | 0 | 0 | 0 | +| utbc_r | system_msk_top_0_pulse_detect_19 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utbe_a | system_msk_top_0_pulse_detect_20 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utbe_c | system_msk_top_0_data_capture_21 | 0 | 0 | 0 | 0 | 32 | 0 | 0 | 0 | +| utbe_r | system_msk_top_0_pulse_detect_22 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utf1a_a | system_msk_top_0_pulse_detect_23 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utf1a_c | system_msk_top_0_data_capture_24 | 0 | 0 | 0 | 0 | 32 | 0 | 0 | 0 | +| utf1a_r | system_msk_top_0_pulse_detect_25 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utf1e_a | system_msk_top_0_pulse_detect_26 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utf1e_c | system_msk_top_0_data_capture_27 | 0 | 0 | 0 | 0 | 32 | 0 | 0 | 0 | +| utf1e_r | system_msk_top_0_pulse_detect_28 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utf2a_a | system_msk_top_0_pulse_detect_29 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utf2a_c | system_msk_top_0_data_capture_30 | 0 | 0 | 0 | 0 | 32 | 0 | 0 | 0 | +| utf2a_r | system_msk_top_0_pulse_detect_31 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utf2e_a | system_msk_top_0_pulse_detect_32 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utf2e_c | system_msk_top_0_data_capture_33 | 0 | 0 | 0 | 0 | 32 | 0 | 0 | 0 | +| utf2e_r | system_msk_top_0_pulse_detect_34 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utfsc_c | system_msk_top_0_data_capture__parameterized4 | 0 | 0 | 0 | 0 | 24 | 0 | 0 | 0 | +| utfse_c | system_msk_top_0_data_capture__parameterized6 | 0 | 0 | 0 | 0 | 6 | 0 | 0 | 0 | +| utfsr_a | system_msk_top_0_pulse_detect_35 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utfsr_r | system_msk_top_0_pulse_detect_36 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utfss_a | system_msk_top_0_pulse_detect_37 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utfss_r | system_msk_top_0_pulse_detect_38 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utlp1_a | system_msk_top_0_pulse_detect_39 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utlp1_c | system_msk_top_0_data_capture_40 | 0 | 0 | 0 | 0 | 32 | 0 | 0 | 0 | +| utlp1_r | system_msk_top_0_pulse_detect_41 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utlp2_a | system_msk_top_0_pulse_detect_42 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utlp2_c | system_msk_top_0_data_capture_43 | 0 | 0 | 0 | 0 | 32 | 0 | 0 | 0 | +| utlp2_r | system_msk_top_0_pulse_detect_44 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utprb_a | system_msk_top_0_pulse_detect_45 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utprb_c | system_msk_top_0_data_capture_46 | 0 | 0 | 0 | 0 | 32 | 0 | 0 | 0 | +| utprb_r | system_msk_top_0_pulse_detect_47 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utpre_a | system_msk_top_0_pulse_detect_48 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utpre_c | system_msk_top_0_data_capture_49 | 0 | 0 | 0 | 0 | 32 | 0 | 0 | 0 | +| utpre_r | system_msk_top_0_pulse_detect_50 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utpwr_a | system_msk_top_0_pulse_detect_51 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utpwr_c | system_msk_top_0_data_capture__parameterized2 | 0 | 0 | 0 | 0 | 23 | 0 | 0 | 0 | +| utpwr_r | system_msk_top_0_pulse_detect_52 | 2 | 2 | 0 | 0 | 3 | 0 | 0 | 0 | +| utxe_s | system_msk_top_0_cdc_resync_53 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| u_ov_decoder | system_msk_top_0_ov_frame_decoder | 1395 | 1353 | 42 | 0 | 2693 | 0 | 1 | 0 | +| (u_ov_decoder) | system_msk_top_0_ov_frame_decoder | 151 | 109 | 42 | 0 | 70 | 0 | 1 | 0 | +| U_DECODER | system_msk_top_0_viterbi_decoder_k7_simple | 1244 | 1244 | 0 | 0 | 2623 | 0 | 0 | 0 | +| u_ov_encoder | system_msk_top_0_ov_frame_encoder | 4419 | 4395 | 24 | 0 | 6595 | 0 | 0 | 0 | +| (u_ov_encoder) | system_msk_top_0_ov_frame_encoder | 1382 | 1358 | 24 | 0 | 4393 | 0 | 0 | 0 | +| U_ENCODER | system_msk_top_0_conv_encoder_k7 | 3037 | 3037 | 0 | 0 | 2202 | 0 | 0 | 0 | +| u_power_det | system_msk_top_0_power_detector | 57 | 57 | 0 | 0 | 41 | 0 | 0 | 4 | +| (u_power_det) | system_msk_top_0_power_detector | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | +| u_ema_1 | system_msk_top_0_lowpass_ema | 57 | 57 | 0 | 0 | 41 | 0 | 0 | 2 | +| u_prbs_gen | system_msk_top_0_prbs_gen | 2 | 2 | 0 | 0 | 34 | 0 | 0 | 0 | +| u_prbs_mon | system_msk_top_0_prbs_mon | 26 | 26 | 0 | 0 | 105 | 0 | 0 | 0 | +| u_rx_async_fifo | system_msk_top_0_axis_async_fifo | 365 | 141 | 224 | 0 | 127 | 0 | 0 | 0 | +| u_rx_frame_sync | system_msk_top_0_frame_sync_detector | 126 | 126 | 0 | 0 | 173 | 0 | 1 | 0 | +| u_msk_top_csr | system_msk_top_0_msk_top_csr | 2348 | 2348 | 0 | 0 | 1618 | 0 | 0 | 0 | +| (u_msk_top_csr) | system_msk_top_0_msk_top_csr | 9 | 9 | 0 | 0 | 2 | 0 | 0 | 0 | +| u01s | system_msk_top_0_cdc_resync | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| u02s | system_msk_top_0_cdc_resync_0 | 2 | 2 | 0 | 0 | 2 | 0 | 0 | 0 | +| u03s | system_msk_top_0_cdc_resync_1 | 2 | 2 | 0 | 0 | 2 | 0 | 0 | 0 | +| u04s | system_msk_top_0_cdc_resync_2 | 1 | 1 | 0 | 0 | 2 | 0 | 0 | 0 | +| u05s | system_msk_top_0_cdc_resync_3 | 31 | 31 | 0 | 0 | 2 | 0 | 0 | 0 | +| u06s | system_msk_top_0_cdc_resync_4 | 2 | 2 | 0 | 0 | 2 | 0 | 0 | 0 | +| u07s | system_msk_top_0_cdc_resync_5 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| u09s | system_msk_top_0_cdc_resync_6 | 2 | 2 | 0 | 0 | 2 | 0 | 0 | 0 | +| u10s | system_msk_top_0_cdc_resync_7 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| u11s | system_msk_top_0_cdc_resync_8 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| u12s | system_msk_top_0_cdc_resync_9 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| u13s | system_msk_top_0_cdc_resync_10 | 1 | 1 | 0 | 0 | 2 | 0 | 0 | 0 | +| u14s | system_msk_top_0_cdc_resync_11 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| u15s | system_msk_top_0_cdc_resync_12 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| u16s | system_msk_top_0_cdc_resync_13 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| u_msk_regs | system_msk_top_0_msk_top_regs | 2215 | 2215 | 0 | 0 | 1091 | 0 | 0 | 0 | +| urfl_s | system_msk_top_0_cdc_resync_14 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| urxe_s | system_msk_top_0_cdc_resync_15 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | +| utatc_a | system_msk_top_0_pulse_detect | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utatc_c | system_msk_top_0_data_capture | 0 | 0 | 0 | 0 | 32 | 0 | 0 | 0 | +| utatc_r | system_msk_top_0_pulse_detect_16 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utbc_a | system_msk_top_0_pulse_detect_17 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utbc_c | system_msk_top_0_data_capture_18 | 0 | 0 | 0 | 0 | 32 | 0 | 0 | 0 | +| utbc_r | system_msk_top_0_pulse_detect_19 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utbe_a | system_msk_top_0_pulse_detect_20 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utbe_c | system_msk_top_0_data_capture_21 | 0 | 0 | 0 | 0 | 32 | 0 | 0 | 0 | +| utbe_r | system_msk_top_0_pulse_detect_22 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utf1a_a | system_msk_top_0_pulse_detect_23 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utf1a_c | system_msk_top_0_data_capture_24 | 0 | 0 | 0 | 0 | 32 | 0 | 0 | 0 | +| utf1a_r | system_msk_top_0_pulse_detect_25 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utf1e_a | system_msk_top_0_pulse_detect_26 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utf1e_c | system_msk_top_0_data_capture_27 | 0 | 0 | 0 | 0 | 32 | 0 | 0 | 0 | +| utf1e_r | system_msk_top_0_pulse_detect_28 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utf2a_a | system_msk_top_0_pulse_detect_29 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utf2a_c | system_msk_top_0_data_capture_30 | 0 | 0 | 0 | 0 | 32 | 0 | 0 | 0 | +| utf2a_r | system_msk_top_0_pulse_detect_31 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utf2e_a | system_msk_top_0_pulse_detect_32 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utf2e_c | system_msk_top_0_data_capture_33 | 0 | 0 | 0 | 0 | 32 | 0 | 0 | 0 | +| utf2e_r | system_msk_top_0_pulse_detect_34 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utfsc_c | system_msk_top_0_data_capture__parameterized4 | 0 | 0 | 0 | 0 | 24 | 0 | 0 | 0 | +| utfse_c | system_msk_top_0_data_capture__parameterized6 | 0 | 0 | 0 | 0 | 6 | 0 | 0 | 0 | +| utfsr_a | system_msk_top_0_pulse_detect_35 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utfsr_r | system_msk_top_0_pulse_detect_36 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utfss_a | system_msk_top_0_pulse_detect_37 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utfss_r | system_msk_top_0_pulse_detect_38 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utlp1_a | system_msk_top_0_pulse_detect_39 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utlp1_c | system_msk_top_0_data_capture_40 | 0 | 0 | 0 | 0 | 32 | 0 | 0 | 0 | +| utlp1_r | system_msk_top_0_pulse_detect_41 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utlp2_a | system_msk_top_0_pulse_detect_42 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utlp2_c | system_msk_top_0_data_capture_43 | 0 | 0 | 0 | 0 | 32 | 0 | 0 | 0 | +| utlp2_r | system_msk_top_0_pulse_detect_44 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utprb_a | system_msk_top_0_pulse_detect_45 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utprb_c | system_msk_top_0_data_capture_46 | 0 | 0 | 0 | 0 | 32 | 0 | 0 | 0 | +| utprb_r | system_msk_top_0_pulse_detect_47 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utpre_a | system_msk_top_0_pulse_detect_48 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utpre_c | system_msk_top_0_data_capture_49 | 0 | 0 | 0 | 0 | 32 | 0 | 0 | 0 | +| utpre_r | system_msk_top_0_pulse_detect_50 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utpwr_a | system_msk_top_0_pulse_detect_51 | 3 | 3 | 0 | 0 | 3 | 0 | 0 | 0 | +| utpwr_c | system_msk_top_0_data_capture__parameterized2 | 0 | 0 | 0 | 0 | 23 | 0 | 0 | 0 | +| utpwr_r | system_msk_top_0_pulse_detect_52 | 2 | 2 | 0 | 0 | 3 | 0 | 0 | 0 | +| utxe_s | system_msk_top_0_cdc_resync_53 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | ++---------------------------------+-----------------------------------------------+------------+------------+---------+------+-------+--------+--------+------------+ + + diff --git a/rdl/Makefile b/rdl/Makefile index c9f51ae..7f5ea16 100644 --- a/rdl/Makefile +++ b/rdl/Makefile @@ -1,21 +1,51 @@ -all: msk_top_regs.pdf msk_top_regs.h msk_top_regs_desy.rdl gen_files_cocotb.txt gen_files_vhdl.txt +#all: msk_top_regs.pdf msk_top_regs.h msk_top_regs_desy.rdl gen_files_cocotb.txt gen_files_vhdl.txt -gen_files_cocotb.txt : msk_top_regs_desy.rdl - desyrdl -i msk_top_regs_desy.rdl -f cocotb +SRCS = src/regblock_udps.rdl src/msk_top_regs.rdl -gen_files_vhdl.txt : msk_top_regs_desy.rdl - desyrdl -i msk_top_regs_desy.rdl -f vhdl +OUTDOCS = outputs/docs +OUTRTL = outputs/rtl +OUTPYTHON = outputs/python +OUTCHEADER = outputs/c-header -msk_top_regs_desy.rdl : msk_top_regs.rdl msk_top_regs.pl - rm msk_top_regs_desy.rdl - ./msk_top_regs.pl msk_top_regs.rdl > msk_top_regs_desy.rdl +all: $(OUTDOCS)/msk_top_regs.pdf \ + $(OUTDOCS)/msk_top_regs.md \ + $(OUTDOCS)/html/index.html \ + $(OUTDOCS)/msk_top_regs.docx \ + $(OUTRTL)/msk_top_regs.vhd \ + $(OUTPYTHON)/__init__.py \ + $(OUTCHEADER)/msk_top_regs.h -msk_top_regs.md: msk_top_regs.rdl - peakrdl markdown msk_top_regs.rdl -o msk_top_regs.md +$(OUTDOCS)/msk_top_regs.md: $(SRCS) + peakrdl markdown $(SRCS) -o $(OUTDOCS)/msk_top_regs.md -msk_top_regs.h: msk_top_regs.rdl - peakrdl c-header msk_top_regs.rdl -o msk_top_regs.h +$(OUTDOCS)/msk_top_regs.docx: $(SRCS) + peakrdl docx $(SRCS) -o $(OUTDOCS)/msk_top_regs.docx --title "MSK Modem Registers" -msk_top_regs.pdf: msk_top_regs.md - pandoc -o msk_top_regs.pdf msk_top_regs.md +$(OUTDOCS)/html/index.html: $(SRCS) + peakrdl html $(SRCS) -o $(OUTDOCS)/html + +$(OUTCHEADER)/msk_top_regs.h: $(SRCS) + peakrdl c-header $(SRCS) -o outputs/c-header/msk_top_regs.h + +$(OUTRTL)/msk_top_regs.vhd: $(SRCS) + peakrdl regblock-vhdl $(SRCS) -o $(OUTRTL) --cpuif axi4-lite + @echo "Converting VHDL-2019 to VHDL-2008 for XSim compatibility..." + perl -i -pe 's/^context ieee\.ieee_std_context;$$/use ieee.std_logic_1164.all;\nuse ieee.numeric_std.all;/' \ + outputs/rtl/msk_top_regs.vhd \ + src/axi4lite_intf_pkg.vhd \ + src/reg_utils.vhd + @echo "Conversion complete!" + + +$(OUTDOCS)/msk_top_regs.pdf: $(OUTDOCS)/msk_top_regs.md + pandoc -o $(OUTDOCS)/msk_top_regs.pdf $(OUTDOCS)/msk_top_regs.md + +$(OUTPYTHON)/__init__.py: $(SRCS) + peakrdl python $(SRCS) --async -o $(OUTPYTHON) + +clean: + rm -rf outputs/docs/* + rm -f outputs/c-header/* + rm -rf outputs/python/* + rm -f outputs/rtl/* diff --git a/rdl/cocotb/desyrdl/addrmap_ch0.py b/rdl/cocotb/desyrdl/addrmap_ch0.py deleted file mode 100644 index 300f4d6..0000000 --- a/rdl/cocotb/desyrdl/addrmap_ch0.py +++ /dev/null @@ -1,117 +0,0 @@ - -import numpy as np -import logging - -logging.basicConfig(level=logging.NOTSET) -logger = logging.getLogger() -logger.setLevel(logging.INFO) - - - -class AddrmapItem (): - def __init__(self, name, bus, address, size, bits, fixp, signed, access): - self.name = name - self.bus = bus - self.address = address - self.size = size - self.bits = bits - self.fixp = fixp - self.access = access - self.scaling = 1; - if fixp == "IEEE754": - self.dtype = np.float32 - elif fixp == 0 and signed == 0: - self.dtype = np.uint32 - elif fixp == 0 and signed == 1: - self.dtype = np.int32 - else: - self.scaling = 1/pow(2, fixp) - self.dtype = np.float32 - - async def read(self, count, offset): - data = await self.bus.read_dwords(self.address+offset*4, count) - return np.array(data * self.scaling, dtype=self.dtype) - - async def read_raw(self, count, offset): - data = await self.bus.read_dwords(self.address+offset*4, count) - return np.array(data, dtype=np.uint32) - - async def write(self, value, offset): - val_np = np.array(value) - if val_np.size > 1: - data = np.uint32(np.round(val_np / self.scaling)).tolist() - else: - data = [] - data.append(np.uint32(np.round(val_np / self.scaling)).tolist()) - await self.bus.write_dwords(self.address+offset*4, data) - - async def write_raw(self, value, offset): - val_np = np.array(value) - if val_np.size > 1: - data = np.uint32(np.round(val_np)).tolist() - else: - data = [] - data.append(np.uint32(np.round(val_np)).tolist()) - await self.bus.write_dwords(self.address+offset*4, data) - -class Addrmap: - def __init__(self, bus): - self.addrmap ={} - self.addrmap['msk_top_regs.Hash_ID_Low'] = AddrmapItem("msk_top_regs.Hash_ID_Low", bus, 0, 4, 32, 0, 0, "RO") - self.addrmap['msk_top_regs.Hash_ID_High'] = AddrmapItem("msk_top_regs.Hash_ID_High", bus, 4, 4, 32, 0, 0, "RO") - self.addrmap['msk_top_regs.MSK_Init'] = AddrmapItem("msk_top_regs.MSK_Init", bus, 8, 4, 3, 0, 0, "RW") - self.addrmap['msk_top_regs.MSK_Control'] = AddrmapItem("msk_top_regs.MSK_Control", bus, 12, 4, 5, 0, 0, "RW") - self.addrmap['msk_top_regs.MSK_Status'] = AddrmapItem("msk_top_regs.MSK_Status", bus, 16, 4, 4, 0, 0, "RO") - self.addrmap['msk_top_regs.Tx_Bit_Count'] = AddrmapItem("msk_top_regs.Tx_Bit_Count", bus, 20, 4, 32, 0, 0, "RO") - self.addrmap['msk_top_regs.Tx_Enable_Count'] = AddrmapItem("msk_top_regs.Tx_Enable_Count", bus, 24, 4, 32, 0, 0, "RO") - self.addrmap['msk_top_regs.Fb_FreqWord'] = AddrmapItem("msk_top_regs.Fb_FreqWord", bus, 28, 4, 32, 0, 0, "RW") - self.addrmap['msk_top_regs.TX_F1_FreqWord'] = AddrmapItem("msk_top_regs.TX_F1_FreqWord", bus, 32, 4, 32, 0, 0, "RW") - self.addrmap['msk_top_regs.TX_F2_FreqWord'] = AddrmapItem("msk_top_regs.TX_F2_FreqWord", bus, 36, 4, 32, 0, 0, "RW") - self.addrmap['msk_top_regs.RX_F1_FreqWord'] = AddrmapItem("msk_top_regs.RX_F1_FreqWord", bus, 40, 4, 32, 0, 0, "RW") - self.addrmap['msk_top_regs.RX_F2_FreqWord'] = AddrmapItem("msk_top_regs.RX_F2_FreqWord", bus, 44, 4, 32, 0, 0, "RW") - self.addrmap['msk_top_regs.LPF_Config_0'] = AddrmapItem("msk_top_regs.LPF_Config_0", bus, 48, 4, 32, 0, 0, "RW") - self.addrmap['msk_top_regs.LPF_Config_1'] = AddrmapItem("msk_top_regs.LPF_Config_1", bus, 52, 4, 32, 0, 0, "RW") - self.addrmap['msk_top_regs.Tx_Data_Width'] = AddrmapItem("msk_top_regs.Tx_Data_Width", bus, 56, 4, 8, 0, 0, "RW") - self.addrmap['msk_top_regs.Rx_Data_Width'] = AddrmapItem("msk_top_regs.Rx_Data_Width", bus, 60, 4, 8, 0, 0, "RW") - self.addrmap['msk_top_regs.PRBS_Control'] = AddrmapItem("msk_top_regs.PRBS_Control", bus, 64, 4, 32, 0, 0, "RW") - self.addrmap['msk_top_regs.PRBS_Initial_State'] = AddrmapItem("msk_top_regs.PRBS_Initial_State", bus, 68, 4, 32, 0, 0, "RW") - self.addrmap['msk_top_regs.PRBS_Polynomial'] = AddrmapItem("msk_top_regs.PRBS_Polynomial", bus, 72, 4, 32, 0, 0, "RW") - self.addrmap['msk_top_regs.PRBS_Error_Mask'] = AddrmapItem("msk_top_regs.PRBS_Error_Mask", bus, 76, 4, 32, 0, 0, "RW") - self.addrmap['msk_top_regs.PRBS_Bit_Count'] = AddrmapItem("msk_top_regs.PRBS_Bit_Count", bus, 80, 4, 32, 0, 0, "RO") - self.addrmap['msk_top_regs.PRBS_Error_Count'] = AddrmapItem("msk_top_regs.PRBS_Error_Count", bus, 84, 4, 32, 0, 0, "RO") - self.addrmap['msk_top_regs.LPF_Accum_F1'] = AddrmapItem("msk_top_regs.LPF_Accum_F1", bus, 88, 4, 32, 0, 0, "RO") - self.addrmap['msk_top_regs.LPF_Accum_F2'] = AddrmapItem("msk_top_regs.LPF_Accum_F2", bus, 92, 4, 32, 0, 0, "RO") - self.addrmap['msk_top_regs.axis_xfer_count'] = AddrmapItem("msk_top_regs.axis_xfer_count", bus, 96, 4, 32, 0, 0, "RO") - self.addrmap['msk_top_regs.Rx_Sample_Discard'] = AddrmapItem("msk_top_regs.Rx_Sample_Discard", bus, 100, 4, 16, 0, 0, "RW") - self.addrmap['msk_top_regs.LPF_Config_2'] = AddrmapItem("msk_top_regs.LPF_Config_2", bus, 104, 4, 32, 0, 0, "RW") - self.addrmap['msk_top_regs.f1_nco_adjust'] = AddrmapItem("msk_top_regs.f1_nco_adjust", bus, 108, 4, 32, 0, 0, "RO") - self.addrmap['msk_top_regs.f2_nco_adjust'] = AddrmapItem("msk_top_regs.f2_nco_adjust", bus, 112, 4, 32, 0, 0, "RO") - self.addrmap['msk_top_regs.f1_error'] = AddrmapItem("msk_top_regs.f1_error", bus, 116, 4, 32, 0, 0, "RO") - self.addrmap['msk_top_regs.f2_error'] = AddrmapItem("msk_top_regs.f2_error", bus, 120, 4, 32, 0, 0, "RO") - self.addrmap['msk_top_regs.Tx_Sync_Ctrl'] = AddrmapItem("msk_top_regs.Tx_Sync_Ctrl", bus, 124, 4, 4, 0, 0, "RW") - self.addrmap['msk_top_regs.Tx_Sync_Cnt'] = AddrmapItem("msk_top_regs.Tx_Sync_Cnt", bus, 128, 4, 24, 0, 0, "RW") - self.addrmap['msk_top_regs.lowpass_ema_alpha1'] = AddrmapItem("msk_top_regs.lowpass_ema_alpha1", bus, 132, 4, 18, 0, 0, "RW") - self.addrmap['msk_top_regs.lowpass_ema_alpha2'] = AddrmapItem("msk_top_regs.lowpass_ema_alpha2", bus, 136, 4, 18, 0, 0, "RW") - self.addrmap['msk_top_regs.rx_power'] = AddrmapItem("msk_top_regs.rx_power", bus, 140, 4, 23, 0, 0, "RO") - - def get_path(self, module, name): - path = module + "." + name - if path not in self.addrmap: - msg = f"Cannot find `{path}` in register dict" - logger.error(msg) - assert False - return path - - async def read(self, module, name, count=1, offset=0): - path = self.get_path(module, name) - return await self.addrmap[path].read(count, offset) - - async def write(self, module, name, value, offset=0): - path = self.get_path(module, name) - return await self.addrmap[path].write(value, offset) - async def read_raw(self, module, name, count=1, offset=0): - path = self.get_path(module, name) - return await self.addrmap[path].read_raw(count, offset) - async def write_raw(self, module, name, value, offset=0): - path = self.get_path(module, name) - return await self.addrmap[path].write_raw(value, offset) \ No newline at end of file diff --git a/rdl/msk_top_regs.h b/rdl/msk_top_regs.h deleted file mode 100644 index 1579eaf..0000000 --- a/rdl/msk_top_regs.h +++ /dev/null @@ -1,369 +0,0 @@ -// Generated by PeakRDL-cheader - A free and open-source header generator -// https://github.com/SystemRDL/PeakRDL-cheader - -#ifndef MSK_TOP_REGS_H -#define MSK_TOP_REGS_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -// Reg - msk_hash_lo -#define MSK_HASH_LO__HASH_ID_LO_bm 0xffffffff -#define MSK_HASH_LO__HASH_ID_LO_bp 0 -#define MSK_HASH_LO__HASH_ID_LO_bw 32 -#define MSK_HASH_LO__HASH_ID_LO_reset 0xaaaa5555 - -// Reg - msk_hash_hi -#define MSK_HASH_HI__HASH_ID_HI_bm 0xffffffff -#define MSK_HASH_HI__HASH_ID_HI_bp 0 -#define MSK_HASH_HI__HASH_ID_HI_bw 32 -#define MSK_HASH_HI__HASH_ID_HI_reset 0x5555aaaa - -// Reg - msk_init -#define MSK_INIT__TXRXINIT_bm 0x1 -#define MSK_INIT__TXRXINIT_bp 0 -#define MSK_INIT__TXRXINIT_bw 1 -#define MSK_INIT__TXRXINIT_reset 0x1 -#define MSK_INIT__TXINIT_bm 0x2 -#define MSK_INIT__TXINIT_bp 1 -#define MSK_INIT__TXINIT_bw 1 -#define MSK_INIT__TXINIT_reset 0x1 -#define MSK_INIT__RXINIT_bm 0x4 -#define MSK_INIT__RXINIT_bp 2 -#define MSK_INIT__RXINIT_bw 1 -#define MSK_INIT__RXINIT_reset 0x1 - -// Reg - msk_ctrl -#define MSK_CTRL__PTT_bm 0x1 -#define MSK_CTRL__PTT_bp 0 -#define MSK_CTRL__PTT_bw 1 -#define MSK_CTRL__PTT_reset 0x0 -#define MSK_CTRL__LOOPBACK_ENA_bm 0x2 -#define MSK_CTRL__LOOPBACK_ENA_bp 1 -#define MSK_CTRL__LOOPBACK_ENA_bw 1 -#define MSK_CTRL__LOOPBACK_ENA_reset 0x0 -#define MSK_CTRL__RX_INVERT_bm 0x4 -#define MSK_CTRL__RX_INVERT_bp 2 -#define MSK_CTRL__RX_INVERT_bw 1 -#define MSK_CTRL__RX_INVERT_reset 0x0 -#define MSK_CTRL__CLEAR_COUNTS_bm 0x8 -#define MSK_CTRL__CLEAR_COUNTS_bp 3 -#define MSK_CTRL__CLEAR_COUNTS_bw 1 -#define MSK_CTRL__CLEAR_COUNTS_reset 0x0 -#define MSK_CTRL__DIFF_ENCODER_LOOPBACK_bm 0x10 -#define MSK_CTRL__DIFF_ENCODER_LOOPBACK_bp 4 -#define MSK_CTRL__DIFF_ENCODER_LOOPBACK_bw 1 -#define MSK_CTRL__DIFF_ENCODER_LOOPBACK_reset 0x0 - -// Reg - msk_stat_0 -#define MSK_STAT_0__DEMOD_SYNC_LOCK_bm 0x1 -#define MSK_STAT_0__DEMOD_SYNC_LOCK_bp 0 -#define MSK_STAT_0__DEMOD_SYNC_LOCK_bw 1 -#define MSK_STAT_0__DEMOD_SYNC_LOCK_reset 0x0 -#define MSK_STAT_0__TX_ENABLE_bm 0x2 -#define MSK_STAT_0__TX_ENABLE_bp 1 -#define MSK_STAT_0__TX_ENABLE_bw 1 -#define MSK_STAT_0__TX_ENABLE_reset 0x0 -#define MSK_STAT_0__RX_ENABLE_bm 0x4 -#define MSK_STAT_0__RX_ENABLE_bp 2 -#define MSK_STAT_0__RX_ENABLE_bw 1 -#define MSK_STAT_0__RX_ENABLE_reset 0x0 -#define MSK_STAT_0__TX_AXIS_VALID_bm 0x8 -#define MSK_STAT_0__TX_AXIS_VALID_bp 3 -#define MSK_STAT_0__TX_AXIS_VALID_bw 1 -#define MSK_STAT_0__TX_AXIS_VALID_reset 0x0 - -// Reg - msk_stat_1 -#define MSK_STAT_1__TX_BIT_COUNTER_bm 0xffffffff -#define MSK_STAT_1__TX_BIT_COUNTER_bp 0 -#define MSK_STAT_1__TX_BIT_COUNTER_bw 32 -#define MSK_STAT_1__TX_BIT_COUNTER_reset 0x0 - -// Reg - msk_stat_2 -#define MSK_STAT_2__TX_ENA_COUNTER_bm 0xffffffff -#define MSK_STAT_2__TX_ENA_COUNTER_bp 0 -#define MSK_STAT_2__TX_ENA_COUNTER_bw 32 -#define MSK_STAT_2__TX_ENA_COUNTER_reset 0x0 - -// Reg - config_nco_fw_desc_c4924cc6_name_0c494469 -#define CONFIG_NCO_FW_DESC_C4924CC6_NAME_0C494469__CONFIG_DATA_bm 0xffffffff -#define CONFIG_NCO_FW_DESC_C4924CC6_NAME_0C494469__CONFIG_DATA_bp 0 -#define CONFIG_NCO_FW_DESC_C4924CC6_NAME_0C494469__CONFIG_DATA_bw 32 -#define CONFIG_NCO_FW_DESC_C4924CC6_NAME_0C494469__CONFIG_DATA_reset 0x0 - -// Reg - config_nco_fw_desc_94d7aaf5_name_84dd0c1c -#define CONFIG_NCO_FW_DESC_94D7AAF5_NAME_84DD0C1C__CONFIG_DATA_bm 0xffffffff -#define CONFIG_NCO_FW_DESC_94D7AAF5_NAME_84DD0C1C__CONFIG_DATA_bp 0 -#define CONFIG_NCO_FW_DESC_94D7AAF5_NAME_84DD0C1C__CONFIG_DATA_bw 32 -#define CONFIG_NCO_FW_DESC_94D7AAF5_NAME_84DD0C1C__CONFIG_DATA_reset 0x0 - -// Reg - config_nco_fw_desc_42134a4f_name_d97dbd51 -#define CONFIG_NCO_FW_DESC_42134A4F_NAME_D97DBD51__CONFIG_DATA_bm 0xffffffff -#define CONFIG_NCO_FW_DESC_42134A4F_NAME_D97DBD51__CONFIG_DATA_bp 0 -#define CONFIG_NCO_FW_DESC_42134A4F_NAME_D97DBD51__CONFIG_DATA_bw 32 -#define CONFIG_NCO_FW_DESC_42134A4F_NAME_D97DBD51__CONFIG_DATA_reset 0x0 - -// Reg - config_nco_fw_desc_16fb48c8_name_8d01a20d -#define CONFIG_NCO_FW_DESC_16FB48C8_NAME_8D01A20D__CONFIG_DATA_bm 0xffffffff -#define CONFIG_NCO_FW_DESC_16FB48C8_NAME_8D01A20D__CONFIG_DATA_bp 0 -#define CONFIG_NCO_FW_DESC_16FB48C8_NAME_8D01A20D__CONFIG_DATA_bw 32 -#define CONFIG_NCO_FW_DESC_16FB48C8_NAME_8D01A20D__CONFIG_DATA_reset 0x0 - -// Reg - config_nco_fw_desc_43c0828f_name_bdc60ecf -#define CONFIG_NCO_FW_DESC_43C0828F_NAME_BDC60ECF__CONFIG_DATA_bm 0xffffffff -#define CONFIG_NCO_FW_DESC_43C0828F_NAME_BDC60ECF__CONFIG_DATA_bp 0 -#define CONFIG_NCO_FW_DESC_43C0828F_NAME_BDC60ECF__CONFIG_DATA_bw 32 -#define CONFIG_NCO_FW_DESC_43C0828F_NAME_BDC60ECF__CONFIG_DATA_reset 0x0 - -// Reg - lpf_config_0 -#define LPF_CONFIG_0__LPF_FREEZE_bm 0x1 -#define LPF_CONFIG_0__LPF_FREEZE_bp 0 -#define LPF_CONFIG_0__LPF_FREEZE_bw 1 -#define LPF_CONFIG_0__LPF_FREEZE_reset 0x0 -#define LPF_CONFIG_0__LPF_ZERO_bm 0x2 -#define LPF_CONFIG_0__LPF_ZERO_bp 1 -#define LPF_CONFIG_0__LPF_ZERO_bw 1 -#define LPF_CONFIG_0__LPF_ZERO_reset 0x0 -#define LPF_CONFIG_0__PRBS_RESERVED_bm 0xfc -#define LPF_CONFIG_0__PRBS_RESERVED_bp 2 -#define LPF_CONFIG_0__PRBS_RESERVED_bw 6 -#define LPF_CONFIG_0__PRBS_RESERVED_reset 0x0 -#define LPF_CONFIG_0__LPF_ALPHA_bm 0xffffff00 -#define LPF_CONFIG_0__LPF_ALPHA_bp 8 -#define LPF_CONFIG_0__LPF_ALPHA_bw 24 -#define LPF_CONFIG_0__LPF_ALPHA_reset 0x0 - -// Reg - lpf_config_1 -#define LPF_CONFIG_1__I_GAIN_bm 0xffffff -#define LPF_CONFIG_1__I_GAIN_bp 0 -#define LPF_CONFIG_1__I_GAIN_bw 24 -#define LPF_CONFIG_1__I_GAIN_reset 0x0 -#define LPF_CONFIG_1__I_SHIFT_bm 0xff000000 -#define LPF_CONFIG_1__I_SHIFT_bp 24 -#define LPF_CONFIG_1__I_SHIFT_bw 8 -#define LPF_CONFIG_1__I_SHIFT_reset 0x0 - -// Reg - data_width_desc_58c848dd_name_2fbd8eba -#define DATA_WIDTH_DESC_58C848DD_NAME_2FBD8EBA__DATA_WIDTH_bm 0xff -#define DATA_WIDTH_DESC_58C848DD_NAME_2FBD8EBA__DATA_WIDTH_bp 0 -#define DATA_WIDTH_DESC_58C848DD_NAME_2FBD8EBA__DATA_WIDTH_bw 8 -#define DATA_WIDTH_DESC_58C848DD_NAME_2FBD8EBA__DATA_WIDTH_reset 0x8 - -// Reg - data_width_desc_6097df38_name_4609588b -#define DATA_WIDTH_DESC_6097DF38_NAME_4609588B__DATA_WIDTH_bm 0xff -#define DATA_WIDTH_DESC_6097DF38_NAME_4609588B__DATA_WIDTH_bp 0 -#define DATA_WIDTH_DESC_6097DF38_NAME_4609588B__DATA_WIDTH_bw 8 -#define DATA_WIDTH_DESC_6097DF38_NAME_4609588B__DATA_WIDTH_reset 0x8 - -// Reg - prbs_ctrl -#define PRBS_CTRL__PRBS_SEL_bm 0x1 -#define PRBS_CTRL__PRBS_SEL_bp 0 -#define PRBS_CTRL__PRBS_SEL_bw 1 -#define PRBS_CTRL__PRBS_SEL_reset 0x0 -#define PRBS_CTRL__PRBS_ERROR_INSERT_bm 0x2 -#define PRBS_CTRL__PRBS_ERROR_INSERT_bp 1 -#define PRBS_CTRL__PRBS_ERROR_INSERT_bw 1 -#define PRBS_CTRL__PRBS_ERROR_INSERT_reset 0x0 -#define PRBS_CTRL__PRBS_CLEAR_bm 0x4 -#define PRBS_CTRL__PRBS_CLEAR_bp 2 -#define PRBS_CTRL__PRBS_CLEAR_bw 1 -#define PRBS_CTRL__PRBS_CLEAR_reset 0x0 -#define PRBS_CTRL__PRBS_MANUAL_SYNC_bm 0x8 -#define PRBS_CTRL__PRBS_MANUAL_SYNC_bp 3 -#define PRBS_CTRL__PRBS_MANUAL_SYNC_bw 1 -#define PRBS_CTRL__PRBS_MANUAL_SYNC_reset 0x0 -#define PRBS_CTRL__PRBS_RESERVED_bm 0xfff0 -#define PRBS_CTRL__PRBS_RESERVED_bp 4 -#define PRBS_CTRL__PRBS_RESERVED_bw 12 -#define PRBS_CTRL__PRBS_RESERVED_reset 0x0 -#define PRBS_CTRL__PRBS_SYNC_THRESHOLD_bm 0xffff0000 -#define PRBS_CTRL__PRBS_SYNC_THRESHOLD_bp 16 -#define PRBS_CTRL__PRBS_SYNC_THRESHOLD_bw 16 -#define PRBS_CTRL__PRBS_SYNC_THRESHOLD_reset 0x0 - -// Reg - config_prbs_seed -#define CONFIG_PRBS_SEED__CONFIG_DATA_bm 0xffffffff -#define CONFIG_PRBS_SEED__CONFIG_DATA_bp 0 -#define CONFIG_PRBS_SEED__CONFIG_DATA_bw 32 -#define CONFIG_PRBS_SEED__CONFIG_DATA_reset 0x0 - -// Reg - config_prbs_poly -#define CONFIG_PRBS_POLY__CONFIG_DATA_bm 0xffffffff -#define CONFIG_PRBS_POLY__CONFIG_DATA_bp 0 -#define CONFIG_PRBS_POLY__CONFIG_DATA_bw 32 -#define CONFIG_PRBS_POLY__CONFIG_DATA_reset 0x0 - -// Reg - config_prbs_errmask -#define CONFIG_PRBS_ERRMASK__CONFIG_DATA_bm 0xffffffff -#define CONFIG_PRBS_ERRMASK__CONFIG_DATA_bp 0 -#define CONFIG_PRBS_ERRMASK__CONFIG_DATA_bw 32 -#define CONFIG_PRBS_ERRMASK__CONFIG_DATA_reset 0x0 - -// Reg - stat_32_bits -#define STAT_32_BITS__STATUS_DATA_bm 0xffffffff -#define STAT_32_BITS__STATUS_DATA_bp 0 -#define STAT_32_BITS__STATUS_DATA_bw 32 -#define STAT_32_BITS__STATUS_DATA_reset 0x0 - -// Reg - stat_32_errs -#define STAT_32_ERRS__STATUS_DATA_bm 0xffffffff -#define STAT_32_ERRS__STATUS_DATA_bp 0 -#define STAT_32_ERRS__STATUS_DATA_bw 32 -#define STAT_32_ERRS__STATUS_DATA_reset 0x0 - -// Reg - stat_32_lpf_acc_desc_8cebc7dc_name_f20c6670 -#define STAT_32_LPF_ACC_DESC_8CEBC7DC_NAME_F20C6670__STATUS_DATA_bm 0xffffffff -#define STAT_32_LPF_ACC_DESC_8CEBC7DC_NAME_F20C6670__STATUS_DATA_bp 0 -#define STAT_32_LPF_ACC_DESC_8CEBC7DC_NAME_F20C6670__STATUS_DATA_bw 32 -#define STAT_32_LPF_ACC_DESC_8CEBC7DC_NAME_F20C6670__STATUS_DATA_reset 0x0 - -// Reg - stat_32_lpf_acc_desc_dea6bd99_name_758fd0ce -#define STAT_32_LPF_ACC_DESC_DEA6BD99_NAME_758FD0CE__STATUS_DATA_bm 0xffffffff -#define STAT_32_LPF_ACC_DESC_DEA6BD99_NAME_758FD0CE__STATUS_DATA_bp 0 -#define STAT_32_LPF_ACC_DESC_DEA6BD99_NAME_758FD0CE__STATUS_DATA_bw 32 -#define STAT_32_LPF_ACC_DESC_DEA6BD99_NAME_758FD0CE__STATUS_DATA_reset 0x0 - -// Reg - msk_stat_3 -#define MSK_STAT_3__XFER_COUNT_bm 0xffffffff -#define MSK_STAT_3__XFER_COUNT_bp 0 -#define MSK_STAT_3__XFER_COUNT_bw 32 -#define MSK_STAT_3__XFER_COUNT_reset 0x0 - -// Reg - rx_sample_discard -#define RX_SAMPLE_DISCARD__RX_SAMPLE_DISCARD_bm 0xff -#define RX_SAMPLE_DISCARD__RX_SAMPLE_DISCARD_bp 0 -#define RX_SAMPLE_DISCARD__RX_SAMPLE_DISCARD_bw 8 -#define RX_SAMPLE_DISCARD__RX_SAMPLE_DISCARD_reset 0x0 -#define RX_SAMPLE_DISCARD__RX_NCO_DISCARD_bm 0xff00 -#define RX_SAMPLE_DISCARD__RX_NCO_DISCARD_bp 8 -#define RX_SAMPLE_DISCARD__RX_NCO_DISCARD_bw 8 -#define RX_SAMPLE_DISCARD__RX_NCO_DISCARD_reset 0x0 - -// Reg - lpf_config_2 -#define LPF_CONFIG_2__P_GAIN_bm 0xffffff -#define LPF_CONFIG_2__P_GAIN_bp 0 -#define LPF_CONFIG_2__P_GAIN_bw 24 -#define LPF_CONFIG_2__P_GAIN_reset 0x0 -#define LPF_CONFIG_2__P_SHIFT_bm 0xff000000 -#define LPF_CONFIG_2__P_SHIFT_bp 24 -#define LPF_CONFIG_2__P_SHIFT_bw 8 -#define LPF_CONFIG_2__P_SHIFT_reset 0x0 - -// Reg - observation_data_data_0c017ef4_desc_64ff3689_name_d8ad3b25 -#define OBSERVATION_DATA_DATA_0C017EF4_DESC_64FF3689_NAME_D8AD3B25__DATA_bm 0xffffffff -#define OBSERVATION_DATA_DATA_0C017EF4_DESC_64FF3689_NAME_D8AD3B25__DATA_bp 0 -#define OBSERVATION_DATA_DATA_0C017EF4_DESC_64FF3689_NAME_D8AD3B25__DATA_bw 32 -#define OBSERVATION_DATA_DATA_0C017EF4_DESC_64FF3689_NAME_D8AD3B25__DATA_reset 0x0 - -// Reg - observation_data_data_0515efaa_desc_ebde6d39_name_2c154788 -#define OBSERVATION_DATA_DATA_0515EFAA_DESC_EBDE6D39_NAME_2C154788__DATA_bm 0xffffffff -#define OBSERVATION_DATA_DATA_0515EFAA_DESC_EBDE6D39_NAME_2C154788__DATA_bp 0 -#define OBSERVATION_DATA_DATA_0515EFAA_DESC_EBDE6D39_NAME_2C154788__DATA_bw 32 -#define OBSERVATION_DATA_DATA_0515EFAA_DESC_EBDE6D39_NAME_2C154788__DATA_reset 0x0 - -// Reg - observation_data_data_25a21249_desc_417e1c96_name_3b640507 -#define OBSERVATION_DATA_DATA_25A21249_DESC_417E1C96_NAME_3B640507__DATA_bm 0xffffffff -#define OBSERVATION_DATA_DATA_25A21249_DESC_417E1C96_NAME_3B640507__DATA_bp 0 -#define OBSERVATION_DATA_DATA_25A21249_DESC_417E1C96_NAME_3B640507__DATA_bw 32 -#define OBSERVATION_DATA_DATA_25A21249_DESC_417E1C96_NAME_3B640507__DATA_reset 0x0 - -// Reg - observation_data_data_272a00b6_desc_70869502_name_3de9a0d3 -#define OBSERVATION_DATA_DATA_272A00B6_DESC_70869502_NAME_3DE9A0D3__DATA_bm 0xffffffff -#define OBSERVATION_DATA_DATA_272A00B6_DESC_70869502_NAME_3DE9A0D3__DATA_bp 0 -#define OBSERVATION_DATA_DATA_272A00B6_DESC_70869502_NAME_3DE9A0D3__DATA_bw 32 -#define OBSERVATION_DATA_DATA_272A00B6_DESC_70869502_NAME_3DE9A0D3__DATA_reset 0x0 - -// Reg - tx_sync_ctrl -#define TX_SYNC_CTRL__TX_SYNC_ENA_bm 0x1 -#define TX_SYNC_CTRL__TX_SYNC_ENA_bp 0 -#define TX_SYNC_CTRL__TX_SYNC_ENA_bw 1 -#define TX_SYNC_CTRL__TX_SYNC_ENA_reset 0x0 -#define TX_SYNC_CTRL__TX_SYNC_FORCE_bm 0x2 -#define TX_SYNC_CTRL__TX_SYNC_FORCE_bp 1 -#define TX_SYNC_CTRL__TX_SYNC_FORCE_bw 1 -#define TX_SYNC_CTRL__TX_SYNC_FORCE_reset 0x0 -#define TX_SYNC_CTRL__TX_SYNC_F1_bm 0x4 -#define TX_SYNC_CTRL__TX_SYNC_F1_bp 2 -#define TX_SYNC_CTRL__TX_SYNC_F1_bw 1 -#define TX_SYNC_CTRL__TX_SYNC_F1_reset 0x0 -#define TX_SYNC_CTRL__TX_SYNC_F2_bm 0x8 -#define TX_SYNC_CTRL__TX_SYNC_F2_bp 3 -#define TX_SYNC_CTRL__TX_SYNC_F2_bw 1 -#define TX_SYNC_CTRL__TX_SYNC_F2_reset 0x0 - -// Reg - tx_sync_cnt -#define TX_SYNC_CNT__TX_SYNC_CNT_bm 0xffffff -#define TX_SYNC_CNT__TX_SYNC_CNT_bp 0 -#define TX_SYNC_CNT__TX_SYNC_CNT_bw 24 -#define TX_SYNC_CNT__TX_SYNC_CNT_reset 0x0 - -// Reg - lowpass_ema_alpha -#define LOWPASS_EMA_ALPHA__ALPHA_bm 0x3ffff -#define LOWPASS_EMA_ALPHA__ALPHA_bp 0 -#define LOWPASS_EMA_ALPHA__ALPHA_bw 18 -#define LOWPASS_EMA_ALPHA__ALPHA_reset 0x0 - -// Reg - rx_power -#define RX_POWER__RX_POWER_bm 0x7fffff -#define RX_POWER__RX_POWER_bp 0 -#define RX_POWER__RX_POWER_bw 23 -#define RX_POWER__RX_POWER_reset 0x0 - -// Addrmap - msk_top_regs -typedef struct __attribute__ ((__packed__)) { - uint32_t Hash_ID_Low; - uint32_t Hash_ID_High; - uint32_t MSK_Init; - uint32_t MSK_Control; - uint32_t MSK_Status; - uint32_t Tx_Bit_Count; - uint32_t Tx_Enable_Count; - uint32_t Fb_FreqWord; - uint32_t TX_F1_FreqWord; - uint32_t TX_F2_FreqWord; - uint32_t RX_F1_FreqWord; - uint32_t RX_F2_FreqWord; - uint32_t LPF_Config_0; - uint32_t LPF_Config_1; - uint32_t Tx_Data_Width; - uint32_t Rx_Data_Width; - uint32_t PRBS_Control; - uint32_t PRBS_Initial_State; - uint32_t PRBS_Polynomial; - uint32_t PRBS_Error_Mask; - uint32_t PRBS_Bit_Count; - uint32_t PRBS_Error_Count; - uint32_t LPF_Accum_F1; - uint32_t LPF_Accum_F2; - uint32_t axis_xfer_count; - uint32_t Rx_Sample_Discard; - uint32_t LPF_Config_2; - uint32_t f1_nco_adjust; - uint32_t f2_nco_adjust; - uint32_t f1_error; - uint32_t f2_error; - uint32_t Tx_Sync_Ctrl; - uint32_t Tx_Sync_Cnt; - uint32_t lowpass_ema_alpha1; - uint32_t lowpass_ema_alpha2; - uint32_t rx_power; -} msk_top_regs_t; - -// Addrmap - Pluto_MSK_Modem -typedef struct __attribute__ ((__packed__)) { - uint8_t RESERVED_0_43bfffff[0x43c00000]; - msk_top_regs_t pluto_msk_regs; -} Pluto_MSK_Modem_t; - - -static_assert(sizeof(Pluto_MSK_Modem_t) == 0x43c00090, "Packing error"); - -#ifdef __cplusplus -} -#endif - -#endif /* MSK_TOP_REGS_H */ diff --git a/rdl/msk_top_regs.md b/rdl/msk_top_regs.md deleted file mode 100644 index 79009bc..0000000 --- a/rdl/msk_top_regs.md +++ /dev/null @@ -1,769 +0,0 @@ - - -## Pluto_MSK_Modem address map - -- Absolute Address: 0x0 -- Base Offset: 0x0 -- Size: 0x43C00090 - -| Offset | Identifier | Name | -|----------|--------------|-------------------| -|0x43C00000|pluto_msk_regs|Pluto MSK Registers| - -## pluto_msk_regs address map - -- Absolute Address: 0x43C00000 -- Base Offset: 0x43C00000 -- Size: 0x90 - -

MSK Modem Configuration and Status Registers

- -|Offset| Identifier | Name | -|------|------------------|-------------------------------------------------------------| -| 0x00 | Hash_ID_Low | Pluto MSK FPGA Hash ID - Lower 32-bits | -| 0x04 | Hash_ID_High | Pluto MSK FPGA Hash ID - Upper 32-bits | -| 0x08 | MSK_Init | MSK Modem Control 0 | -| 0x0C | MSK_Control | MSK Modem Control 1 | -| 0x10 | MSK_Status | MSK Modem Status 0 | -| 0x14 | Tx_Bit_Count | MSK Modem Status 1 | -| 0x18 | Tx_Enable_Count | MSK Modem Status 2 | -| 0x1C | Fb_FreqWord | Bitrate NCO Frequency Control Word | -| 0x20 | TX_F1_FreqWord | Tx F1 NCO Frequency Control Word | -| 0x24 | TX_F2_FreqWord | Tx F2 NCO Frequency Control Word | -| 0x28 | RX_F1_FreqWord | Rx F1 NCO Frequency Control Word | -| 0x2C | RX_F2_FreqWord | Rx F2 NCO Frequency Control Word | -| 0x30 | LPF_Config_0 |PI Controller Configuration and Low-pass Filter Configuration| -| 0x34 | LPF_Config_1 | PI Controller Configuration Configuration Register 1 | -| 0x38 | Tx_Data_Width | Modem Tx Input Data Width | -| 0x3C | Rx_Data_Width | Modem Rx Output Data Width | -| 0x40 | PRBS_Control | PRBS Control 0 | -| 0x44 |PRBS_Initial_State| PRBS Control 1 | -| 0x48 | PRBS_Polynomial | PRBS Control 2 | -| 0x4C | PRBS_Error_Mask | PRBS Control 3 | -| 0x50 | PRBS_Bit_Count | PRBS Status 0 | -| 0x54 | PRBS_Error_Count | PRBS Status 1 | -| 0x58 | LPF_Accum_F1 | F1 PI Controller Accumulator | -| 0x5C | LPF_Accum_F2 | F2 PI Controller Accumulator | -| 0x60 | axis_xfer_count | MSK Modem Status 3 | -| 0x64 | Rx_Sample_Discard| Rx Sample Discard | -| 0x68 | LPF_Config_2 | PI Controller Configuration Configuration Register 2 | -| 0x6C | f1_nco_adjust | F1 NCO Frequency Adjust | -| 0x70 | f2_nco_adjust | F2 NCO Frequency Adjust | -| 0x74 | f1_error | F1 Error Value | -| 0x78 | f2_error | F2 Error Value | -| 0x7C | Tx_Sync_Ctrl | Transmitter Sync Control | -| 0x80 | Tx_Sync_Cnt | Transmitter Sync Duration | -| 0x84 |lowpass_ema_alpha1| Exponential Moving Average Alpha | -| 0x88 |lowpass_ema_alpha2| Exponential Moving Average Alpha | -| 0x8C | rx_power | Receive Power | - -### Hash_ID_Low register - -- Absolute Address: 0x43C00000 -- Base Offset: 0x0 -- Size: 0x4 - -|Bits|Identifier|Access| Reset | Name | -|----|----------|------|----------|---------------------| -|31:0|hash_id_lo| r |0xAAAA5555|Hash ID Lower 32-bits| - -#### hash_id_lo field - -

Lower 32-bits of Pluto MSK FPGA Hash ID

- -### Hash_ID_High register - -- Absolute Address: 0x43C00004 -- Base Offset: 0x4 -- Size: 0x4 - -|Bits|Identifier|Access| Reset | Name | -|----|----------|------|----------|---------------------| -|31:0|hash_id_hi| r |0x5555AAAA|Hash ID Upper 32-bits| - -#### hash_id_hi field - -

Upper 32-bits of Pluto MSK FPGA Hash ID

- -### MSK_Init register - -- Absolute Address: 0x43C00008 -- Base Offset: 0x8 -- Size: 0x4 - -

Synchronous initialization of MSK Modem functions, does not affect configuration registers.

- -|Bits|Identifier|Access|Reset| Name | -|----|----------|------|-----|-----------------| -| 0 | txrxinit | rw | 0x1 |Tx/Rx Init Enable| -| 1 | txinit | rw | 0x1 | Tx Init Enable | -| 2 | rxinit | rw | 0x1 | Rx Init Enable | - -#### txrxinit field - -

0 -> Normal modem operation -1 -> Initialize Tx and Rx

- -#### txinit field - -

0 -> Normal Tx operation -1 -> Initialize Tx

- -#### rxinit field - -

0 -> Normal Rx operation -1 -> Initialize Rx

- -### MSK_Control register - -- Absolute Address: 0x43C0000C -- Base Offset: 0xC -- Size: 0x4 - -

MSK Modem Configuration and Control

- -|Bits| Identifier |Access|Reset| Name | -|----|---------------------|------|-----|-----------------------------------------------| -| 0 | ptt | rw | 0x0 | Push-to-Talk Enable | -| 1 | loopback_ena | rw | 0x0 | Modem Loopback Enable | -| 2 | rx_invert | rw | 0x0 | Rx Data Invert Enable | -| 3 | clear_counts | rw | 0x0 | Clear Status Counters | -| 4 |diff_encoder_loopback| rw | 0x0 |Differential Encoder -> Decoder Loopback Enable| - -#### ptt field - -

0 -> PTT Disabled -1 -> PTT Enabled

- -#### loopback_ena field - -

0 -> Modem loopback disabled -1 -> Modem loopback enabled

- -#### rx_invert field - -

0 -> Rx data normal -1 -> Rx data inverted

- -#### clear_counts field - -

Clear Tx Bit Counter and Tx Enable Counter

- -#### diff_encoder_loopback field - -

0 -> Differential Encoder -> Decoder loopback disabled -1 -> Differential Encoder -> Decoder loopback enabled

- -### MSK_Status register - -- Absolute Address: 0x43C00010 -- Base Offset: 0x10 -- Size: 0x4 - -

Modem status bits

- -|Bits| Identifier |Access|Reset| Name | -|----|---------------|------|-----|-------------------------------------------| -| 0 |demod_sync_lock| r | 0x0 | Demodulator Sync Status | -| 1 | tx_enable | r | 0x0 |AD9363 DAC Interface Tx Enable Input Active| -| 2 | rx_enable | r | 0x0 |AD9363 ADC Interface Rx Enable Input Active| -| 3 | tx_axis_valid | r | 0x0 | Tx S_AXIS_VALID | - -#### demod_sync_lock field - -

Demodulator Sync Status - not currently implemented

- -#### tx_enable field - -

1 -> Data to DAC Enabled -0 -> Data to DAC Disabled

- -#### rx_enable field - -

1 -> Data from ADC Enabled -0 -> Data from ADC Disabled

- -#### tx_axis_valid field - -

1 -> S_AXIS_VALID Enabled -0 -> S_AXIS_VALID Disabled

- -### Tx_Bit_Count register - -- Absolute Address: 0x43C00014 -- Base Offset: 0x14 -- Size: 0x4 - -

Modem status data

- -|Bits| Identifier |Access|Reset| Name | -|----|--------------|------|-----|------------| -|31:0|tx_bit_counter| r | 0x0 |Tx Bit Count| - -#### tx_bit_counter field - -

Count of data requests made by modem

- -### Tx_Enable_Count register - -- Absolute Address: 0x43C00018 -- Base Offset: 0x18 -- Size: 0x4 - -

Modem status data

- -|Bits| Identifier |Access|Reset| Name | -|----|--------------|------|-----|---------------| -|31:0|tx_ena_counter| r | 0x0 |Tx Enable Count| - -#### tx_ena_counter field - -

Number of clocks on which Tx Enable is active

- -### Fb_FreqWord register - -- Absolute Address: 0x43C0001C -- Base Offset: 0x1C -- Size: 0x4 - -

Set Modem Data Rate

- -|Bits| Identifier|Access|Reset| Name | -|----|-----------|------|-----|----------------------| -|31:0|config_data| rw | 0x0 |Frequency Control Word| - -#### config_data field - -

Sets the center frequency of the NCO as FW = Fn * 2^32/Fs, where Fn is the desired NCO frequency, and Fs is the NCO sample rate

- -### TX_F1_FreqWord register - -- Absolute Address: 0x43C00020 -- Base Offset: 0x20 -- Size: 0x4 - -

Set Modulator F1 Frequency

- -|Bits| Identifier|Access|Reset| Name | -|----|-----------|------|-----|----------------------| -|31:0|config_data| rw | 0x0 |Frequency Control Word| - -#### config_data field - -

Sets the center frequency of the NCO as FW = Fn * 2^32/Fs, where Fn is the desired NCO frequency, and Fs is the NCO sample rate

- -### TX_F2_FreqWord register - -- Absolute Address: 0x43C00024 -- Base Offset: 0x24 -- Size: 0x4 - -

Set Modulator F2 Frequency

- -|Bits| Identifier|Access|Reset| Name | -|----|-----------|------|-----|----------------------| -|31:0|config_data| rw | 0x0 |Frequency Control Word| - -#### config_data field - -

Sets the center frequency of the NCO as FW = Fn * 2^32/Fs, where Fn is the desired NCO frequency, and Fs is the NCO sample rate

- -### RX_F1_FreqWord register - -- Absolute Address: 0x43C00028 -- Base Offset: 0x28 -- Size: 0x4 - -

Set Demodulator F1 Frequency

- -|Bits| Identifier|Access|Reset| Name | -|----|-----------|------|-----|----------------------| -|31:0|config_data| rw | 0x0 |Frequency Control Word| - -#### config_data field - -

Sets the center frequency of the NCO as FW = Fn * 2^32/Fs, where Fn is the desired NCO frequency, and Fs is the NCO sample rate

- -### RX_F2_FreqWord register - -- Absolute Address: 0x43C0002C -- Base Offset: 0x2C -- Size: 0x4 - -

Set Demodulator F2 Frequency

- -|Bits| Identifier|Access|Reset| Name | -|----|-----------|------|-----|----------------------| -|31:0|config_data| rw | 0x0 |Frequency Control Word| - -#### config_data field - -

Sets the center frequency of the NCO as FW = Fn * 2^32/Fs, where Fn is the desired NCO frequency, and Fs is the NCO sample rate

- -### LPF_Config_0 register - -- Absolute Address: 0x43C00030 -- Base Offset: 0x30 -- Size: 0x4 - -

Configure PI controller and low-pass filter

- -|Bits| Identifier |Access|Reset| Name | -|----|-------------|------|-----|--------------------------------------| -| 0 | lpf_freeze | rw | 0x0 |Freeze the accumulator's current value| -| 1 | lpf_zero | rw | 0x0 | Hold the PI Accumulator at zero | -| 7:2|prbs_reserved| w | 0x0 | — | -|31:8| lpf_alpha | rw | 0x0 | Lowpass IIR filter alpha | - -#### lpf_freeze field - -

0 -> Normal operation -1 -> Freeze current value

- -#### lpf_zero field - -

0 -> Normal operation -1 -> Zero and hold accumulator

- -#### lpf_alpha field - -

Value controls the filter rolloff

- -### LPF_Config_1 register - -- Absolute Address: 0x43C00034 -- Base Offset: 0x34 -- Size: 0x4 - -

Configures PI Controller I-gain and divisor

- -| Bits|Identifier|Access|Reset| Name | -|-----|----------|------|-----|-----------------------| -| 23:0| i_gain | rw | 0x0 | Integral Gain Value | -|31:24| i_shift | rw | 0x0 |Integral Gain Bit Shift| - -#### i_gain field - -

Value m of 0-16,777,215 sets the integral multiplier

- -#### i_shift field - -

Value n of 0-32 sets the integral divisor as 2^-n

- -### Tx_Data_Width register - -- Absolute Address: 0x43C00038 -- Base Offset: 0x38 -- Size: 0x4 - -

Set the parallel data width of the parallel-to-serial converter

- -|Bits|Identifier|Access|Reset| Name | -|----|----------|------|-----|-----------------------------| -| 7:0|data_width| rw | 0x8 |Modem input/output data width| - -#### data_width field - -

Set the data width of the modem input/output

- -### Rx_Data_Width register - -- Absolute Address: 0x43C0003C -- Base Offset: 0x3C -- Size: 0x4 - -

Set the parallel data width of the serial-to-parallel converter

- -|Bits|Identifier|Access|Reset| Name | -|----|----------|------|-----|-----------------------------| -| 7:0|data_width| rw | 0x8 |Modem input/output data width| - -#### data_width field - -

Set the data width of the modem input/output

- -### PRBS_Control register - -- Absolute Address: 0x43C00040 -- Base Offset: 0x40 -- Size: 0x4 - -

Configures operation of the PRBS Generator and Monitor

- -| Bits| Identifier |Access|Reset| Name | -|-----|-------------------|------|-----|------------------------| -| 0 | prbs_sel | rw | 0x0 | PRBS Data Select | -| 1 | prbs_error_insert | w | 0x0 | PRBS Error Insert | -| 2 | prbs_clear | w | 0x0 | PRBS Clear Counters | -| 3 | prbs_manual_sync | w | 0x0 | PRBS Manual Sync | -| 15:4| prbs_reserved | w | 0x0 | — | -|31:16|prbs_sync_threshold| w | 0x0 |PRBS Auto Sync Threshold| - -#### prbs_sel field - -

0 -> Select Normal Tx Data -1 -> Select PRBS Tx Data

- -#### prbs_error_insert field - -

0 -> 1 : Insert bit error in Tx data (both Normal and PRBS) -1 -> 0 : Insert bit error in Tx data (both Normal and PRBS)

- -#### prbs_clear field - -

0 -> 1 : Clear PRBS Counters -1 -> 0 : Clear PRBS Counters

- -#### prbs_manual_sync field - -

0 -> 1 : Synchronize PRBS monitor -1 -> 0 : Synchronize PRBS monitor

- -#### prbs_sync_threshold field - -

0 : Auto Sync Disabled -N > 0 : Auto sync after N errors

- -### PRBS_Initial_State register - -- Absolute Address: 0x43C00044 -- Base Offset: 0x44 -- Size: 0x4 - -

PRBS Initial State

- -|Bits| Identifier|Access|Reset| Name | -|----|-----------|------|-----|---------| -|31:0|config_data| rw | 0x0 |PRBS Seed| - -#### config_data field - -

Sets the starting value of the PRBS generator

- -### PRBS_Polynomial register - -- Absolute Address: 0x43C00048 -- Base Offset: 0x48 -- Size: 0x4 - -

PRBS Polynomial

- -|Bits| Identifier|Access|Reset| Name | -|----|-----------|------|-----|---------------| -|31:0|config_data| rw | 0x0 |PRBS Polynomial| - -#### config_data field - -

Bit positions set to '1' indicate polynomial feedback positions

- -### PRBS_Error_Mask register - -- Absolute Address: 0x43C0004C -- Base Offset: 0x4C -- Size: 0x4 - -

PRBS Error Mask

- -|Bits| Identifier|Access|Reset| Name | -|----|-----------|------|-----|---------------| -|31:0|config_data| rw | 0x0 |PRBS Error Mask| - -#### config_data field - -

Bit positions set to '1' indicate bits that are inverted when a bit error is inserted

- -### PRBS_Bit_Count register - -- Absolute Address: 0x43C00050 -- Base Offset: 0x50 -- Size: 0x4 - -

PRBS Bits Received

- -|Bits| Identifier|Access|Reset| Name | -|----|-----------|------|-----|------------------| -|31:0|status_data| r | 0x0 |PRBS Bits Received| - -#### status_data field - -

Number of bits received by the PRBS monitor since last -BER can be calculated as the ratio of received bits to errored-bits

- -### PRBS_Error_Count register - -- Absolute Address: 0x43C00054 -- Base Offset: 0x54 -- Size: 0x4 - -

PRBS Bit Errors

- -|Bits| Identifier|Access|Reset| Name | -|----|-----------|------|-----|---------------| -|31:0|status_data| r | 0x0 |PRBS Bit Errors| - -#### status_data field - -

Number of errored-bits received by the PRBS monitor since last sync -BER can be calculated as the ratio of received bits to errored-bits

- -### LPF_Accum_F1 register - -- Absolute Address: 0x43C00058 -- Base Offset: 0x58 -- Size: 0x4 - -

Value of the F1 PI Controller Accumulator

- -|Bits| Identifier|Access|Reset| Name | -|----|-----------|------|-----|-------------------------------| -|31:0|status_data| r | 0x0 |PI Controller Accumulator Value| - -#### status_data field - -

PI Controller Accumulator Value

- -### LPF_Accum_F2 register - -- Absolute Address: 0x43C0005C -- Base Offset: 0x5C -- Size: 0x4 - -

Value of the F2 PI Controller Accumulator

- -|Bits| Identifier|Access|Reset| Name | -|----|-----------|------|-----|-------------------------------| -|31:0|status_data| r | 0x0 |PI Controller Accumulator Value| - -#### status_data field - -

PI Controller Accumulator Value

- -### axis_xfer_count register - -- Absolute Address: 0x43C00060 -- Base Offset: 0x60 -- Size: 0x4 - -

Modem status data

- -|Bits|Identifier|Access|Reset| Name | -|----|----------|------|-----|----------------| -|31:0|xfer_count| r | 0x0 |S_AXIS Transfers| - -#### xfer_count field - -

Number completed S_AXIS transfers

- -### Rx_Sample_Discard register - -- Absolute Address: 0x43C00064 -- Base Offset: 0x64 -- Size: 0x4 - -

Configure samples discard operation for demodulator

- -|Bits| Identifier |Access|Reset| Name | -|----|-----------------|------|-----|---------------------------| -| 7:0|rx_sample_discard| rw | 0x0 | Rx Sample Discard Value | -|15:8| rx_nco_discard | rw | 0x0 |Rx NCO Sample Discard Value| - -#### rx_sample_discard field - -

Number of Rx samples to discard

- -#### rx_nco_discard field - -

Number of NCO samples to discard

- -### LPF_Config_2 register - -- Absolute Address: 0x43C00068 -- Base Offset: 0x68 -- Size: 0x4 - -

Configures PI Controller I-gain and divisor

- -| Bits|Identifier|Access|Reset| Name | -|-----|----------|------|-----|---------------------------| -| 23:0| p_gain | rw | 0x0 | Proportional Gain Value | -|31:24| p_shift | rw | 0x0 |Proportional Gain Bit Shift| - -#### p_gain field - -

Value m of 0-16,777,215 sets the proportional multiplier

- -#### p_shift field - -

Value n of 0-32 sets the proportional divisor as 2^-n

- -### f1_nco_adjust register - -- Absolute Address: 0x43C0006C -- Base Offset: 0x6C -- Size: 0x4 - -

Frequency offet applied to the F1 NCO

- -|Bits|Identifier|Access|Reset| Name | -|----|----------|------|-----|-----------------------| -|31:0| data | r | 0x0 |F1 NCO Frequency Adjust| - -#### data field - -

Frequency offet applied to the F1 NCO

- -### f2_nco_adjust register - -- Absolute Address: 0x43C00070 -- Base Offset: 0x70 -- Size: 0x4 - -

Frequency offet applied to the F2 NCO

- -|Bits|Identifier|Access|Reset| Name | -|----|----------|------|-----|-----------------------| -|31:0| data | r | 0x0 |F2 NCO Frequency Adjust| - -#### data field - -

Frequency offet applied to the F2 NCO

- -### f1_error register - -- Absolute Address: 0x43C00074 -- Base Offset: 0x74 -- Size: 0x4 - -

Error value of the F1 Costas loop after each active bit period

- -|Bits|Identifier|Access|Reset| Name | -|----|----------|------|-----|--------------| -|31:0| data | r | 0x0 |F1 Error Value| - -#### data field - -

Error value of the F1 Costas loop after each active bit period

- -### f2_error register - -- Absolute Address: 0x43C00078 -- Base Offset: 0x78 -- Size: 0x4 - -

Error value of the F2 Costas loop after each active bit period

- -|Bits|Identifier|Access|Reset| Name | -|----|----------|------|-----|--------------| -|31:0| data | r | 0x0 |F2 Error Value| - -#### data field - -

Error value of the F2 Costas loop after each active bit period

- -### Tx_Sync_Ctrl register - -- Absolute Address: 0x43C0007C -- Base Offset: 0x7C -- Size: 0x4 - -

Provides control bits for generation of transmitter synchronization patterns

- -|Bits| Identifier |Access|Reset| Name | -|----|-------------|------|-----|-----------------| -| 0 | tx_sync_ena | rw | 0x0 | Tx Sync Enable | -| 1 |tx_sync_force| rw | 0x0 | Tx Sync Force | -| 2 | tx_sync_f1 | rw | 0x0 |Tx F1 Sync Enable| -| 3 | tx_sync_f2 | rw | 0x0 |Tx F2 Sync Enable| - -#### tx_sync_ena field - -

0 -> Disable sync transmission -1 -> Enable sync transmission when PTT is asserted

- -#### tx_sync_force field - -

0 : Normal operation) -1 : Transmit synchronization pattern)

- -#### tx_sync_f1 field - -

Enables/Disables transmission of F1 tone for receiver synchronization -0 : F1 tone transmission disabled -1 : F1 tone transmission enabled -Both F1 and F2 can be enabled at the same time

- -#### tx_sync_f2 field - -

Enables/Disables transmission of F2 tone for receiver synchronization -0 : F2 tone transmission disabled -1 : F2 tone transmission enabled -Both F1 and F2 can be enabled at the same time

- -### Tx_Sync_Cnt register - -- Absolute Address: 0x43C00080 -- Base Offset: 0x80 -- Size: 0x4 - -

Sets the duration of the synchronization tones when enabled

- -|Bits| Identifier|Access|Reset| Name | -|----|-----------|------|-----|----------------| -|23:0|tx_sync_cnt| rw | 0x0 |Tx sync duration| - -#### tx_sync_cnt field - -

Value from 0x00_0000 to 0xFF_FFFF. This value represents the number bit-times the synchronization signal should be sent after PTT is asserted.

- -### lowpass_ema_alpha1 register - -- Absolute Address: 0x43C00084 -- Base Offset: 0x84 -- Size: 0x4 - -

Sets the alpha for the EMA

- -|Bits|Identifier|Access|Reset| Name | -|----|----------|------|-----|---------| -|17:0| alpha | rw | 0x0 |EMA alpha| - -#### alpha field - -

Value from 0x0_0000 to 0x3_FFFF represent the EMA alpha

- -### lowpass_ema_alpha2 register - -- Absolute Address: 0x43C00088 -- Base Offset: 0x88 -- Size: 0x4 - -

Sets the alpha for the EMA

- -|Bits|Identifier|Access|Reset| Name | -|----|----------|------|-----|---------| -|17:0| alpha | rw | 0x0 |EMA alpha| - -#### alpha field - -

Value from 0x0_0000 to 0x3_FFFF represent the EMA alpha

- -### rx_power register - -- Absolute Address: 0x43C0008C -- Base Offset: 0x8C -- Size: 0x4 - -

Receive power computed from I/Q ssamples

- -|Bits|Identifier|Access|Reset| Name | -|----|----------|------|-----|-------------| -|22:0| rx_power | r | 0x0 |Receive Power| - -#### rx_power field - -

Value that represent the RMS power of the incoming I;

diff --git a/rdl/msk_top_regs.pdf b/rdl/msk_top_regs.pdf deleted file mode 100644 index e4168d0..0000000 Binary files a/rdl/msk_top_regs.pdf and /dev/null differ diff --git a/rdl/msk_top_regs.pl b/rdl/msk_top_regs.pl deleted file mode 100755 index 5d951b3..0000000 --- a/rdl/msk_top_regs.pl +++ /dev/null @@ -1,40 +0,0 @@ -#! /usr/bin/perl - -open(FILE, "msk_top_regs.rdl"); - -while() { - - chomp; - - s/}; \/\/ //; - - $line = "$_\n"; - - if (/^\/\/.*desyrdl/) { - $line = substr $line, 2; - } - - if (/name/) { $line = ""; } - - if (/desc/) { - $line = ""; - $eoc = 1; - } - - if (/;$/) { - if ($eoc == 1) { - $eoc = 0; - $line = ""; - } - } else { - if ($eoc == 1) { - $line = ""; - } - } - - if (/Pluto_MSK_Modem/) { last; } - - print($line); - -} -close FILE; diff --git a/rdl/msk_top_regs.rdl b/rdl/msk_top_regs.rdl deleted file mode 100644 index ebe3ec0..0000000 --- a/rdl/msk_top_regs.rdl +++ /dev/null @@ -1,408 +0,0 @@ -reg msk_hash_lo { - name = "Pluto MSK FPGA Hash ID - Lower 32-bits"; - regwidth = 32; - accesswidth = 32; - field { sw = r; hw = na; } hash_id_lo[31:0] = 0xAAAA5555; - hash_id_lo->desc = "Lower 32-bits of Pluto MSK FPGA Hash ID"; - hash_id_lo->name = "Hash ID Lower 32-bits"; -}; - -reg msk_hash_hi { - name = "Pluto MSK FPGA Hash ID - Upper 32-bits"; - regwidth = 32; - accesswidth = 32; - field { sw = r; hw = na; } hash_id_hi[31:0] = 0x5555AAAA; - hash_id_hi->desc = "Upper 32-bits of Pluto MSK FPGA Hash ID"; - hash_id_hi->name = "Hash ID Upper 32-bits"; -}; - -reg msk_init { - name = "MSK Modem Control 0"; - regwidth = 32; - desc = "Synchronous initialization of MSK Modem functions, does not affect configuration registers."; - field { sw = rw; hw=r; } txrxinit = 1; - txrxinit->desc = "0 -> Normal modem operation - 1 -> Initialize Tx and Rx"; - txrxinit->name = "Tx/Rx Init Enable"; - field { sw = rw; hw=r; } txinit = 1; - txinit->desc = "0 -> Normal Tx operation - 1 -> Initialize Tx"; - txinit->name = "Tx Init Enable"; - field { sw = rw; hw=r; } rxinit = 1; - rxinit->desc = "0 -> Normal Rx operation - 1 -> Initialize Rx"; - rxinit->name = "Rx Init Enable"; -}; - -reg msk_ctrl { - name = "MSK Modem Control 1"; - regwidth = 32; - desc = "MSK Modem Configuration and Control"; - field { sw = rw; hw = r; } ptt = 0; - ptt->desc = "0 -> PTT Disabled - 1 -> PTT Enabled"; - ptt->name = "Push-to-Talk Enable"; - field { sw = rw; hw = r; } loopback_ena = 0; - loopback_ena->desc = "0 -> Modem loopback disabled - 1 -> Modem loopback enabled"; - loopback_ena->name = "Modem Loopback Enable"; - field { sw = rw; hw = r; } rx_invert = 0; - rx_invert->desc = "0 -> Rx data normal - 1 -> Rx data inverted"; - rx_invert->name = "Rx Data Invert Enable"; - field { sw = rw; hw = r; singlepulse = true; } clear_counts = 0; - clear_counts->desc = "Clear Tx Bit Counter and Tx Enable Counter"; - clear_counts->name = "Clear Status Counters"; - field { sw = rw; hw = r; } diff_encoder_loopback = 0; - diff_encoder_loopback->desc = "0 -> Differential Encoder -> Decoder loopback disabled - 1 -> Differential Encoder -> Decoder loopback enabled"; - diff_encoder_loopback->name = "Differential Encoder -> Decoder Loopback Enable"; -}; - -reg msk_stat_0 { - name = "MSK Modem Status 0"; - desc = "Modem status bits"; - regwidth = 32; - field { sw = r; hw = w; } demod_sync_lock=0; - demod_sync_lock->desc = "Demodulator Sync Status - not currently implemented"; - demod_sync_lock->name = "Demodulator Sync Status"; - field { sw = r; hw = w; } tx_enable=0; - tx_enable->name = "AD9363 DAC Interface Tx Enable Input Active"; - tx_enable->desc = "1 -> Data to DAC Enabled - 0 -> Data to DAC Disabled"; - field { sw = r; hw = w; } rx_enable=0; - rx_enable->name = "AD9363 ADC Interface Rx Enable Input Active"; - rx_enable->desc = "1 -> Data from ADC Enabled - 0 -> Data from ADC Disabled"; - field { sw = r; hw = w; } tx_axis_valid=0; - tx_axis_valid->name = "Tx S_AXIS_VALID"; - tx_axis_valid->desc = "1 -> S_AXIS_VALID Enabled - 0 -> S_AXIS_VALID Disabled"; -}; - -reg msk_stat_1 { - name = "MSK Modem Status 1"; - desc = "Modem status data"; - regwidth = 32; - field { sw = r; hw = w; } tx_bit_counter[31:0] = 0; - tx_bit_counter->desc = "Count of data requests made by modem"; - tx_bit_counter->name = "Tx Bit Count"; -}; - -reg msk_stat_2 { - name = "MSK Modem Status 2"; - desc = "Modem status data"; - regwidth = 32; - field { sw = r; hw = w; } tx_ena_counter[31:0] = 0; - tx_ena_counter->desc = "Number of clocks on which Tx Enable is active"; - tx_ena_counter->name = "Tx Enable Count"; -}; - -reg config_nco_fw { - regwidth = 32; - field { sw = rw; hw = r; } config_data[31:0] = 0; - config_data->name = "Frequency Control Word"; - config_data->desc = "Sets the center frequency of the NCO as FW = Fn * 2^32/Fs, where Fn is the desired NCO frequency, and Fs is the NCO sample rate"; -}; - -reg rx_sample_discard { - name = "Rx Sample Discard"; - desc = "Configure samples discard operation for demodulator"; - regwidth = 32; - field { sw = rw; hw = r; } rx_sample_discard[7:0] = 0; - rx_sample_discard->desc = "Number of Rx samples to discard"; - rx_sample_discard->name = "Rx Sample Discard Value"; - field { sw = rw; hw = r; } rx_nco_discard[15:8] = 0; - rx_nco_discard->desc = "Number of NCO samples to discard"; - rx_nco_discard->name = "Rx NCO Sample Discard Value"; -}; - -reg lpf_config_0 { - name = "PI Controller Configuration and Low-pass Filter Configuration"; - desc = "Configure PI controller and low-pass filter"; - regwidth = 32; - field { sw = rw; hw = r; } lpf_freeze = 0; - lpf_freeze->name = "Freeze the accumulator's current value"; - lpf_freeze->desc = "0 -> Normal operation - 1 -> Freeze current value"; - field { sw = rw; hw = r; } lpf_zero = 0; - lpf_zero->name = "Hold the PI Accumulator at zero"; - lpf_zero->desc = "0 -> Normal operation - 1 -> Zero and hold accumulator"; - field { sw = w; hw = r; } prbs_reserved[7:2] = 0; - field { sw = rw; hw = r; } lpf_alpha[31:8] = 0; - lpf_alpha->name = "Lowpass IIR filter alpha"; - lpf_alpha->desc = "Value controls the filter rolloff"; -}; - -reg lpf_config_1 { - name = "PI Controller Configuration Configuration Register 1"; - desc = "Configures PI Controller I-gain and divisor"; - regwidth = 32; - field { sw = rw; hw = r; } i_gain[23:0] = 0; - i_gain->name = "Integral Gain Value"; - i_gain->desc = "Value m of 0-16,777,215 sets the integral multiplier"; - field { sw = rw; hw = r; } i_shift[31:24] = 0; - i_shift->name = "Integral Gain Bit Shift"; - i_shift->desc = "Value n of 0-32 sets the integral divisor as 2^-n"; -}; - -reg lpf_config_2 { - name = "PI Controller Configuration Configuration Register 2"; - desc = "Configures PI Controller I-gain and divisor"; - regwidth = 32; - field { sw = rw; hw = r; } p_gain[23:0] = 0; - p_gain->name = "Proportional Gain Value"; - p_gain->desc = "Value m of 0-16,777,215 sets the proportional multiplier"; - field { sw = rw; hw = r; } p_shift[31:24] = 0; - p_shift->name = "Proportional Gain Bit Shift"; - p_shift->desc = "Value n of 0-32 sets the proportional divisor as 2^-n"; -}; - -reg data_width { - regwidth = 32; - field { sw = rw; hw = r; } data_width[7:0] = 8; - data_width->name = "Modem input/output data width"; - data_width->desc = "Set the data width of the modem input/output"; -}; - -reg prbs_ctrl { - name = "PRBS Control 0"; - desc = "Configures operation of the PRBS Generator and Monitor"; - regwidth = 32; - field { sw = rw; hw = r; } prbs_sel = 0; - prbs_sel->name = "PRBS Data Select"; - prbs_sel->desc = "0 -> Select Normal Tx Data - 1 -> Select PRBS Tx Data"; - field { sw = w; hw = r; singlepulse = true; } prbs_error_insert = 0; - prbs_error_insert->name = "PRBS Error Insert"; - prbs_error_insert->desc = "0 -> 1 : Insert bit error in Tx data (both Normal and PRBS) - 1 -> 0 : Insert bit error in Tx data (both Normal and PRBS)"; - field { sw = w; hw = r; singlepulse = true; } prbs_clear = 0; - prbs_clear->name = "PRBS Clear Counters"; - prbs_clear->desc = "0 -> 1 : Clear PRBS Counters - 1 -> 0 : Clear PRBS Counters"; - field { sw = w; hw = r; singlepulse = true; } prbs_manual_sync = 0; - prbs_manual_sync->name = "PRBS Manual Sync"; - prbs_manual_sync->desc = "0 -> 1 : Synchronize PRBS monitor - 1 -> 0 : Synchronize PRBS monitor"; - field { sw = w; hw = r; } prbs_reserved[15:4] = 0; - field { sw = w; hw = r; } prbs_sync_threshold[31:16] = 0; - prbs_sync_threshold->name = "PRBS Auto Sync Threshold"; - prbs_sync_threshold->desc = "0 : Auto Sync Disabled - N > 0 : Auto sync after N errors"; -}; - -reg config_prbs_seed { - name = "PRBS Control 1"; - desc = "PRBS Initial State"; - regwidth = 32; - field { sw = rw; hw = r; } config_data[31:0] = 0; - config_data->name = "PRBS Seed"; - config_data->desc = "Sets the starting value of the PRBS generator"; -}; - -reg config_prbs_poly { - name = "PRBS Control 2"; - desc = "PRBS Polynomial"; - regwidth = 32; - field { sw = rw; hw = r; } config_data[31:0] = 0; - config_data->name = "PRBS Polynomial"; - config_data->desc = "Bit positions set to '1' indicate polynomial feedback positions"; -}; - -reg config_prbs_errmask { - name = "PRBS Control 3"; - desc = "PRBS Error Mask"; - regwidth = 32; - field { sw = rw; hw = r; } config_data[31:0] = 0; - config_data->name = "PRBS Error Mask"; - config_data->desc = "Bit positions set to '1' indicate bits that are inverted when a bit error is inserted"; -}; - -reg stat_32_bits { - name = "PRBS Status 0"; - desc = "PRBS Bits Received"; - regwidth = 32; - field { sw = r; hw = w; } status_data[31:0] = 0; - status_data->name = "PRBS Bits Received"; - status_data->desc = "Number of bits received by the PRBS monitor since last - BER can be calculated as the ratio of received bits to errored-bits"; -}; - -reg stat_32_errs { - name = "PRBS Status 1"; - desc = "PRBS Bit Errors"; - regwidth = 32; - field { sw = r; hw = w; } status_data[31:0] = 0; - status_data->name = "PRBS Bit Errors"; - status_data->desc = "Number of errored-bits received by the PRBS monitor since last sync - BER can be calculated as the ratio of received bits to errored-bits"; -}; - -reg stat_32_lpf_acc { - regwidth = 32; - field { sw = r; hw = w; } status_data[31:0] = 0; - status_data->name = "PI Controller Accumulator Value"; - status_data->desc = "PI Controller Accumulator Value"; -}; - -reg msk_stat_3 { - name = "MSK Modem Status 3"; - desc = "Modem status data"; - regwidth = 32; - field { sw = r; hw = w; } xfer_count[31:0] = 0; - xfer_count->desc = "Number completed S_AXIS transfers"; - xfer_count->name = "S_AXIS Transfers"; -}; - -reg tx_sync_ctrl { - name = "Transmitter Sync Control"; - desc = "Provides control bits for generation of transmitter synchronization patterns"; - regwidth = 32; - field { sw = rw; hw = r; } tx_sync_ena = 0; - tx_sync_ena->name = "Tx Sync Enable"; - tx_sync_ena->desc = "0 -> Disable sync transmission - 1 -> Enable sync transmission when PTT is asserted"; - field { sw = rw; hw = r; } tx_sync_force = 0; - tx_sync_force->name = "Tx Sync Force"; - tx_sync_force->desc = "0 : Normal operation) - 1 : Transmit synchronization pattern)"; - field { sw = rw; hw = r; } tx_sync_f1 = 0; - tx_sync_f1->name = "Tx F1 Sync Enable"; - tx_sync_f1->desc = "Enables/Disables transmission of F1 tone for receiver synchronization - 0 : F1 tone transmission disabled - 1 : F1 tone transmission enabled - Both F1 and F2 can be enabled at the same time"; - field { sw = rw; hw = r; } tx_sync_f2 = 0; - tx_sync_f2->name = "Tx F2 Sync Enable"; - tx_sync_f2->desc = "Enables/Disables transmission of F2 tone for receiver synchronization - 0 : F2 tone transmission disabled - 1 : F2 tone transmission enabled - Both F1 and F2 can be enabled at the same time"; -}; - -reg tx_sync_cnt { - name = "Transmitter Sync Duration"; - desc = "Sets the duration of the synchronization tones when enabled"; - regwidth = 32; - field { sw = rw; hw = r; } tx_sync_cnt[23:0] = 0; - tx_sync_cnt->name = "Tx sync duration"; - tx_sync_cnt->desc = "Value from 0x00_0000 to 0xFF_FFFF. This value represents the number bit-times the synchronization signal should be sent after PTT is asserted."; -}; - -reg lowpass_ema_alpha { - name = "Exponential Moving Average Alpha"; - desc = "Sets the alpha for the EMA"; - regwidth = 32; - field { sw = rw; hw = r; } alpha[17:0] = 0; - alpha->name = "EMA alpha"; - alpha->desc = "Value from 0x0_0000 to 0x3_FFFF represent the EMA alpha"; -}; - -reg rx_power { - name = "Receive Power"; - desc = "Receive power computed from I/Q ssamples"; - regwidth = 32; - field { sw = r; hw = w; } rx_power[22:0] = 0; - rx_power->name = "Receive Power"; - rx_power->desc = "Value that represent the RMS power of the incoming I;"; -}; - -field data32 { - fieldwidth = 32; - sw = r; - hw = w; -}; - -reg observation_data { - regwidth = 32; - data32 data[31:0] = 0; -}; - -addrmap msk_top_regs { - name="Pluto MSK Registers"; - desc="MSK Modem Configuration and Status Registers"; - lsb0; - default accesswidth=32; - addressing=compact; - -// desyrdl_interface = "AXI4L"; -// desyrdl_access_channel = 0; - - msk_hash_lo Hash_ID_Low; - msk_hash_hi Hash_ID_High; - msk_init MSK_Init; - msk_ctrl MSK_Control; - msk_stat_0 MSK_Status; - msk_stat_1 Tx_Bit_Count; - msk_stat_2 Tx_Enable_Count; - config_nco_fw Fb_FreqWord; - Fb_FreqWord->desc = "Set Modem Data Rate"; - Fb_FreqWord->name = "Bitrate NCO Frequency Control Word"; - config_nco_fw TX_F1_FreqWord; - TX_F1_FreqWord->desc = "Set Modulator F1 Frequency"; - TX_F1_FreqWord->name = "Tx F1 NCO Frequency Control Word"; - config_nco_fw TX_F2_FreqWord; - TX_F2_FreqWord->desc = "Set Modulator F2 Frequency"; - TX_F2_FreqWord->name = "Tx F2 NCO Frequency Control Word"; - config_nco_fw RX_F1_FreqWord; - RX_F1_FreqWord->desc = "Set Demodulator F1 Frequency"; - RX_F1_FreqWord->name = "Rx F1 NCO Frequency Control Word"; - config_nco_fw RX_F2_FreqWord; - RX_F2_FreqWord->desc = "Set Demodulator F2 Frequency"; - RX_F2_FreqWord->name = "Rx F2 NCO Frequency Control Word"; - lpf_config_0 LPF_Config_0; - lpf_config_1 LPF_Config_1; - data_width Tx_Data_Width; - Tx_Data_Width->desc = "Set the parallel data width of the parallel-to-serial converter"; - Tx_Data_Width->name = "Modem Tx Input Data Width"; - data_width Rx_Data_Width; - Rx_Data_Width->desc = "Set the parallel data width of the serial-to-parallel converter"; - Rx_Data_Width->name = "Modem Rx Output Data Width"; - prbs_ctrl PRBS_Control; - config_prbs_seed PRBS_Initial_State; - config_prbs_poly PRBS_Polynomial; - config_prbs_errmask PRBS_Error_Mask; - stat_32_bits PRBS_Bit_Count; - stat_32_errs PRBS_Error_Count; - stat_32_lpf_acc LPF_Accum_F1; - LPF_Accum_F1->name = "F1 PI Controller Accumulator"; - LPF_Accum_F1->desc = "Value of the F1 PI Controller Accumulator"; - stat_32_lpf_acc LPF_Accum_F2; - LPF_Accum_F2->name = "F2 PI Controller Accumulator"; - LPF_Accum_F2->desc = "Value of the F2 PI Controller Accumulator"; - msk_stat_3 axis_xfer_count; - rx_sample_discard Rx_Sample_Discard; - lpf_config_2 LPF_Config_2; - observation_data f1_nco_adjust; - f1_nco_adjust->name = "F1 NCO Frequency Adjust"; - f1_nco_adjust->desc = "Frequency offet applied to the F1 NCO"; - f1_nco_adjust.data->name = "F1 NCO Frequency Adjust"; - f1_nco_adjust.data->desc = "Frequency offet applied to the F1 NCO"; - observation_data f2_nco_adjust; - f2_nco_adjust->name = "F2 NCO Frequency Adjust"; - f2_nco_adjust->desc = "Frequency offet applied to the F2 NCO"; - f2_nco_adjust.data->name = "F2 NCO Frequency Adjust"; - f2_nco_adjust.data->desc = "Frequency offet applied to the F2 NCO"; - observation_data f1_error; - f1_error->name = "F1 Error Value"; - f1_error->desc = "Error value of the F1 Costas loop after each active bit period"; - f1_error.data->name = "F1 Error Value"; - f1_error.data->desc = "Error value of the F1 Costas loop after each active bit period"; - observation_data f2_error; - f2_error->name = "F2 Error Value"; - f2_error->desc = "Error value of the F2 Costas loop after each active bit period"; - f2_error.data->name = "F2 Error Value"; - f2_error.data->desc = "Error value of the F2 Costas loop after each active bit period"; - tx_sync_ctrl Tx_Sync_Ctrl; - tx_sync_cnt Tx_Sync_Cnt; - lowpass_ema_alpha lowpass_ema_alpha1; - lowpass_ema_alpha lowpass_ema_alpha2; - rx_power rx_power; - -}; - -addrmap Pluto_MSK_Modem { - msk_top_regs pluto_msk_regs @0x43C00000; -}; diff --git a/rdl/msk_top_regs_desy.rdl b/rdl/msk_top_regs_desy.rdl deleted file mode 100644 index 3204600..0000000 --- a/rdl/msk_top_regs_desy.rdl +++ /dev/null @@ -1,208 +0,0 @@ -reg msk_hash_lo { - regwidth = 32; - accesswidth = 32; - field { sw = r; hw = na; } hash_id_lo[31:0] = 0xAAAA5555; -}; - -reg msk_hash_hi { - regwidth = 32; - accesswidth = 32; - field { sw = r; hw = na; } hash_id_hi[31:0] = 0x5555AAAA; -}; - -reg msk_init { - regwidth = 32; - field { sw = rw; hw=r; } txrxinit = 1; - field { sw = rw; hw=r; } txinit = 1; - field { sw = rw; hw=r; } rxinit = 1; -}; - -reg msk_ctrl { - regwidth = 32; - field { sw = rw; hw = r; } ptt = 0; - field { sw = rw; hw = r; } loopback_ena = 0; - field { sw = rw; hw = r; } rx_invert = 0; - field { sw = rw; hw = r; singlepulse = true; } clear_counts = 0; - field { sw = rw; hw = r; } diff_encoder_loopback = 0; -}; - -reg msk_stat_0 { - regwidth = 32; - field { sw = r; hw = w; } demod_sync_lock=0; - field { sw = r; hw = w; } tx_enable=0; - field { sw = r; hw = w; } rx_enable=0; - field { sw = r; hw = w; } tx_axis_valid=0; -}; - -reg msk_stat_1 { - regwidth = 32; - field { sw = r; hw = w; } tx_bit_counter[31:0] = 0; -}; - -reg msk_stat_2 { - regwidth = 32; - field { sw = r; hw = w; } tx_ena_counter[31:0] = 0; -}; - -reg config_nco_fw { - regwidth = 32; - field { sw = rw; hw = r; } config_data[31:0] = 0; -}; - -reg rx_sample_discard { - regwidth = 32; - field { sw = rw; hw = r; } rx_sample_discard[7:0] = 0; - field { sw = rw; hw = r; } rx_nco_discard[15:8] = 0; -}; - -reg lpf_config_0 { - regwidth = 32; - field { sw = rw; hw = r; } lpf_freeze = 0; - field { sw = rw; hw = r; } lpf_zero = 0; - field { sw = w; hw = r; } prbs_reserved[7:2] = 0; - field { sw = rw; hw = r; } lpf_alpha[31:8] = 0; -}; - -reg lpf_config_1 { - regwidth = 32; - field { sw = rw; hw = r; } i_gain[23:0] = 0; - field { sw = rw; hw = r; } i_shift[31:24] = 0; -}; - -reg lpf_config_2 { - regwidth = 32; - field { sw = rw; hw = r; } p_gain[23:0] = 0; - field { sw = rw; hw = r; } p_shift[31:24] = 0; -}; - -reg data_width { - regwidth = 32; - field { sw = rw; hw = r; } data_width[7:0] = 8; -}; - -reg prbs_ctrl { - regwidth = 32; - field { sw = rw; hw = r; } prbs_sel = 0; - field { sw = w; hw = r; singlepulse = true; } prbs_error_insert = 0; - field { sw = w; hw = r; singlepulse = true; } prbs_clear = 0; - field { sw = w; hw = r; singlepulse = true; } prbs_manual_sync = 0; - field { sw = w; hw = r; } prbs_reserved[15:4] = 0; - field { sw = w; hw = r; } prbs_sync_threshold[31:16] = 0; -}; - -reg config_prbs_seed { - regwidth = 32; - field { sw = rw; hw = r; } config_data[31:0] = 0; -}; - -reg config_prbs_poly { - regwidth = 32; - field { sw = rw; hw = r; } config_data[31:0] = 0; -}; - -reg config_prbs_errmask { - regwidth = 32; - field { sw = rw; hw = r; } config_data[31:0] = 0; -}; - -reg stat_32_bits { - regwidth = 32; - field { sw = r; hw = w; } status_data[31:0] = 0; -}; - -reg stat_32_errs { - regwidth = 32; - field { sw = r; hw = w; } status_data[31:0] = 0; -}; - -reg stat_32_lpf_acc { - regwidth = 32; - field { sw = r; hw = w; } status_data[31:0] = 0; -}; - -reg msk_stat_3 { - regwidth = 32; - field { sw = r; hw = w; } xfer_count[31:0] = 0; -}; - -reg tx_sync_ctrl { - regwidth = 32; - field { sw = rw; hw = r; } tx_sync_ena = 0; - field { sw = rw; hw = r; } tx_sync_force = 0; - field { sw = rw; hw = r; } tx_sync_f1 = 0; - field { sw = rw; hw = r; } tx_sync_f2 = 0; -}; - -reg tx_sync_cnt { - regwidth = 32; - field { sw = rw; hw = r; } tx_sync_cnt[23:0] = 0; -}; - -reg lowpass_ema_alpha { - regwidth = 32; - field { sw = rw; hw = r; } alpha[17:0] = 0; -}; - -reg rx_power { - regwidth = 32; - field { sw = r; hw = w; } rx_power[22:0] = 0; -}; - -field data32 { - fieldwidth = 32; - sw = r; - hw = w; -}; - -reg observation_data { - regwidth = 32; - data32 data[31:0] = 0; -}; - -addrmap msk_top_regs { - lsb0; - default accesswidth=32; - addressing=compact; - - desyrdl_interface = "AXI4L"; - desyrdl_access_channel = 0; - - msk_hash_lo Hash_ID_Low; - msk_hash_hi Hash_ID_High; - msk_init MSK_Init; - msk_ctrl MSK_Control; - msk_stat_0 MSK_Status; - msk_stat_1 Tx_Bit_Count; - msk_stat_2 Tx_Enable_Count; - config_nco_fw Fb_FreqWord; - config_nco_fw TX_F1_FreqWord; - config_nco_fw TX_F2_FreqWord; - config_nco_fw RX_F1_FreqWord; - config_nco_fw RX_F2_FreqWord; - lpf_config_0 LPF_Config_0; - lpf_config_1 LPF_Config_1; - data_width Tx_Data_Width; - data_width Rx_Data_Width; - prbs_ctrl PRBS_Control; - config_prbs_seed PRBS_Initial_State; - config_prbs_poly PRBS_Polynomial; - config_prbs_errmask PRBS_Error_Mask; - stat_32_bits PRBS_Bit_Count; - stat_32_errs PRBS_Error_Count; - stat_32_lpf_acc LPF_Accum_F1; - stat_32_lpf_acc LPF_Accum_F2; - msk_stat_3 axis_xfer_count; - rx_sample_discard Rx_Sample_Discard; - lpf_config_2 LPF_Config_2; - observation_data f1_nco_adjust; - observation_data f2_nco_adjust; - observation_data f1_error; - observation_data f2_error; - tx_sync_ctrl Tx_Sync_Ctrl; - tx_sync_cnt Tx_Sync_Cnt; - lowpass_ema_alpha lowpass_ema_alpha1; - lowpass_ema_alpha lowpass_ema_alpha2; - rx_power rx_power; - -}; - diff --git a/rdl/outputs/c-header/msk_top_regs.h b/rdl/outputs/c-header/msk_top_regs.h new file mode 100644 index 0000000..a26ed30 --- /dev/null +++ b/rdl/outputs/c-header/msk_top_regs.h @@ -0,0 +1,388 @@ +// Generated by PeakRDL-cheader - A free and open-source header generator +// https://github.com/SystemRDL/PeakRDL-cheader + +#ifndef MSK_TOP_REGS_H +#define MSK_TOP_REGS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +// Reg - msk_top_regs::msk_hash_lo +#define MSK_TOP_REGS__MSK_HASH_LO__HASH_ID_LO_bm 0xffffffff +#define MSK_TOP_REGS__MSK_HASH_LO__HASH_ID_LO_bp 0 +#define MSK_TOP_REGS__MSK_HASH_LO__HASH_ID_LO_bw 32 +#define MSK_TOP_REGS__MSK_HASH_LO__HASH_ID_LO_reset 0xaaaa5555 + +// Reg - msk_top_regs::msk_hash_hi +#define MSK_TOP_REGS__MSK_HASH_HI__HASH_ID_HI_bm 0xffffffff +#define MSK_TOP_REGS__MSK_HASH_HI__HASH_ID_HI_bp 0 +#define MSK_TOP_REGS__MSK_HASH_HI__HASH_ID_HI_bw 32 +#define MSK_TOP_REGS__MSK_HASH_HI__HASH_ID_HI_reset 0x5555aaaa + +// Reg - msk_top_regs::msk_init +#define MSK_TOP_REGS__MSK_INIT__TXRXINIT_bm 0x1 +#define MSK_TOP_REGS__MSK_INIT__TXRXINIT_bp 0 +#define MSK_TOP_REGS__MSK_INIT__TXRXINIT_bw 1 +#define MSK_TOP_REGS__MSK_INIT__TXRXINIT_reset 0x1 +#define MSK_TOP_REGS__MSK_INIT__TXINIT_bm 0x2 +#define MSK_TOP_REGS__MSK_INIT__TXINIT_bp 1 +#define MSK_TOP_REGS__MSK_INIT__TXINIT_bw 1 +#define MSK_TOP_REGS__MSK_INIT__TXINIT_reset 0x1 +#define MSK_TOP_REGS__MSK_INIT__RXINIT_bm 0x4 +#define MSK_TOP_REGS__MSK_INIT__RXINIT_bp 2 +#define MSK_TOP_REGS__MSK_INIT__RXINIT_bw 1 +#define MSK_TOP_REGS__MSK_INIT__RXINIT_reset 0x1 + +// Reg - msk_top_regs::msk_ctrl +#define MSK_TOP_REGS__MSK_CTRL__PTT_bm 0x1 +#define MSK_TOP_REGS__MSK_CTRL__PTT_bp 0 +#define MSK_TOP_REGS__MSK_CTRL__PTT_bw 1 +#define MSK_TOP_REGS__MSK_CTRL__PTT_reset 0x0 +#define MSK_TOP_REGS__MSK_CTRL__LOOPBACK_ENA_bm 0x2 +#define MSK_TOP_REGS__MSK_CTRL__LOOPBACK_ENA_bp 1 +#define MSK_TOP_REGS__MSK_CTRL__LOOPBACK_ENA_bw 1 +#define MSK_TOP_REGS__MSK_CTRL__LOOPBACK_ENA_reset 0x0 +#define MSK_TOP_REGS__MSK_CTRL__RX_INVERT_bm 0x4 +#define MSK_TOP_REGS__MSK_CTRL__RX_INVERT_bp 2 +#define MSK_TOP_REGS__MSK_CTRL__RX_INVERT_bw 1 +#define MSK_TOP_REGS__MSK_CTRL__RX_INVERT_reset 0x0 +#define MSK_TOP_REGS__MSK_CTRL__CLEAR_COUNTS_bm 0x8 +#define MSK_TOP_REGS__MSK_CTRL__CLEAR_COUNTS_bp 3 +#define MSK_TOP_REGS__MSK_CTRL__CLEAR_COUNTS_bw 1 +#define MSK_TOP_REGS__MSK_CTRL__CLEAR_COUNTS_reset 0x0 +#define MSK_TOP_REGS__MSK_CTRL__DIFF_ENCODER_LOOPBACK_bm 0x10 +#define MSK_TOP_REGS__MSK_CTRL__DIFF_ENCODER_LOOPBACK_bp 4 +#define MSK_TOP_REGS__MSK_CTRL__DIFF_ENCODER_LOOPBACK_bw 1 +#define MSK_TOP_REGS__MSK_CTRL__DIFF_ENCODER_LOOPBACK_reset 0x0 + +// Reg - msk_top_regs::msk_stat_0 +#define MSK_TOP_REGS__MSK_STAT_0__DEMOD_SYNC_LOCK_bm 0x1 +#define MSK_TOP_REGS__MSK_STAT_0__DEMOD_SYNC_LOCK_bp 0 +#define MSK_TOP_REGS__MSK_STAT_0__DEMOD_SYNC_LOCK_bw 1 +#define MSK_TOP_REGS__MSK_STAT_0__DEMOD_SYNC_LOCK_reset 0x0 +#define MSK_TOP_REGS__MSK_STAT_0__TX_ENABLE_bm 0x2 +#define MSK_TOP_REGS__MSK_STAT_0__TX_ENABLE_bp 1 +#define MSK_TOP_REGS__MSK_STAT_0__TX_ENABLE_bw 1 +#define MSK_TOP_REGS__MSK_STAT_0__TX_ENABLE_reset 0x0 +#define MSK_TOP_REGS__MSK_STAT_0__RX_ENABLE_bm 0x4 +#define MSK_TOP_REGS__MSK_STAT_0__RX_ENABLE_bp 2 +#define MSK_TOP_REGS__MSK_STAT_0__RX_ENABLE_bw 1 +#define MSK_TOP_REGS__MSK_STAT_0__RX_ENABLE_reset 0x0 +#define MSK_TOP_REGS__MSK_STAT_0__TX_AXIS_VALID_bm 0x8 +#define MSK_TOP_REGS__MSK_STAT_0__TX_AXIS_VALID_bp 3 +#define MSK_TOP_REGS__MSK_STAT_0__TX_AXIS_VALID_bw 1 +#define MSK_TOP_REGS__MSK_STAT_0__TX_AXIS_VALID_reset 0x0 + +// Reg - msk_top_regs::msk_stat_1 +#define MSK_TOP_REGS__MSK_STAT_1__DATA_bm 0xffffffff +#define MSK_TOP_REGS__MSK_STAT_1__DATA_bp 0 +#define MSK_TOP_REGS__MSK_STAT_1__DATA_bw 32 +#define MSK_TOP_REGS__MSK_STAT_1__DATA_reset 0x0 + +// Reg - msk_top_regs::msk_stat_2 +#define MSK_TOP_REGS__MSK_STAT_2__DATA_bm 0xffffffff +#define MSK_TOP_REGS__MSK_STAT_2__DATA_bp 0 +#define MSK_TOP_REGS__MSK_STAT_2__DATA_bw 32 +#define MSK_TOP_REGS__MSK_STAT_2__DATA_reset 0x0 + +// Reg - msk_top_regs::config_nco_fw_desc_c4924cc6_name_0c494469 +#define MSK_TOP_REGS__CONFIG_NCO_FW_DESC_C4924CC6_NAME_0C494469__CONFIG_DATA_bm 0xffffffff +#define MSK_TOP_REGS__CONFIG_NCO_FW_DESC_C4924CC6_NAME_0C494469__CONFIG_DATA_bp 0 +#define MSK_TOP_REGS__CONFIG_NCO_FW_DESC_C4924CC6_NAME_0C494469__CONFIG_DATA_bw 32 +#define MSK_TOP_REGS__CONFIG_NCO_FW_DESC_C4924CC6_NAME_0C494469__CONFIG_DATA_reset 0x0 + +// Reg - msk_top_regs::config_nco_fw_desc_94d7aaf5_name_84dd0c1c +#define MSK_TOP_REGS__CONFIG_NCO_FW_DESC_94D7AAF5_NAME_84DD0C1C__CONFIG_DATA_bm 0xffffffff +#define MSK_TOP_REGS__CONFIG_NCO_FW_DESC_94D7AAF5_NAME_84DD0C1C__CONFIG_DATA_bp 0 +#define MSK_TOP_REGS__CONFIG_NCO_FW_DESC_94D7AAF5_NAME_84DD0C1C__CONFIG_DATA_bw 32 +#define MSK_TOP_REGS__CONFIG_NCO_FW_DESC_94D7AAF5_NAME_84DD0C1C__CONFIG_DATA_reset 0x0 + +// Reg - msk_top_regs::config_nco_fw_desc_42134a4f_name_d97dbd51 +#define MSK_TOP_REGS__CONFIG_NCO_FW_DESC_42134A4F_NAME_D97DBD51__CONFIG_DATA_bm 0xffffffff +#define MSK_TOP_REGS__CONFIG_NCO_FW_DESC_42134A4F_NAME_D97DBD51__CONFIG_DATA_bp 0 +#define MSK_TOP_REGS__CONFIG_NCO_FW_DESC_42134A4F_NAME_D97DBD51__CONFIG_DATA_bw 32 +#define MSK_TOP_REGS__CONFIG_NCO_FW_DESC_42134A4F_NAME_D97DBD51__CONFIG_DATA_reset 0x0 + +// Reg - msk_top_regs::config_nco_fw_desc_16fb48c8_name_8d01a20d +#define MSK_TOP_REGS__CONFIG_NCO_FW_DESC_16FB48C8_NAME_8D01A20D__CONFIG_DATA_bm 0xffffffff +#define MSK_TOP_REGS__CONFIG_NCO_FW_DESC_16FB48C8_NAME_8D01A20D__CONFIG_DATA_bp 0 +#define MSK_TOP_REGS__CONFIG_NCO_FW_DESC_16FB48C8_NAME_8D01A20D__CONFIG_DATA_bw 32 +#define MSK_TOP_REGS__CONFIG_NCO_FW_DESC_16FB48C8_NAME_8D01A20D__CONFIG_DATA_reset 0x0 + +// Reg - msk_top_regs::config_nco_fw_desc_43c0828f_name_bdc60ecf +#define MSK_TOP_REGS__CONFIG_NCO_FW_DESC_43C0828F_NAME_BDC60ECF__CONFIG_DATA_bm 0xffffffff +#define MSK_TOP_REGS__CONFIG_NCO_FW_DESC_43C0828F_NAME_BDC60ECF__CONFIG_DATA_bp 0 +#define MSK_TOP_REGS__CONFIG_NCO_FW_DESC_43C0828F_NAME_BDC60ECF__CONFIG_DATA_bw 32 +#define MSK_TOP_REGS__CONFIG_NCO_FW_DESC_43C0828F_NAME_BDC60ECF__CONFIG_DATA_reset 0x0 + +// Reg - msk_top_regs::lpf_config_0 +#define MSK_TOP_REGS__LPF_CONFIG_0__LPF_FREEZE_bm 0x1 +#define MSK_TOP_REGS__LPF_CONFIG_0__LPF_FREEZE_bp 0 +#define MSK_TOP_REGS__LPF_CONFIG_0__LPF_FREEZE_bw 1 +#define MSK_TOP_REGS__LPF_CONFIG_0__LPF_FREEZE_reset 0x0 +#define MSK_TOP_REGS__LPF_CONFIG_0__LPF_ZERO_bm 0x2 +#define MSK_TOP_REGS__LPF_CONFIG_0__LPF_ZERO_bp 1 +#define MSK_TOP_REGS__LPF_CONFIG_0__LPF_ZERO_bw 1 +#define MSK_TOP_REGS__LPF_CONFIG_0__LPF_ZERO_reset 0x0 +#define MSK_TOP_REGS__LPF_CONFIG_0__PRBS_RESERVED_bm 0xfc +#define MSK_TOP_REGS__LPF_CONFIG_0__PRBS_RESERVED_bp 2 +#define MSK_TOP_REGS__LPF_CONFIG_0__PRBS_RESERVED_bw 6 +#define MSK_TOP_REGS__LPF_CONFIG_0__PRBS_RESERVED_reset 0x0 +#define MSK_TOP_REGS__LPF_CONFIG_0__LPF_ALPHA_bm 0xffffff00 +#define MSK_TOP_REGS__LPF_CONFIG_0__LPF_ALPHA_bp 8 +#define MSK_TOP_REGS__LPF_CONFIG_0__LPF_ALPHA_bw 24 +#define MSK_TOP_REGS__LPF_CONFIG_0__LPF_ALPHA_reset 0x0 + +// Reg - msk_top_regs::lpf_config_1 +#define MSK_TOP_REGS__LPF_CONFIG_1__I_GAIN_bm 0xffffff +#define MSK_TOP_REGS__LPF_CONFIG_1__I_GAIN_bp 0 +#define MSK_TOP_REGS__LPF_CONFIG_1__I_GAIN_bw 24 +#define MSK_TOP_REGS__LPF_CONFIG_1__I_GAIN_reset 0x0 +#define MSK_TOP_REGS__LPF_CONFIG_1__I_SHIFT_bm 0xff000000 +#define MSK_TOP_REGS__LPF_CONFIG_1__I_SHIFT_bp 24 +#define MSK_TOP_REGS__LPF_CONFIG_1__I_SHIFT_bw 8 +#define MSK_TOP_REGS__LPF_CONFIG_1__I_SHIFT_reset 0x0 + +// Reg - msk_top_regs::data_width_desc_58c848dd_name_2fbd8eba +#define MSK_TOP_REGS__DATA_WIDTH_DESC_58C848DD_NAME_2FBD8EBA__DATA_WIDTH_bm 0xff +#define MSK_TOP_REGS__DATA_WIDTH_DESC_58C848DD_NAME_2FBD8EBA__DATA_WIDTH_bp 0 +#define MSK_TOP_REGS__DATA_WIDTH_DESC_58C848DD_NAME_2FBD8EBA__DATA_WIDTH_bw 8 +#define MSK_TOP_REGS__DATA_WIDTH_DESC_58C848DD_NAME_2FBD8EBA__DATA_WIDTH_reset 0x8 + +// Reg - msk_top_regs::data_width_desc_6097df38_name_4609588b +#define MSK_TOP_REGS__DATA_WIDTH_DESC_6097DF38_NAME_4609588B__DATA_WIDTH_bm 0xff +#define MSK_TOP_REGS__DATA_WIDTH_DESC_6097DF38_NAME_4609588B__DATA_WIDTH_bp 0 +#define MSK_TOP_REGS__DATA_WIDTH_DESC_6097DF38_NAME_4609588B__DATA_WIDTH_bw 8 +#define MSK_TOP_REGS__DATA_WIDTH_DESC_6097DF38_NAME_4609588B__DATA_WIDTH_reset 0x8 + +// Reg - msk_top_regs::prbs_ctrl +#define MSK_TOP_REGS__PRBS_CTRL__PRBS_SEL_bm 0x1 +#define MSK_TOP_REGS__PRBS_CTRL__PRBS_SEL_bp 0 +#define MSK_TOP_REGS__PRBS_CTRL__PRBS_SEL_bw 1 +#define MSK_TOP_REGS__PRBS_CTRL__PRBS_SEL_reset 0x0 +#define MSK_TOP_REGS__PRBS_CTRL__PRBS_ERROR_INSERT_bm 0x2 +#define MSK_TOP_REGS__PRBS_CTRL__PRBS_ERROR_INSERT_bp 1 +#define MSK_TOP_REGS__PRBS_CTRL__PRBS_ERROR_INSERT_bw 1 +#define MSK_TOP_REGS__PRBS_CTRL__PRBS_ERROR_INSERT_reset 0x0 +#define MSK_TOP_REGS__PRBS_CTRL__PRBS_CLEAR_bm 0x4 +#define MSK_TOP_REGS__PRBS_CTRL__PRBS_CLEAR_bp 2 +#define MSK_TOP_REGS__PRBS_CTRL__PRBS_CLEAR_bw 1 +#define MSK_TOP_REGS__PRBS_CTRL__PRBS_CLEAR_reset 0x0 +#define MSK_TOP_REGS__PRBS_CTRL__PRBS_MANUAL_SYNC_bm 0x8 +#define MSK_TOP_REGS__PRBS_CTRL__PRBS_MANUAL_SYNC_bp 3 +#define MSK_TOP_REGS__PRBS_CTRL__PRBS_MANUAL_SYNC_bw 1 +#define MSK_TOP_REGS__PRBS_CTRL__PRBS_MANUAL_SYNC_reset 0x0 +#define MSK_TOP_REGS__PRBS_CTRL__PRBS_RESERVED_bm 0xfff0 +#define MSK_TOP_REGS__PRBS_CTRL__PRBS_RESERVED_bp 4 +#define MSK_TOP_REGS__PRBS_CTRL__PRBS_RESERVED_bw 12 +#define MSK_TOP_REGS__PRBS_CTRL__PRBS_RESERVED_reset 0x0 +#define MSK_TOP_REGS__PRBS_CTRL__PRBS_SYNC_THRESHOLD_bm 0xffff0000 +#define MSK_TOP_REGS__PRBS_CTRL__PRBS_SYNC_THRESHOLD_bp 16 +#define MSK_TOP_REGS__PRBS_CTRL__PRBS_SYNC_THRESHOLD_bw 16 +#define MSK_TOP_REGS__PRBS_CTRL__PRBS_SYNC_THRESHOLD_reset 0x0 + +// Reg - msk_top_regs::config_prbs_seed +#define MSK_TOP_REGS__CONFIG_PRBS_SEED__CONFIG_DATA_bm 0xffffffff +#define MSK_TOP_REGS__CONFIG_PRBS_SEED__CONFIG_DATA_bp 0 +#define MSK_TOP_REGS__CONFIG_PRBS_SEED__CONFIG_DATA_bw 32 +#define MSK_TOP_REGS__CONFIG_PRBS_SEED__CONFIG_DATA_reset 0x0 + +// Reg - msk_top_regs::config_prbs_poly +#define MSK_TOP_REGS__CONFIG_PRBS_POLY__CONFIG_DATA_bm 0xffffffff +#define MSK_TOP_REGS__CONFIG_PRBS_POLY__CONFIG_DATA_bp 0 +#define MSK_TOP_REGS__CONFIG_PRBS_POLY__CONFIG_DATA_bw 32 +#define MSK_TOP_REGS__CONFIG_PRBS_POLY__CONFIG_DATA_reset 0x0 + +// Reg - msk_top_regs::config_prbs_errmask +#define MSK_TOP_REGS__CONFIG_PRBS_ERRMASK__CONFIG_DATA_bm 0xffffffff +#define MSK_TOP_REGS__CONFIG_PRBS_ERRMASK__CONFIG_DATA_bp 0 +#define MSK_TOP_REGS__CONFIG_PRBS_ERRMASK__CONFIG_DATA_bw 32 +#define MSK_TOP_REGS__CONFIG_PRBS_ERRMASK__CONFIG_DATA_reset 0x0 + +// Reg - msk_top_regs::stat_32_bits +#define MSK_TOP_REGS__STAT_32_BITS__DATA_bm 0xffffffff +#define MSK_TOP_REGS__STAT_32_BITS__DATA_bp 0 +#define MSK_TOP_REGS__STAT_32_BITS__DATA_bw 32 +#define MSK_TOP_REGS__STAT_32_BITS__DATA_reset 0x0 + +// Reg - msk_top_regs::stat_32_errs +#define MSK_TOP_REGS__STAT_32_ERRS__DATA_bm 0xffffffff +#define MSK_TOP_REGS__STAT_32_ERRS__DATA_bp 0 +#define MSK_TOP_REGS__STAT_32_ERRS__DATA_bw 32 +#define MSK_TOP_REGS__STAT_32_ERRS__DATA_reset 0x0 + +// Reg - msk_top_regs::stat_32_lpf_acc_desc_8cebc7dc_name_f20c6670 +#define MSK_TOP_REGS__STAT_32_LPF_ACC_DESC_8CEBC7DC_NAME_F20C6670__DATA_bm 0xffffffff +#define MSK_TOP_REGS__STAT_32_LPF_ACC_DESC_8CEBC7DC_NAME_F20C6670__DATA_bp 0 +#define MSK_TOP_REGS__STAT_32_LPF_ACC_DESC_8CEBC7DC_NAME_F20C6670__DATA_bw 32 +#define MSK_TOP_REGS__STAT_32_LPF_ACC_DESC_8CEBC7DC_NAME_F20C6670__DATA_reset 0x0 + +// Reg - msk_top_regs::stat_32_lpf_acc_desc_dea6bd99_name_758fd0ce +#define MSK_TOP_REGS__STAT_32_LPF_ACC_DESC_DEA6BD99_NAME_758FD0CE__DATA_bm 0xffffffff +#define MSK_TOP_REGS__STAT_32_LPF_ACC_DESC_DEA6BD99_NAME_758FD0CE__DATA_bp 0 +#define MSK_TOP_REGS__STAT_32_LPF_ACC_DESC_DEA6BD99_NAME_758FD0CE__DATA_bw 32 +#define MSK_TOP_REGS__STAT_32_LPF_ACC_DESC_DEA6BD99_NAME_758FD0CE__DATA_reset 0x0 + +// Reg - msk_top_regs::msk_stat_3 +#define MSK_TOP_REGS__MSK_STAT_3__DATA_bm 0xffffffff +#define MSK_TOP_REGS__MSK_STAT_3__DATA_bp 0 +#define MSK_TOP_REGS__MSK_STAT_3__DATA_bw 32 +#define MSK_TOP_REGS__MSK_STAT_3__DATA_reset 0x0 + +// Reg - msk_top_regs::rx_sample_discard +#define MSK_TOP_REGS__RX_SAMPLE_DISCARD__RX_SAMPLE_DISCARD_bm 0xff +#define MSK_TOP_REGS__RX_SAMPLE_DISCARD__RX_SAMPLE_DISCARD_bp 0 +#define MSK_TOP_REGS__RX_SAMPLE_DISCARD__RX_SAMPLE_DISCARD_bw 8 +#define MSK_TOP_REGS__RX_SAMPLE_DISCARD__RX_SAMPLE_DISCARD_reset 0x0 +#define MSK_TOP_REGS__RX_SAMPLE_DISCARD__RX_NCO_DISCARD_bm 0xff00 +#define MSK_TOP_REGS__RX_SAMPLE_DISCARD__RX_NCO_DISCARD_bp 8 +#define MSK_TOP_REGS__RX_SAMPLE_DISCARD__RX_NCO_DISCARD_bw 8 +#define MSK_TOP_REGS__RX_SAMPLE_DISCARD__RX_NCO_DISCARD_reset 0x0 + +// Reg - msk_top_regs::lpf_config_2 +#define MSK_TOP_REGS__LPF_CONFIG_2__P_GAIN_bm 0xffffff +#define MSK_TOP_REGS__LPF_CONFIG_2__P_GAIN_bp 0 +#define MSK_TOP_REGS__LPF_CONFIG_2__P_GAIN_bw 24 +#define MSK_TOP_REGS__LPF_CONFIG_2__P_GAIN_reset 0x0 +#define MSK_TOP_REGS__LPF_CONFIG_2__P_SHIFT_bm 0xff000000 +#define MSK_TOP_REGS__LPF_CONFIG_2__P_SHIFT_bp 24 +#define MSK_TOP_REGS__LPF_CONFIG_2__P_SHIFT_bw 8 +#define MSK_TOP_REGS__LPF_CONFIG_2__P_SHIFT_reset 0x0 + +// Reg - msk_top_regs::status_reg_data_f53978c8_name_d8ad3b25 +#define MSK_TOP_REGS__STATUS_REG_DATA_F53978C8_NAME_D8AD3B25__DATA_bm 0xffffffff +#define MSK_TOP_REGS__STATUS_REG_DATA_F53978C8_NAME_D8AD3B25__DATA_bp 0 +#define MSK_TOP_REGS__STATUS_REG_DATA_F53978C8_NAME_D8AD3B25__DATA_bw 32 +#define MSK_TOP_REGS__STATUS_REG_DATA_F53978C8_NAME_D8AD3B25__DATA_reset 0x0 + +// Reg - msk_top_regs::status_reg_data_05243a4e_name_2c154788 +#define MSK_TOP_REGS__STATUS_REG_DATA_05243A4E_NAME_2C154788__DATA_bm 0xffffffff +#define MSK_TOP_REGS__STATUS_REG_DATA_05243A4E_NAME_2C154788__DATA_bp 0 +#define MSK_TOP_REGS__STATUS_REG_DATA_05243A4E_NAME_2C154788__DATA_bw 32 +#define MSK_TOP_REGS__STATUS_REG_DATA_05243A4E_NAME_2C154788__DATA_reset 0x0 + +// Reg - msk_top_regs::status_reg_data_10a2e5b5_name_3b640507 +#define MSK_TOP_REGS__STATUS_REG_DATA_10A2E5B5_NAME_3B640507__DATA_bm 0xffffffff +#define MSK_TOP_REGS__STATUS_REG_DATA_10A2E5B5_NAME_3B640507__DATA_bp 0 +#define MSK_TOP_REGS__STATUS_REG_DATA_10A2E5B5_NAME_3B640507__DATA_bw 32 +#define MSK_TOP_REGS__STATUS_REG_DATA_10A2E5B5_NAME_3B640507__DATA_reset 0x0 + +// Reg - msk_top_regs::status_reg_data_642692cf_name_3de9a0d3 +#define MSK_TOP_REGS__STATUS_REG_DATA_642692CF_NAME_3DE9A0D3__DATA_bm 0xffffffff +#define MSK_TOP_REGS__STATUS_REG_DATA_642692CF_NAME_3DE9A0D3__DATA_bp 0 +#define MSK_TOP_REGS__STATUS_REG_DATA_642692CF_NAME_3DE9A0D3__DATA_bw 32 +#define MSK_TOP_REGS__STATUS_REG_DATA_642692CF_NAME_3DE9A0D3__DATA_reset 0x0 + +// Reg - msk_top_regs::tx_sync_ctrl +#define MSK_TOP_REGS__TX_SYNC_CTRL__TX_SYNC_ENA_bm 0x1 +#define MSK_TOP_REGS__TX_SYNC_CTRL__TX_SYNC_ENA_bp 0 +#define MSK_TOP_REGS__TX_SYNC_CTRL__TX_SYNC_ENA_bw 1 +#define MSK_TOP_REGS__TX_SYNC_CTRL__TX_SYNC_ENA_reset 0x0 +#define MSK_TOP_REGS__TX_SYNC_CTRL__TX_SYNC_FORCE_bm 0x2 +#define MSK_TOP_REGS__TX_SYNC_CTRL__TX_SYNC_FORCE_bp 1 +#define MSK_TOP_REGS__TX_SYNC_CTRL__TX_SYNC_FORCE_bw 1 +#define MSK_TOP_REGS__TX_SYNC_CTRL__TX_SYNC_FORCE_reset 0x0 + +// Reg - msk_top_regs::tx_sync_cnt +#define MSK_TOP_REGS__TX_SYNC_CNT__TX_SYNC_CNT_bm 0xffffff +#define MSK_TOP_REGS__TX_SYNC_CNT__TX_SYNC_CNT_bp 0 +#define MSK_TOP_REGS__TX_SYNC_CNT__TX_SYNC_CNT_bw 24 +#define MSK_TOP_REGS__TX_SYNC_CNT__TX_SYNC_CNT_reset 0x0 + +// Reg - msk_top_regs::lowpass_ema_alpha +#define MSK_TOP_REGS__LOWPASS_EMA_ALPHA__ALPHA_bm 0x3ffff +#define MSK_TOP_REGS__LOWPASS_EMA_ALPHA__ALPHA_bp 0 +#define MSK_TOP_REGS__LOWPASS_EMA_ALPHA__ALPHA_bw 18 +#define MSK_TOP_REGS__LOWPASS_EMA_ALPHA__ALPHA_reset 0x0 + +// Reg - msk_top_regs::rx_power +#define MSK_TOP_REGS__RX_POWER__DATA_bm 0x7fffff +#define MSK_TOP_REGS__RX_POWER__DATA_bp 0 +#define MSK_TOP_REGS__RX_POWER__DATA_bw 23 +#define MSK_TOP_REGS__RX_POWER__DATA_reset 0x0 + +// Reg - msk_top_regs::status_reg_data_8a67e1fe_desc_aa4ec676_name_aa4ec676 +#define MSK_TOP_REGS__STATUS_REG_DATA_8A67E1FE_DESC_AA4EC676_NAME_AA4EC676__DATA_bm 0xffffffff +#define MSK_TOP_REGS__STATUS_REG_DATA_8A67E1FE_DESC_AA4EC676_NAME_AA4EC676__DATA_bp 0 +#define MSK_TOP_REGS__STATUS_REG_DATA_8A67E1FE_DESC_AA4EC676_NAME_AA4EC676__DATA_bw 32 +#define MSK_TOP_REGS__STATUS_REG_DATA_8A67E1FE_DESC_AA4EC676_NAME_AA4EC676__DATA_reset 0x0 + +// Reg - msk_top_regs::status_reg_data_8a67e1fe_desc_8a90eed1_name_8a90eed1 +#define MSK_TOP_REGS__STATUS_REG_DATA_8A67E1FE_DESC_8A90EED1_NAME_8A90EED1__DATA_bm 0xffffffff +#define MSK_TOP_REGS__STATUS_REG_DATA_8A67E1FE_DESC_8A90EED1_NAME_8A90EED1__DATA_bp 0 +#define MSK_TOP_REGS__STATUS_REG_DATA_8A67E1FE_DESC_8A90EED1_NAME_8A90EED1__DATA_bw 32 +#define MSK_TOP_REGS__STATUS_REG_DATA_8A67E1FE_DESC_8A90EED1_NAME_8A90EED1__DATA_reset 0x0 + +// Reg - msk_top_regs::frame_sync_status +#define MSK_TOP_REGS__FRAME_SYNC_STATUS__FRAME_SYNC_LOCKED_bm 0x1 +#define MSK_TOP_REGS__FRAME_SYNC_STATUS__FRAME_SYNC_LOCKED_bp 0 +#define MSK_TOP_REGS__FRAME_SYNC_STATUS__FRAME_SYNC_LOCKED_bw 1 +#define MSK_TOP_REGS__FRAME_SYNC_STATUS__FRAME_SYNC_LOCKED_reset 0x0 +#define MSK_TOP_REGS__FRAME_SYNC_STATUS__FRAME_BUFFER_OVERFLOW_bm 0x2 +#define MSK_TOP_REGS__FRAME_SYNC_STATUS__FRAME_BUFFER_OVERFLOW_bp 1 +#define MSK_TOP_REGS__FRAME_SYNC_STATUS__FRAME_BUFFER_OVERFLOW_bw 1 +#define MSK_TOP_REGS__FRAME_SYNC_STATUS__FRAME_BUFFER_OVERFLOW_reset 0x0 +#define MSK_TOP_REGS__FRAME_SYNC_STATUS__FRAMES_RECEIVED_bm 0x3fffffc +#define MSK_TOP_REGS__FRAME_SYNC_STATUS__FRAMES_RECEIVED_bp 2 +#define MSK_TOP_REGS__FRAME_SYNC_STATUS__FRAMES_RECEIVED_bw 24 +#define MSK_TOP_REGS__FRAME_SYNC_STATUS__FRAMES_RECEIVED_reset 0x0 +#define MSK_TOP_REGS__FRAME_SYNC_STATUS__FRAME_SYNC_ERRORS_bm 0xfc000000 +#define MSK_TOP_REGS__FRAME_SYNC_STATUS__FRAME_SYNC_ERRORS_bp 26 +#define MSK_TOP_REGS__FRAME_SYNC_STATUS__FRAME_SYNC_ERRORS_bw 6 +#define MSK_TOP_REGS__FRAME_SYNC_STATUS__FRAME_SYNC_ERRORS_reset 0x0 + +// Addrmap - msk_top_regs +typedef struct __attribute__ ((__packed__)) { + uint32_t Hash_ID_Low; + uint32_t Hash_ID_High; + uint32_t MSK_Init; + uint32_t MSK_Control; + uint32_t MSK_Status; + uint32_t Tx_Bit_Count; + uint32_t Tx_Enable_Count; + uint32_t Fb_FreqWord; + uint32_t TX_F1_FreqWord; + uint32_t TX_F2_FreqWord; + uint32_t RX_F1_FreqWord; + uint32_t RX_F2_FreqWord; + uint32_t LPF_Config_0; + uint32_t LPF_Config_1; + uint32_t Tx_Data_Width; + uint32_t Rx_Data_Width; + uint32_t PRBS_Control; + uint32_t PRBS_Initial_State; + uint32_t PRBS_Polynomial; + uint32_t PRBS_Error_Mask; + uint32_t PRBS_Bit_Count; + uint32_t PRBS_Error_Count; + uint32_t LPF_Accum_F1; + uint32_t LPF_Accum_F2; + uint32_t axis_xfer_count; + uint32_t Rx_Sample_Discard; + uint32_t LPF_Config_2; + uint32_t f1_nco_adjust; + uint32_t f2_nco_adjust; + uint32_t f1_error; + uint32_t f2_error; + uint32_t Tx_Sync_Ctrl; + uint32_t Tx_Sync_Cnt; + uint32_t lowpass_ema_alpha1; + uint32_t lowpass_ema_alpha2; + uint32_t rx_power; + uint32_t tx_async_fifo_rd_wr_ptr; + uint32_t rx_async_fifo_rd_wr_ptr; + uint32_t rx_frame_sync_status; +} msk_top_regs_t; + + +static_assert(sizeof(msk_top_regs_t) == 0x9c, "Packing error"); + +#ifdef __cplusplus +} +#endif + +#endif /* MSK_TOP_REGS_H */ diff --git a/rdl/outputs/docs/html/.launcher_data/firefox/user.js b/rdl/outputs/docs/html/.launcher_data/firefox/user.js new file mode 100644 index 0000000..34b966f --- /dev/null +++ b/rdl/outputs/docs/html/.launcher_data/firefox/user.js @@ -0,0 +1,4 @@ +user_pref("app.normandy.first_run", false); +user_pref("toolkit.telemetry.reportingpolicy.firstRun", false); + +user_pref("security.fileuri.strict_origin_policy", false); \ No newline at end of file diff --git a/rdl/outputs/docs/html/content/1211d8a8c3c9175e1c33719680affb67165e68d7.html b/rdl/outputs/docs/html/content/1211d8a8c3c9175e1c33719680affb67165e68d7.html new file mode 100644 index 0000000..0428d5d --- /dev/null +++ b/rdl/outputs/docs/html/content/1211d8a8c3c9175e1c33719680affb67165e68d7.html @@ -0,0 +1,76 @@ + + +
+

Tx async FIFO read and write pointers

+ + +
+
Absolute Address:
+
+
Base Offset:
0x90
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+

Description

+
+

Tx async FIFO read and write pointers

+
+ +

Contents

+ + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:0]data + rw0x0 + + + - + + +
+

+ +

+

Field Descriptions

+ +

data + +

+
+

Read and Write Pointers

+

+Bits 31:16 - write pointer (12-bits) +Bits 15:00 - read pointer (12-bits)

+

This register is write-to-capture. To read data the following steps are required:

+
    +
  1. Write any value to this register to capture read data +
  2. Read the register +
+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/1254c2cce678b196818b4f08e31bc15b1b3e6e8e.html b/rdl/outputs/docs/html/content/1254c2cce678b196818b4f08e31bc15b1b3e6e8e.html new file mode 100644 index 0000000..25659e1 --- /dev/null +++ b/rdl/outputs/docs/html/content/1254c2cce678b196818b4f08e31bc15b1b3e6e8e.html @@ -0,0 +1,95 @@ + + +
+

PI Controller Configuration Configuration Register 1

+ + +
+
Absolute Address:
+
+
Base Offset:
0x34
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+

Description

+
+

Configures PI Controller I-gain and divisor

+
+ +

Contents

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:24]i_shift + rw0x0 + + + Integral Gain Bit Shift + + +
[23:0]i_gain + rw0x0 + + + Integral Gain Value + + +
+

+ +

+

Field Descriptions

+ +

i_shift - Integral Gain Bit Shift + +

+
+

Value n of 0-32 sets the integral divisor as 2^-n

+
+ +

i_gain - Integral Gain Value + +

+
+

Value m of 0-16,777,215 sets the integral multiplier

+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/14648ccc7797ab5a2e0a9ce250fc373fb5d1b044.html b/rdl/outputs/docs/html/content/14648ccc7797ab5a2e0a9ce250fc373fb5d1b044.html new file mode 100644 index 0000000..77b6e21 --- /dev/null +++ b/rdl/outputs/docs/html/content/14648ccc7797ab5a2e0a9ce250fc373fb5d1b044.html @@ -0,0 +1,72 @@ + + +
+

F2 PI Controller Accumulator

+ + +
+
Absolute Address:
+
+
Base Offset:
0x5c
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+

Description

+
+

Value of the F2 PI Controller Accumulator

+
+ +

Contents

+ + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:0]data + rw0x0 + + + PI Controller Accumulator Value + + +
+

+ +

+

Field Descriptions

+ +

data - PI Controller Accumulator Value + +

+
+

PI Controller Accumulator Value

+

This register is write-to-capture.

+

To read data the following steps are required:

+

1 - Write any value to this register to capture read data

+

2 - Read the register

+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/181914803428de754127f501a151f8d9f2f6346f.html b/rdl/outputs/docs/html/content/181914803428de754127f501a151f8d9f2f6346f.html new file mode 100644 index 0000000..f88fad0 --- /dev/null +++ b/rdl/outputs/docs/html/content/181914803428de754127f501a151f8d9f2f6346f.html @@ -0,0 +1,77 @@ + + +
+

Modem Tx Input Data Width

+ + +
+
Absolute Address:
+
+
Base Offset:
0x38
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+

Description

+
+

Set the parallel data width of the parallel-to-serial converter

+
+ +

Contents

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:8]----
[7:0]data_width + rw0x8 + + + Modem input/output data width + + +
+

+ +

+

Field Descriptions

+ +

data_width - Modem input/output data width + +

+
+

Set the data width of the modem input/output

+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/1e2385a5df67ff7f5d1fbfe621945563573fbb22.html b/rdl/outputs/docs/html/content/1e2385a5df67ff7f5d1fbfe621945563573fbb22.html new file mode 100644 index 0000000..1d7492d --- /dev/null +++ b/rdl/outputs/docs/html/content/1e2385a5df67ff7f5d1fbfe621945563573fbb22.html @@ -0,0 +1,69 @@ + + +
+

Bitrate NCO Frequency Control Word

+ + +
+
Absolute Address:
+
+
Base Offset:
0x1c
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+

Description

+
+

Set Modem Data Rate

+
+ +

Contents

+ + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:0]config_data + rw0x0 + + + Frequency Control Word + + +
+

+ +

+

Field Descriptions

+ +

config_data - Frequency Control Word + +

+
+

Sets the center frequency of the NCO as FW = Fn * 2^32/Fs, +where Fn is the desired NCO frequency, and Fs is the NCO sample rate

+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/1e5eb9d33100e7486423224eec5450a659e2203c.html b/rdl/outputs/docs/html/content/1e5eb9d33100e7486423224eec5450a659e2203c.html new file mode 100644 index 0000000..dd353c9 --- /dev/null +++ b/rdl/outputs/docs/html/content/1e5eb9d33100e7486423224eec5450a659e2203c.html @@ -0,0 +1,72 @@ + + +
+

F1 Error Value

+ + +
+
Absolute Address:
+
+
Base Offset:
0x74
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+

Description

+
+

Status Register

+
+ +

Contents

+ + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:0]data + rw0x0 + + + - + + +
+

+ +

+

Field Descriptions

+ +

data + +

+
+

Error value of the F1 Costas loop after each active bit period

+

This register is write-to-capture.

+

To read data the following steps are required:

+

1 - Write any value to this register to capture read data

+

2 - Read the register

+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/1fc360864d8b656cfa1ebcc20f12a51ba4f4f9cc.html b/rdl/outputs/docs/html/content/1fc360864d8b656cfa1ebcc20f12a51ba4f4f9cc.html new file mode 100644 index 0000000..6167fcd --- /dev/null +++ b/rdl/outputs/docs/html/content/1fc360864d8b656cfa1ebcc20f12a51ba4f4f9cc.html @@ -0,0 +1,201 @@ + + +
+

PRBS Control 0

+ + +
+
Absolute Address:
+
+
Base Offset:
0x40
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+

Description

+
+

Configures operation of the PRBS Generator and Monitor

+
+ +

Contents

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:16]prbs_sync_threshold + rw0x0 + + + PRBS Auto Sync Threshold + + +
[15:4]prbs_reserved + rw0x0 + + + Reserved + + +
[3]prbs_manual_sync + w0x0 + + + PRBS Manual Sync + + +
[2]prbs_clear + w0x0 + + + PRBS Clear Counters + + +
[1]prbs_error_insert + w0x0 + + + PRBS Error Insert + + +
[0]prbs_sel + rw0x0 + + + PRBS Data Select + + +
+

+ +

+

Field Descriptions

+ +

prbs_sync_threshold - PRBS Auto Sync Threshold + +

+
+

0 : Auto Sync Disabled

+

N > 0 : Auto sync after N errors

+
+ +

prbs_manual_sync - PRBS Manual Sync + +

+
+

0 -> 1 : Synchronize PRBS monitor

+

1 -> 0 : Synchronize PRBS monitor

+
+ +

prbs_clear - PRBS Clear Counters + +

+
+

0 -> 1 : Clear PRBS Counters

+

1 -> 0 : Clear PRBS Counters

+
+ +

prbs_error_insert - PRBS Error Insert + +

+
+

0 -> 1 : Insert bit error in Tx data (both Normal and PRBS)

+

1 -> 0 : Insert bit error in Tx data (both Normal and PRBS)

+
+ +

prbs_sel - PRBS Data Select + +

+
+

0 -> Select Normal Tx Data +1 -> Select PRBS Tx Data

+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/263d902a6f30dcb8d14e261e3eb867f29ae8aa29.html b/rdl/outputs/docs/html/content/263d902a6f30dcb8d14e261e3eb867f29ae8aa29.html new file mode 100644 index 0000000..ac7d09d --- /dev/null +++ b/rdl/outputs/docs/html/content/263d902a6f30dcb8d14e261e3eb867f29ae8aa29.html @@ -0,0 +1,95 @@ + + +
+

PI Controller Configuration Configuration Register 2

+ + +
+
Absolute Address:
+
+
Base Offset:
0x68
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+

Description

+
+

Configures PI Controller I-gain and divisor

+
+ +

Contents

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:24]p_shift + rw0x0 + + + Proportional Gain Bit Shift + + +
[23:0]p_gain + rw0x0 + + + Proportional Gain Value + + +
+

+ +

+

Field Descriptions

+ +

p_shift - Proportional Gain Bit Shift + +

+
+

Value n of 0-32 sets the proportional divisor as 2^-n

+
+ +

p_gain - Proportional Gain Value + +

+
+

Value m of 0-16,777,215 sets the proportional multiplier

+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/26afac861ad2452f8ace4d5f4459d66b2ead24dc.html b/rdl/outputs/docs/html/content/26afac861ad2452f8ace4d5f4459d66b2ead24dc.html new file mode 100644 index 0000000..9680292 --- /dev/null +++ b/rdl/outputs/docs/html/content/26afac861ad2452f8ace4d5f4459d66b2ead24dc.html @@ -0,0 +1,72 @@ + + +
+

F1 NCO Frequency Adjust

+ + +
+
Absolute Address:
+
+
Base Offset:
0x6c
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+

Description

+
+

Status Register

+
+ +

Contents

+ + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:0]data + rw0x0 + + + - + + +
+

+ +

+

Field Descriptions

+ +

data + +

+
+

Frequency offet applied to the F1 NCO

+

This register is write-to-capture.

+

To read data the following steps are required:

+

1 - Write any value to this register to capture read data

+

2 - Read the register

+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/2b5b7862ddb3fa504d82685711c9a66bce7f577d.html b/rdl/outputs/docs/html/content/2b5b7862ddb3fa504d82685711c9a66bce7f577d.html new file mode 100644 index 0000000..85a5bfe --- /dev/null +++ b/rdl/outputs/docs/html/content/2b5b7862ddb3fa504d82685711c9a66bce7f577d.html @@ -0,0 +1,72 @@ + + +
+

MSK Modem Status 1

+ + +
+
Absolute Address:
+
+
Base Offset:
0x14
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+

Description

+
+

Modem status data

+
+ +

Contents

+ + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:0]data + rw0x0 + + + Tx Bit Count + + +
+

+ +

+

Field Descriptions

+ +

data - Tx Bit Count + +

+
+

Count of data requests made by modem

+

This register is write-to-capture.

+

To read data the following steps are required:

+

1 - Write any value to this register to capture read data

+

2 - Read the register

+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/373508e257881c5e4a5502062b7c9aa9a792dc12.html b/rdl/outputs/docs/html/content/373508e257881c5e4a5502062b7c9aa9a792dc12.html new file mode 100644 index 0000000..872c0ab --- /dev/null +++ b/rdl/outputs/docs/html/content/373508e257881c5e4a5502062b7c9aa9a792dc12.html @@ -0,0 +1,68 @@ + + +
+

PRBS Control 3

+ + +
+
Absolute Address:
+
+
Base Offset:
0x4c
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+

Description

+
+

PRBS Error Mask

+
+ +

Contents

+ + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:0]config_data + rw0x0 + + + PRBS Error Mask + + +
+

+ +

+

Field Descriptions

+ +

config_data - PRBS Error Mask + +

+
+

Bit positions set to '1' indicate bits that are inverted when a bit error is inserted

+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/38738d6efca727bb9bf39e13e872f922349ff15e.html b/rdl/outputs/docs/html/content/38738d6efca727bb9bf39e13e872f922349ff15e.html new file mode 100644 index 0000000..8813da8 --- /dev/null +++ b/rdl/outputs/docs/html/content/38738d6efca727bb9bf39e13e872f922349ff15e.html @@ -0,0 +1,68 @@ + + +
+

PRBS Control 1

+ + +
+
Absolute Address:
+
+
Base Offset:
0x44
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+

Description

+
+

PRBS Initial State

+
+ +

Contents

+ + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:0]config_data + rw0x0 + + + PRBS Seed + + +
+

+ +

+

Field Descriptions

+ +

config_data - PRBS Seed + +

+
+

Sets the starting value of the PRBS generator

+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/4092c31237c70d2c50e8a1e8a25d3a13f9cec6a2.html b/rdl/outputs/docs/html/content/4092c31237c70d2c50e8a1e8a25d3a13f9cec6a2.html new file mode 100644 index 0000000..96a4a32 --- /dev/null +++ b/rdl/outputs/docs/html/content/4092c31237c70d2c50e8a1e8a25d3a13f9cec6a2.html @@ -0,0 +1,77 @@ + + +
+

Modem Rx Output Data Width

+ + +
+
Absolute Address:
+
+
Base Offset:
0x3c
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+

Description

+
+

Set the parallel data width of the serial-to-parallel converter

+
+ +

Contents

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:8]----
[7:0]data_width + rw0x8 + + + Modem input/output data width + + +
+

+ +

+

Field Descriptions

+ +

data_width - Modem input/output data width + +

+
+

Set the data width of the modem input/output

+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/4f916507967fd003316096871c9cb43cb2983373.html b/rdl/outputs/docs/html/content/4f916507967fd003316096871c9cb43cb2983373.html new file mode 100644 index 0000000..6b97b33 --- /dev/null +++ b/rdl/outputs/docs/html/content/4f916507967fd003316096871c9cb43cb2983373.html @@ -0,0 +1,161 @@ + + +
+

MSK Modem Status 0

+ + +
+
Absolute Address:
+
+
Base Offset:
0x10
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+

Description

+
+

Modem status bits

+
+ +

Contents

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:4]----
[3]tx_axis_valid + r0x0 + + + Tx S_AXIS_VALID + + +
[2]rx_enable + r0x0 + + + AD9363 ADC Interface Rx Enable Input Active + + +
[1]tx_enable + r0x0 + + + AD9363 DAC Interface Tx Enable Input Active + + +
[0]demod_sync_lock + r0x0 + + + Demodulator Sync Status + + +
+

+ +

+

Field Descriptions

+ +

tx_axis_valid - Tx S_AXIS_VALID + +

+
+

1 -> S_AXIS_VALID Enabled

+

0 -> S_AXIS_VALID Disabled

+
+ +

rx_enable - AD9363 ADC Interface Rx Enable Input Active + +

+
+

1 -> Data from ADC Enabled

+

0 -> Data from ADC Disabled

+
+ +

tx_enable - AD9363 DAC Interface Tx Enable Input Active + +

+
+

1 -> Data to DAC Enabled

+

0 -> Data to DAC Disabled

+
+ +

demod_sync_lock - Demodulator Sync Status + +

+
+

Demodulator Sync Status - not currently implemented

+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/54cea48e8d9edee01f284df7c443e2add40252d9.html b/rdl/outputs/docs/html/content/54cea48e8d9edee01f284df7c443e2add40252d9.html new file mode 100644 index 0000000..7120ffb --- /dev/null +++ b/rdl/outputs/docs/html/content/54cea48e8d9edee01f284df7c443e2add40252d9.html @@ -0,0 +1,189 @@ + + +
+

MSK Modem Control

+ + +
+
Absolute Address:
+
+
Base Offset:
0xc
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+

Description

+
+

MSK Modem Configuration and Control

+
+ +

Contents

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:5]----
[4]diff_encoder_loopback + rw0x0 + + + Differential Encoder -> Decoder Loopback Enable + + +
[3]clear_counts + rw0x0 + + + Clear Status Counters + + +
[2]rx_invert + rw0x0 + + + Rx Data Invert Enable + + +
[1]loopback_ena + rw0x0 + + + Modem Digital Tx -> Rx Loopback Enable + + +
[0]ptt + rw0x0 + + + Push-to-Talk Enable + + +
+

+ +

+

Field Descriptions

+ +

diff_encoder_loopback - Differential Encoder -> Decoder Loopback Enable + +

+
+

0 -> Differential Encoder -> Decoder loopback disabled

+

1 -> Differential Encoder -> Decoder loopback enabled

+
+ +

clear_counts - Clear Status Counters + +

+
+

Clear Tx Bit Counter and Tx Enable Counter

+
+ +

rx_invert - Rx Data Invert Enable + +

+
+

0 -> Rx data normal +1 -> Rx data inverted

+
+ +

loopback_ena - Modem Digital Tx -> Rx Loopback Enable + +

+
+

0 -> Modem loopback disabled

+

1 -> Modem loopback enabled

+
+ +

ptt - Push-to-Talk Enable + +

+
+

0 -> PTT Disabled +1 -> PTT Enabled

+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/611b0a3a62ae385442fa3b250263026f7cfdd441.html b/rdl/outputs/docs/html/content/611b0a3a62ae385442fa3b250263026f7cfdd441.html new file mode 100644 index 0000000..019e6eb --- /dev/null +++ b/rdl/outputs/docs/html/content/611b0a3a62ae385442fa3b250263026f7cfdd441.html @@ -0,0 +1,72 @@ + + +
+

MSK Modem Status 2

+ + +
+
Absolute Address:
+
+
Base Offset:
0x18
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+

Description

+
+

Modem status data

+
+ +

Contents

+ + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:0]data + rw0x0 + + + Tx Enable Count + + +
+

+ +

+

Field Descriptions

+ +

data - Tx Enable Count + +

+
+

Number of clocks on which Tx Enable is active

+

This register is write-to-capture.

+

To read data the following steps are required:

+

1 - Write any value to this register to capture read data

+

2 - Read the register

+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/611d75d5fc9168e025083358f26a5e06ca7b3007.html b/rdl/outputs/docs/html/content/611d75d5fc9168e025083358f26a5e06ca7b3007.html new file mode 100644 index 0000000..7fc73be --- /dev/null +++ b/rdl/outputs/docs/html/content/611d75d5fc9168e025083358f26a5e06ca7b3007.html @@ -0,0 +1,144 @@ + + +
+

PI Controller Configuration and Low-pass Filter Configuration

+ + +
+
Absolute Address:
+
+
Base Offset:
0x30
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+

Description

+
+

Configure PI controller and low-pass filter

+
+ +

Contents

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:8]lpf_alpha + rw0x0 + + + Lowpass IIR filter alpha + + +
[7:2]prbs_reserved + rw0x0 + + + Reserved + + +
[1]lpf_zero + rw0x0 + + + Hold the PI Accumulator at zero + + +
[0]lpf_freeze + rw0x0 + + + Freeze the accumulator's current value + + +
+

+ +

+

Field Descriptions

+ +

lpf_alpha - Lowpass IIR filter alpha + +

+
+

Value controls the filter rolloff

+
+ +

lpf_zero - Hold the PI Accumulator at zero + +

+
+

0 -> Normal operation

+

1 -> Zero and hold accumulator

+
+ +

lpf_freeze - Freeze the accumulator's current value + +

+
+

0 -> Normal operation

+

1 -> Freeze current value

+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/6a1cea7d8db3cfd91d0b598d43abc73b85b237e5.html b/rdl/outputs/docs/html/content/6a1cea7d8db3cfd91d0b598d43abc73b85b237e5.html new file mode 100644 index 0000000..c45c2e1 --- /dev/null +++ b/rdl/outputs/docs/html/content/6a1cea7d8db3cfd91d0b598d43abc73b85b237e5.html @@ -0,0 +1,64 @@ + + +
+

Pluto MSK FPGA Hash ID - Lower 32-bits

+ + +
+
Absolute Address:
+
+
Base Offset:
0x0
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+ +

Contents

+ + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:0]hash_id_lo + r0xaaaa5555 + + + Hash ID Lower 32-bits + + +
+

+ +

+

Field Descriptions

+ +

hash_id_lo - Hash ID Lower 32-bits + +

+
+

Lower 32-bits of Pluto MSK FPGA Hash ID

+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/766520c9b6891107c7d1b147a3b1bed28bebe71c.html b/rdl/outputs/docs/html/content/766520c9b6891107c7d1b147a3b1bed28bebe71c.html new file mode 100644 index 0000000..fb34eaf --- /dev/null +++ b/rdl/outputs/docs/html/content/766520c9b6891107c7d1b147a3b1bed28bebe71c.html @@ -0,0 +1,73 @@ + + +
+

PRBS Status 0

+ + +
+
Absolute Address:
+
+
Base Offset:
0x50
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+

Description

+
+

PRBS Bits Received

+
+ +

Contents

+ + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:0]data + rw0x0 + + + PRBS Bits Received + + +
+

+ +

+

Field Descriptions

+ +

data - PRBS Bits Received + +

+
+

Number of bits received by the PRBS monitor since last +BER can be calculated as the ratio of received bits to errored-bits

+

This register is write-to-capture.

+

To read data the following steps are required:

+

1 - Write any value to this register to capture read data

+

2 - Read the register

+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/8341423b7e011932aacabd59a183a4c2d7c81b46.html b/rdl/outputs/docs/html/content/8341423b7e011932aacabd59a183a4c2d7c81b46.html new file mode 100644 index 0000000..87df749 --- /dev/null +++ b/rdl/outputs/docs/html/content/8341423b7e011932aacabd59a183a4c2d7c81b46.html @@ -0,0 +1,69 @@ + + +
+

Rx F1 NCO Frequency Control Word

+ + +
+
Absolute Address:
+
+
Base Offset:
0x28
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+

Description

+
+

Set Demodulator F1 Frequency

+
+ +

Contents

+ + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:0]config_data + rw0x0 + + + Frequency Control Word + + +
+

+ +

+

Field Descriptions

+ +

config_data - Frequency Control Word + +

+
+

Sets the center frequency of the NCO as FW = Fn * 2^32/Fs, +where Fn is the desired NCO frequency, and Fs is the NCO sample rate

+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/9d2d5d50d18610dbbfe8e1803c2e8d1c73b5a100.html b/rdl/outputs/docs/html/content/9d2d5d50d18610dbbfe8e1803c2e8d1c73b5a100.html new file mode 100644 index 0000000..e1c4393 --- /dev/null +++ b/rdl/outputs/docs/html/content/9d2d5d50d18610dbbfe8e1803c2e8d1c73b5a100.html @@ -0,0 +1,147 @@ + + +
+

Frame Sync Status

+ + +
+
Absolute Address:
+
+
Base Offset:
0x98
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+ +

Contents

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:26]frame_sync_errors + rw0x0 + + + Frames Sync Errors + + +
[25:2]frames_received + rw0x0 + + + Frames Received + + +
[1]frame_buffer_overflow + r, rclr0x0 + + + Frame Buffer Overflow + + +
[0]frame_sync_locked + r0x0 + + + Frame Sync Lock + + +
+

+ +

+

Field Descriptions

+ +

frame_sync_errors - Frames Sync Errors + +

+
+

Count of frame sync errors since last read. Value is 0 to 63. This field will saturate at 63 if more than 63 occur.

+
+ +

frames_received - Frames Received + +

+
+

Count of frames received since last read. Value is 0x00_0000 to 0xFF_FFFF

+
+ +

frame_buffer_overflow - Frame Buffer Overflow + +

+
+

0 - Normal operation +1 - Buffer overflow

+
+ +

frame_sync_locked - Frame Sync Lock + +

+
+

0 - Frame sync not locked +1 - Frame sync locked

+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/aaa99b88ab61eb3569764525c3aef19596c2a4e8.html b/rdl/outputs/docs/html/content/aaa99b88ab61eb3569764525c3aef19596c2a4e8.html new file mode 100644 index 0000000..fbe5ace --- /dev/null +++ b/rdl/outputs/docs/html/content/aaa99b88ab61eb3569764525c3aef19596c2a4e8.html @@ -0,0 +1,72 @@ + + +
+

MSK Modem Status 3

+ + +
+
Absolute Address:
+
+
Base Offset:
0x60
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+

Description

+
+

Modem status data

+
+ +

Contents

+ + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:0]data + rw0x0 + + + S_AXIS Transfers + + +
+

+ +

+

Field Descriptions

+ +

data - S_AXIS Transfers + +

+
+

Number completed S_AXIS transfers

+

This register is write-to-capture.

+

To read data the following steps are required:

+

1 - Write any value to this register to capture read data

+

2 - Read the register

+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/aab8d61e4e2c8cc1adaabca728671903515e6053.html b/rdl/outputs/docs/html/content/aab8d61e4e2c8cc1adaabca728671903515e6053.html new file mode 100644 index 0000000..77463d4 --- /dev/null +++ b/rdl/outputs/docs/html/content/aab8d61e4e2c8cc1adaabca728671903515e6053.html @@ -0,0 +1,69 @@ + + +
+

Tx F1 NCO Frequency Control Word

+ + +
+
Absolute Address:
+
+
Base Offset:
0x20
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+

Description

+
+

Set Modulator F1 Frequency

+
+ +

Contents

+ + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:0]config_data + rw0x0 + + + Frequency Control Word + + +
+

+ +

+

Field Descriptions

+ +

config_data - Frequency Control Word + +

+
+

Sets the center frequency of the NCO as FW = Fn * 2^32/Fs, +where Fn is the desired NCO frequency, and Fs is the NCO sample rate

+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/b4c18df4e6a7993047f37ec6f74d05dae744e911.html b/rdl/outputs/docs/html/content/b4c18df4e6a7993047f37ec6f74d05dae744e911.html new file mode 100644 index 0000000..bb889e5 --- /dev/null +++ b/rdl/outputs/docs/html/content/b4c18df4e6a7993047f37ec6f74d05dae744e911.html @@ -0,0 +1,343 @@ + + +
+

Pluto MSK Registers

+ + +
+
Absolute Address:
+
+
Base Offset:
0x0
+
Size:
0x9c
+ +
Source:
msk_top_regs.rdl
+ +
+

Description

+
+

MSK Modem Configuration and Status Registers

+
+ +

Contents

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OffsetIdentifierName
0x00Hash_ID_LowPluto MSK FPGA Hash ID - Lower 32-bits + +
0x04Hash_ID_HighPluto MSK FPGA Hash ID - Upper 32-bits + +
0x08MSK_InitMSK Modem Initialization Control + +
0x0CMSK_ControlMSK Modem Control + +
0x10MSK_StatusMSK Modem Status 0 + +
0x14Tx_Bit_CountMSK Modem Status 1 + +
0x18Tx_Enable_CountMSK Modem Status 2 + +
0x1CFb_FreqWordBitrate NCO Frequency Control Word + +
0x20TX_F1_FreqWordTx F1 NCO Frequency Control Word + +
0x24TX_F2_FreqWordTx F2 NCO Frequency Control Word + +
0x28RX_F1_FreqWordRx F1 NCO Frequency Control Word + +
0x2CRX_F2_FreqWordRx F2 NCO Frequency Control Word + +
0x30LPF_Config_0PI Controller Configuration and Low-pass Filter Configuration + +
0x34LPF_Config_1PI Controller Configuration Configuration Register 1 + +
0x38Tx_Data_WidthModem Tx Input Data Width + +
0x3CRx_Data_WidthModem Rx Output Data Width + +
0x40PRBS_ControlPRBS Control 0 + +
0x44PRBS_Initial_StatePRBS Control 1 + +
0x48PRBS_PolynomialPRBS Control 2 + +
0x4CPRBS_Error_MaskPRBS Control 3 + +
0x50PRBS_Bit_CountPRBS Status 0 + +
0x54PRBS_Error_CountPRBS Status 1 + +
0x58LPF_Accum_F1F1 PI Controller Accumulator + +
0x5CLPF_Accum_F2F2 PI Controller Accumulator + +
0x60axis_xfer_countMSK Modem Status 3 + +
0x64Rx_Sample_DiscardRx Sample Discard + +
0x68LPF_Config_2PI Controller Configuration Configuration Register 2 + +
0x6Cf1_nco_adjustF1 NCO Frequency Adjust + +
0x70f2_nco_adjustF2 NCO Frequency Adjust + +
0x74f1_errorF1 Error Value + +
0x78f2_errorF2 Error Value + +
0x7CTx_Sync_CtrlTransmitter Sync Control + +
0x80Tx_Sync_CntTransmitter Sync Duration + +
0x84lowpass_ema_alpha1Exponential Moving Average Alpha + +
0x88lowpass_ema_alpha2Exponential Moving Average Alpha + +
0x8Crx_powerReceive Power + +
0x90tx_async_fifo_rd_wr_ptrTx async FIFO read and write pointers + +
0x94rx_async_fifo_rd_wr_ptrRx async FIFO read and write pointers + +
0x98rx_frame_sync_statusFrame Sync Status + +
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/b54cac1ec3dda403a0b7a1db5c224b03a74f9f9d.html b/rdl/outputs/docs/html/content/b54cac1ec3dda403a0b7a1db5c224b03a74f9f9d.html new file mode 100644 index 0000000..f2e7f0c --- /dev/null +++ b/rdl/outputs/docs/html/content/b54cac1ec3dda403a0b7a1db5c224b03a74f9f9d.html @@ -0,0 +1,82 @@ + + +
+

Receive Power

+ + +
+
Absolute Address:
+
+
Base Offset:
0x8c
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+

Description

+
+

Receive power computed from I/Q samples

+
+ +

Contents

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:23]----
[22:0]data + rw0x0 + + + Receive Power + + +
+

+ +

+

Field Descriptions

+ +

data - Receive Power + +

+
+

Value that represent the RMS power of the incoming signal (I-channel)

+

This register is write-to-capture. To read data the following steps are required:

+
    +
  1. Write any value to this register to capture read data +
  2. Read the register +
+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/b60627ebae54f7207a648572a54cbd7f918c0ae7.html b/rdl/outputs/docs/html/content/b60627ebae54f7207a648572a54cbd7f918c0ae7.html new file mode 100644 index 0000000..f4e4805 --- /dev/null +++ b/rdl/outputs/docs/html/content/b60627ebae54f7207a648572a54cbd7f918c0ae7.html @@ -0,0 +1,72 @@ + + +
+

F2 Error Value

+ + +
+
Absolute Address:
+
+
Base Offset:
0x78
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+

Description

+
+

Status Register

+
+ +

Contents

+ + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:0]data + rw0x0 + + + - + + +
+

+ +

+

Field Descriptions

+ +

data + +

+
+

Error value of the F2 Costas loop after each active bit period

+

This register is write-to-capture.

+

To read data the following steps are required:

+

1 - Write any value to this register to capture read data

+

2 - Read the register

+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/b883348faf8a0f9a3da26ea0fc3d9e8d47d5d737.html b/rdl/outputs/docs/html/content/b883348faf8a0f9a3da26ea0fc3d9e8d47d5d737.html new file mode 100644 index 0000000..421d85f --- /dev/null +++ b/rdl/outputs/docs/html/content/b883348faf8a0f9a3da26ea0fc3d9e8d47d5d737.html @@ -0,0 +1,69 @@ + + +
+

Tx F2 NCO Frequency Control Word

+ + +
+
Absolute Address:
+
+
Base Offset:
0x24
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+

Description

+
+

Set Modulator F2 Frequency

+
+ +

Contents

+ + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:0]config_data + rw0x0 + + + Frequency Control Word + + +
+

+ +

+

Field Descriptions

+ +

config_data - Frequency Control Word + +

+
+

Sets the center frequency of the NCO as FW = Fn * 2^32/Fs, +where Fn is the desired NCO frequency, and Fs is the NCO sample rate

+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/c3a0e44e2c6ffcbb57715d4fc6fd621eca17bbe9.html b/rdl/outputs/docs/html/content/c3a0e44e2c6ffcbb57715d4fc6fd621eca17bbe9.html new file mode 100644 index 0000000..e6604b8 --- /dev/null +++ b/rdl/outputs/docs/html/content/c3a0e44e2c6ffcbb57715d4fc6fd621eca17bbe9.html @@ -0,0 +1,106 @@ + + +
+

Transmitter Sync Control

+ + +
+
Absolute Address:
+
+
Base Offset:
0x7c
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+

Description

+
+

Provides control bits for generation of transmitter synchronization patterns

+
+ +

Contents

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:2]----
[1]tx_sync_force + rw0x0 + + + Tx Sync Force + + +
[0]tx_sync_ena + rw0x0 + + + Tx Sync Enable + + +
+

+ +

+

Field Descriptions

+ +

tx_sync_force - Tx Sync Force + +

+
+

0 : Normal operation

+

1 : Continuously transmit synchronization pattern

+
+ +

tx_sync_ena - Tx Sync Enable + +

+
+

0 : Disable sync transmission

+

1 : Enable sync transmission when PTT is asserted

+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/cc5ab06a84343db43279a768a29160c012ea8fcc.html b/rdl/outputs/docs/html/content/cc5ab06a84343db43279a768a29160c012ea8fcc.html new file mode 100644 index 0000000..8ad2a8b --- /dev/null +++ b/rdl/outputs/docs/html/content/cc5ab06a84343db43279a768a29160c012ea8fcc.html @@ -0,0 +1,134 @@ + + +
+

MSK Modem Initialization Control

+ + +
+
Absolute Address:
+
+
Base Offset:
0x8
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+

Description

+
+

Synchronous initialization of MSK Modem functions, does not affect configuration registers.

+
+ +

Contents

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:3]----
[2]rxinit + rw0x1 + + + Rx Init Enable + + +
[1]txinit + rw0x1 + + + Tx Init Enable + + +
[0]txrxinit + rw0x1 + + + Tx/Rx Init Enable + + +
+

+ +

+

Field Descriptions

+ +

rxinit - Rx Init Enable + +

+
+

0 -> Normal Rx operation

+

1 -> Initialize Rx

+
+ +

txinit - Tx Init Enable + +

+
+

0 -> Normal Tx operation

+

1 -> Initialize Tx

+
+ +

txrxinit - Tx/Rx Init Enable + +

+
+

0 -> Normal modem operation

+

1 -> Initialize Tx and Rx

+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/ce06e4ec8a024a37ce1f65c5c90a495b4b9555cf.html b/rdl/outputs/docs/html/content/ce06e4ec8a024a37ce1f65c5c90a495b4b9555cf.html new file mode 100644 index 0000000..8d2655f --- /dev/null +++ b/rdl/outputs/docs/html/content/ce06e4ec8a024a37ce1f65c5c90a495b4b9555cf.html @@ -0,0 +1,72 @@ + + +
+

F2 NCO Frequency Adjust

+ + +
+
Absolute Address:
+
+
Base Offset:
0x70
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+

Description

+
+

Status Register

+
+ +

Contents

+ + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:0]data + rw0x0 + + + - + + +
+

+ +

+

Field Descriptions

+ +

data + +

+
+

Frequency offet applied to the F2 NCO

+

This register is write-to-capture.

+

To read data the following steps are required:

+

1 - Write any value to this register to capture read data

+

2 - Read the register

+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/d4cb92fc9fcd9a12ab08ab5d411dbc399e12cb62.html b/rdl/outputs/docs/html/content/d4cb92fc9fcd9a12ab08ab5d411dbc399e12cb62.html new file mode 100644 index 0000000..6712c3d --- /dev/null +++ b/rdl/outputs/docs/html/content/d4cb92fc9fcd9a12ab08ab5d411dbc399e12cb62.html @@ -0,0 +1,68 @@ + + +
+

PRBS Control 2

+ + +
+
Absolute Address:
+
+
Base Offset:
0x48
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+

Description

+
+

PRBS Polynomial

+
+ +

Contents

+ + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:0]config_data + rw0x0 + + + PRBS Polynomial + + +
+

+ +

+

Field Descriptions

+ +

config_data - PRBS Polynomial + +

+
+

Bit positions set to '1' indicate polynomial feedback positions

+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/db8d99c8aadce2aee57600cd3b0212da9c9972cf.html b/rdl/outputs/docs/html/content/db8d99c8aadce2aee57600cd3b0212da9c9972cf.html new file mode 100644 index 0000000..5fdcba9 --- /dev/null +++ b/rdl/outputs/docs/html/content/db8d99c8aadce2aee57600cd3b0212da9c9972cf.html @@ -0,0 +1,64 @@ + + +
+

Pluto MSK FPGA Hash ID - Upper 32-bits

+ + +
+
Absolute Address:
+
+
Base Offset:
0x4
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+ +

Contents

+ + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:0]hash_id_hi + r0x5555aaaa + + + Hash ID Upper 32-bits + + +
+

+ +

+

Field Descriptions

+ +

hash_id_hi - Hash ID Upper 32-bits + +

+
+

Upper 32-bits of Pluto MSK FPGA Hash ID

+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/dbb506c578ba1e4bb6eaf4767617cd58beb4a3ae.html b/rdl/outputs/docs/html/content/dbb506c578ba1e4bb6eaf4767617cd58beb4a3ae.html new file mode 100644 index 0000000..938039d --- /dev/null +++ b/rdl/outputs/docs/html/content/dbb506c578ba1e4bb6eaf4767617cd58beb4a3ae.html @@ -0,0 +1,78 @@ + + +
+

Transmitter Sync Duration

+ + +
+
Absolute Address:
+
+
Base Offset:
0x80
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+

Description

+
+

Sets the duration of the synchronization tones when enabled

+
+ +

Contents

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:24]----
[23:0]tx_sync_cnt + rw0x0 + + + Tx sync duration + + +
+

+ +

+

Field Descriptions

+ +

tx_sync_cnt - Tx sync duration + +

+
+

Value from 0x00_0000 to 0xFF_FFFF.

+

This value represents the number bit-times the synchronization signal should be sent after PTT is asserted.

+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/e3c786425f5920f3a1e885e740599831cfd792bc.html b/rdl/outputs/docs/html/content/e3c786425f5920f3a1e885e740599831cfd792bc.html new file mode 100644 index 0000000..a01dbd1 --- /dev/null +++ b/rdl/outputs/docs/html/content/e3c786425f5920f3a1e885e740599831cfd792bc.html @@ -0,0 +1,76 @@ + + +
+

Rx async FIFO read and write pointers

+ + +
+
Absolute Address:
+
+
Base Offset:
0x94
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+

Description

+
+

Rx async FIFO read and write pointers

+
+ +

Contents

+ + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:0]data + rw0x0 + + + - + + +
+

+ +

+

Field Descriptions

+ +

data + +

+
+

Read and Write Pointers

+

+Bits 31:16 - write pointer (12-bits) +Bits 15:00 - read pointer (12-bits)

+

This register is write-to-capture. To read data the following steps are required:

+
    +
  1. Write any value to this register to capture read data +
  2. Read the register +
+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/e41b7c226a4ebc36be166e4a2b523cb2a8959870.html b/rdl/outputs/docs/html/content/e41b7c226a4ebc36be166e4a2b523cb2a8959870.html new file mode 100644 index 0000000..bb4822e --- /dev/null +++ b/rdl/outputs/docs/html/content/e41b7c226a4ebc36be166e4a2b523cb2a8959870.html @@ -0,0 +1,104 @@ + + +
+

Rx Sample Discard

+ + +
+
Absolute Address:
+
+
Base Offset:
0x64
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+

Description

+
+

Configure samples discard operation for demodulator

+
+ +

Contents

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:16]----
[15:8]rx_nco_discard + rw0x0 + + + Rx NCO Sample Discard Value + + +
[7:0]rx_sample_discard + rw0x0 + + + Rx Sample Discard Value + + +
+

+ +

+

Field Descriptions

+ +

rx_nco_discard - Rx NCO Sample Discard Value + +

+
+

Number of NCO samples to discard

+
+ +

rx_sample_discard - Rx Sample Discard Value + +

+
+

Number of Rx samples to discard

+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/eca580c1f1dcded555681dfd8a6e15e379cf5f0f.html b/rdl/outputs/docs/html/content/eca580c1f1dcded555681dfd8a6e15e379cf5f0f.html new file mode 100644 index 0000000..2688b8b --- /dev/null +++ b/rdl/outputs/docs/html/content/eca580c1f1dcded555681dfd8a6e15e379cf5f0f.html @@ -0,0 +1,72 @@ + + +
+

F1 PI Controller Accumulator

+ + +
+
Absolute Address:
+
+
Base Offset:
0x58
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+

Description

+
+

Value of the F1 PI Controller Accumulator

+
+ +

Contents

+ + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:0]data + rw0x0 + + + PI Controller Accumulator Value + + +
+

+ +

+

Field Descriptions

+ +

data - PI Controller Accumulator Value + +

+
+

PI Controller Accumulator Value

+

This register is write-to-capture.

+

To read data the following steps are required:

+

1 - Write any value to this register to capture read data

+

2 - Read the register

+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/ee57807489e9b5f5b719044911537b66b3a06bdf.html b/rdl/outputs/docs/html/content/ee57807489e9b5f5b719044911537b66b3a06bdf.html new file mode 100644 index 0000000..06741a0 --- /dev/null +++ b/rdl/outputs/docs/html/content/ee57807489e9b5f5b719044911537b66b3a06bdf.html @@ -0,0 +1,77 @@ + + +
+

Exponential Moving Average Alpha

+ + +
+
Absolute Address:
+
+
Base Offset:
0x88
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+

Description

+
+

Sets the alpha for the EMA

+
+ +

Contents

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:18]----
[17:0]alpha + rw0x0 + + + EMA alpha + + +
+

+ +

+

Field Descriptions

+ +

alpha - EMA alpha + +

+
+

Value from 0x0_0000 to 0x3_FFFF represent the EMA alpha

+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/f439a6888cc769d718b5d38d555e7aed6b422371.html b/rdl/outputs/docs/html/content/f439a6888cc769d718b5d38d555e7aed6b422371.html new file mode 100644 index 0000000..458aa26 --- /dev/null +++ b/rdl/outputs/docs/html/content/f439a6888cc769d718b5d38d555e7aed6b422371.html @@ -0,0 +1,77 @@ + + +
+

Exponential Moving Average Alpha

+ + +
+
Absolute Address:
+
+
Base Offset:
0x84
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+

Description

+
+

Sets the alpha for the EMA

+
+ +

Contents

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:18]----
[17:0]alpha + rw0x0 + + + EMA alpha + + +
+

+ +

+

Field Descriptions

+ +

alpha - EMA alpha + +

+
+

Value from 0x0_0000 to 0x3_FFFF represent the EMA alpha

+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/f7daaf8ea45f55844cf66da35a46142d55a5253a.html b/rdl/outputs/docs/html/content/f7daaf8ea45f55844cf66da35a46142d55a5253a.html new file mode 100644 index 0000000..d3e7289 --- /dev/null +++ b/rdl/outputs/docs/html/content/f7daaf8ea45f55844cf66da35a46142d55a5253a.html @@ -0,0 +1,69 @@ + + +
+

Rx F2 NCO Frequency Control Word

+ + +
+
Absolute Address:
+
+
Base Offset:
0x2c
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+

Description

+
+

Set Demodulator F2 Frequency

+
+ +

Contents

+ + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:0]config_data + rw0x0 + + + Frequency Control Word + + +
+

+ +

+

Field Descriptions

+ +

config_data - Frequency Control Word + +

+
+

Sets the center frequency of the NCO as FW = Fn * 2^32/Fs, +where Fn is the desired NCO frequency, and Fs is the NCO sample rate

+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/content/fd9b9e9189271b3cac659475d0b7621c0ffe0c3f.html b/rdl/outputs/docs/html/content/fd9b9e9189271b3cac659475d0b7621c0ffe0c3f.html new file mode 100644 index 0000000..c4eddb0 --- /dev/null +++ b/rdl/outputs/docs/html/content/fd9b9e9189271b3cac659475d0b7621c0ffe0c3f.html @@ -0,0 +1,73 @@ + + +
+

PRBS Status 1

+ + +
+
Absolute Address:
+
+
Base Offset:
0x54
+
Size:
0x4
+ +
Source:
msk_top_regs.rdl
+ +
+

Description

+
+

PRBS Bit Errors

+
+ +

Contents

+ + + + + + + + + + + + + + + + + + + +
BitsIdentifierAccessResetDecodedName
[31:0]data + rw0x0 + + + PRBS Bit Errors + + +
+

+ +

+

Field Descriptions

+ +

data - PRBS Bit Errors + +

+
+

Number of errored-bits received by the PRBS monitor since last sync +BER can be calculated as the ratio of received bits to errored-bits

+

This register is write-to-capture.

+

To read data the following steps are required:

+

1 - Write any value to this register to capture read data

+

2 - Read the register

+
+
\ No newline at end of file diff --git a/rdl/outputs/docs/html/css/layout.css b/rdl/outputs/docs/html/css/layout.css new file mode 100644 index 0000000..59ab518 --- /dev/null +++ b/rdl/outputs/docs/html/css/layout.css @@ -0,0 +1,209 @@ +/* This file is part of PeakRDL-html . + * and can be redistributed under the terms of GNU GPL v3 . + */ + +/* Base layout */ +html, body { + height: 100%; +} + +button { + cursor: pointer; +} + +img { + max-width: 100%; +} + +#_Sidebar { + height: 100%; +} + +#_SBContents { + width: 19em; + min-width: 19em !important; +} + +#_SBResizer { + width: 6px; + margin-left: -3px; + margin-right: -3px; + cursor: col-resize; +} + +#MainPane { + height: 100%; +} + +#_SBTreeContainer { + display: flex; + flex-direction: column; +} +#_SBTree { + display: inline-flex; + flex-direction: column; + min-width: max-content; +} + +.node { + flex-direction: row; + display: flex; + flex-shrink: 0; +} +.node-link { + flex-grow: 1; +} + +.node-icon { + flex-grow: 0; + flex-shrink: 0; +} + +.node-children { + padding-left: 1em; + display: inline-flex; + flex-direction: column; + min-width: max-content; +} + +.pack-v { + display: flex; + flex-direction: column; +} + +.pack-h { + display: flex; + flex-direction: row; +} + +.scroll-v { + overflow-y: auto; +} + +.scroll-h { + overflow-x: auto; +} + +.stretchy { + flex-grow: 1; + flex-shrink: 1; +} + +.no-stretchy { + flex-grow: 0; + flex-shrink: 0; +} + +#_Overlay { + width: 100%; + height: 100%; + position:absolute; + display:none; + z-index: 2; + cursor:pointer; +} + +#_IdxEditModal { + display: none; /* Hidden by default */ + position: fixed; + z-index: 1; + left: 18.75em; + top: 18.75em; + + padding: 0.625em; +} + +/* arrow thingy on top of modal */ +#_IdxEditModal::before { + content: ""; + width: 0em; + height: 0em; + position: absolute; + left: 2.188em; /* = ([input with] + [modal padding]*2)/2 - [this border_width] */ + top: -1.25em; + border: 0.625em solid transparent; + border-bottom: 0.625em solid; +} + +#_IdxEditInput { + width: 4.375em; +} + +.crumb-idx { + cursor:pointer; +} + +#_AbsAddr div { + cursor: pointer; +} + +#_SearchResults{ + margin: 0em; +} + +#_SearchResults li{ + cursor:pointer; + overflow: hidden; +} + +#_Search, #_SearchBar{ + display: none; +} + +#_SearchInput { + width: 100%; +} + +#_Search { + overflow-wrap: anywhere; +} + +.generic-modal-overlay { + width: 100%; + height: 100%; + position:absolute; + display:none; + z-index: 3; + cursor:pointer; + align-items: center; + justify-content: center; +} + +.generic-modal { + cursor: default; +} + +/* Mobile mode */ +#_Sidebar { + display: none; + position: absolute; + z-index: 3; +} + +#_SBSearchButton, #_SBSearchButtonSpan { + display: none; +} + +/* Desktop mode */ +@media (min-width:950px){ + #_Sidebar { + position: static; + display: flex!important; + z-index: 0; + } + #_SBSearchButton, #_SBSearchButtonSpan { + display: block; + } + + #_MobiTitlebar { + display:none; + } + + #_Overlay { + display: none!important; + } + + .limit-h { + max-width: 900px; + } +} diff --git a/rdl/outputs/docs/html/css/normalize.css b/rdl/outputs/docs/html/css/normalize.css new file mode 100644 index 0000000..47b010e --- /dev/null +++ b/rdl/outputs/docs/html/css/normalize.css @@ -0,0 +1,341 @@ +/*! normalize.css v8.0.0 | MIT License | github.com/necolas/normalize.css */ + +/* Document + ========================================================================== */ + +/** + * 1. Correct the line height in all browsers. + * 2. Prevent adjustments of font size after orientation changes in iOS. + */ + +html { + line-height: 1.15; /* 1 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/* Sections + ========================================================================== */ + +/** + * Remove the margin in all browsers. + */ + +body { + margin: 0; +} + +/** + * Correct the font size and margin on `h1` elements within `section` and + * `article` contexts in Chrome, Firefox, and Safari. + */ + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +/* Grouping content + ========================================================================== */ + +/** + * 1. Add the correct box sizing in Firefox. + * 2. Show the overflow in Edge and IE. + */ + +hr { + box-sizing: content-box; /* 1 */ + height: 0; /* 1 */ + overflow: visible; /* 2 */ +} + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + +pre { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ +} + +/* Text-level semantics + ========================================================================== */ + +/** + * Remove the gray background on active links in IE 10. + */ + +a { + background-color: transparent; +} + +/** + * 1. Remove the bottom border in Chrome 57- + * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. + */ + +abbr[title] { + border-bottom: none; /* 1 */ + text-decoration: underline; /* 2 */ + text-decoration: underline dotted; /* 2 */ +} + +/** + * Add the correct font weight in Chrome, Edge, and Safari. + */ + +b, +strong { + font-weight: bolder; +} + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + +code, +kbd, +samp { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ +} + +/** + * Add the correct font size in all browsers. + */ + +small { + font-size: 80%; +} + +/** + * Prevent `sub` and `sup` elements from affecting the line height in + * all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +/* Embedded content + ========================================================================== */ + +/** + * Remove the border on images inside links in IE 10. + */ + +img { + border-style: none; +} + +/* Forms + ========================================================================== */ + +/** + * 1. Change the font styles in all browsers. + * 2. Remove the margin in Firefox and Safari. + */ + +button, +input, +optgroup, +select, +textarea { + font-family: inherit; /* 1 */ + font-size: 100%; /* 1 */ + line-height: 1.15; /* 1 */ + margin: 0; /* 2 */ +} + +/** + * Show the overflow in IE. + * 1. Show the overflow in Edge. + */ + +button, +input { /* 1 */ + overflow: visible; +} + +/** + * Remove the inheritance of text transform in Edge, Firefox, and IE. + * 1. Remove the inheritance of text transform in Firefox. + */ + +button, +select { /* 1 */ + text-transform: none; +} + +/** + * Correct the inability to style clickable types in iOS and Safari. + */ + +button, +[type="button"], +[type="reset"], +[type="submit"] { + -webkit-appearance: button; +} + +/** + * Remove the inner border and padding in Firefox. + */ + +button::-moz-focus-inner, +[type="button"]::-moz-focus-inner, +[type="reset"]::-moz-focus-inner, +[type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; +} + +/** + * Restore the focus styles unset by the previous rule. + */ + +button:-moz-focusring, +[type="button"]:-moz-focusring, +[type="reset"]:-moz-focusring, +[type="submit"]:-moz-focusring { + outline: 1px dotted ButtonText; +} + +/** + * Correct the padding in Firefox. + */ + +fieldset { + padding: 0.35em 0.75em 0.625em; +} + +/** + * 1. Correct the text wrapping in Edge and IE. + * 2. Correct the color inheritance from `fieldset` elements in IE. + * 3. Remove the padding so developers are not caught out when they zero out + * `fieldset` elements in all browsers. + */ + +legend { + box-sizing: border-box; /* 1 */ + color: inherit; /* 2 */ + display: table; /* 1 */ + max-width: 100%; /* 1 */ + padding: 0; /* 3 */ + white-space: normal; /* 1 */ +} + +/** + * Add the correct vertical alignment in Chrome, Firefox, and Opera. + */ + +progress { + vertical-align: baseline; +} + +/** + * Remove the default vertical scrollbar in IE 10+. + */ + +textarea { + overflow: auto; +} + +/** + * 1. Add the correct box sizing in IE 10. + * 2. Remove the padding in IE 10. + */ + +[type="checkbox"], +[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Correct the cursor style of increment and decrement buttons in Chrome. + */ + +[type="number"]::-webkit-inner-spin-button, +[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +/** + * 1. Correct the odd appearance in Chrome and Safari. + * 2. Correct the outline style in Safari. + */ + +[type="search"] { + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ +} + +/** + * Remove the inner padding in Chrome and Safari on macOS. + */ + +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * 1. Correct the inability to style clickable types in iOS and Safari. + * 2. Change font properties to `inherit` in Safari. + */ + +::-webkit-file-upload-button { + -webkit-appearance: button; /* 1 */ + font: inherit; /* 2 */ +} + +/* Interactive + ========================================================================== */ + +/* + * Add the correct display in Edge, IE 10+, and Firefox. + */ + +details { + display: block; +} + +/* + * Add the correct display in all browsers. + */ + +summary { + display: list-item; +} + +/* Misc + ========================================================================== */ + +/** + * Add the correct display in IE 10+. + */ + +template { + display: none; +} + +/** + * Add the correct display in IE 10. + */ + +[hidden] { + display: none; +} diff --git a/rdl/outputs/docs/html/css/theme.css b/rdl/outputs/docs/html/css/theme.css new file mode 100644 index 0000000..303c3b7 --- /dev/null +++ b/rdl/outputs/docs/html/css/theme.css @@ -0,0 +1,903 @@ +/* This file is part of PeakRDL-html . + * and can be redistributed under the terms of GNU GPL v3 . + */ + +/* ------------------------------ Color Scheme ------------------------------ */ +:root { + --main-text-color:#404040; + --title-text-color: #fff; + --title-text-color-hover: #fff; + --footer-text-color: #808080; + --url-color: #2980b9; + --url-color-hover: #3091d1; + --overlay-bg-rgba: 0,0,0,0.5; + --reserved-text-color:#808080; + --content-preview-text-color:#ccc; + + --offpage-bg-color:#eee; + --main-bg-color:#fcfcfc; + --title-bg-color: #2980b9; + --title-bg-color-hover: #2e8ece; + --alt-row-bg-color:#f3f6f6; + --inline-code-block-bg-color: #fff; + --code-block-bg-color: #efc; + --input-bg-color: #fff; + --input-invalid-bg-color: #f99; + --highlight-color: #f1c40f; + --progressbar-color: #f1c40f; + + --content-border-color: #e1e4e5; + --strong-content-border-color: #aaa; + --blockquote-bar-color: #ccc; + + --button-border-color: #949494; + --button-text-color: #4c4c4c; + --button-gradient-top-color: #f5f5f5; + --button-gradient-bottom-color: #dddddd; + + --button-disabled-border-color: #ccc; + --button-disabled-text-color: #999; + --button-disabled-bg-color: #e8e8e8; + + --admonition-title-text-color: #fff; + --admonition-title-bg-color: #6ab0de; + --admonition-bg-color: #e7f2fa; + --admonition-error-title-bg-color: #f29f97; + --admonition-error-bg-color: #fdf3f2; + --admonition-warning-title-bg-color: #f0b37e; + --admonition-warning-bg-color: #ffedcc; + --admonition-note-title-bg-color: #6ab0de; + --admonition-note-bg-color: #e7f2fa; + --admonition-hint-title-bg-color: #1abc9c; + --admonition-hint-bg-color: #dbfaf4; + + --idx-edit-text-color: #fff; + --idx-edit-bg-color: #2e8ece; + --idx-edit-input-border-color: #2472a4; + + --crumb-idx-hover-text-color: #fff; + --crumb-idx-hover-bg-color: #2e8ece; + + --tree-text-color: #d9d9d9; + --tree-bg-color: #303030; + --tree-border-color: #303030; + --tree-hover-text-color: #d9d9d9; + --tree-hover-bg-color: #4e4a4a; + --tree-hover-border-color: #303030; + --tree-selected-text-color: #444; + --tree-selected-border-color: #c9c9c9; + +} + +@media (prefers-color-scheme: dark) { + :root { + --main-text-color: #C0C0C0; + --title-text-color: #ccc; + --title-text-color-hover: #eee; + --footer-text-color: #444; + --url-color: #2e8fcf; + --url-color-hover: #35a0e6; + --overlay-bg-rgba: 0,0,0,0.65; + --reserved-text-color:#444; + --content-preview-text-color:#888; + + --offpage-bg-color: #111; + --main-bg-color: #000; + --title-bg-color: #005e9a; + --title-bg-color-hover: #2e8ece; + --alt-row-bg-color:#222; + --inline-code-block-bg-color: #111; + --code-block-bg-color: #2a301f; + --input-bg-color: #000; + --input-invalid-bg-color: #A33; + --highlight-color: #7e6500; + --progressbar-color: #7e6500; + + --content-border-color: #444; + --strong-content-border-color: #555; + --blockquote-bar-color: #444; + + --button-border-color: #6c6c6c; + --button-text-color: #999; + --button-gradient-top-color: #444; + --button-gradient-bottom-color: #222; + + --button-disabled-border-color: #555; + --button-disabled-text-color: #555; + --button-disabled-bg-color: #222; + + --admonition-title-text-color: #ccc; + --admonition-title-bg-color: #12806a; + --admonition-bg-color: #263330; + --admonition-error-title-bg-color: #730000; + --admonition-error-bg-color: #300; + --admonition-warning-title-bg-color: #8b6b00; + --admonition-warning-bg-color: #342800; + --admonition-note-title-bg-color: #3d6580; + --admonition-note-bg-color: #262e33; + --admonition-hint-title-bg-color: #12806a; + --admonition-hint-bg-color: #263330; + + --idx-edit-text-color: #ccc; + --idx-edit-bg-color: #005e9a; + --idx-edit-input-border-color: #004e80; + + --crumb-idx-hover-text-color: #000; + --crumb-idx-hover-bg-color: #54abe6; + + --tree-text-color: #d9d9d9; + --tree-bg-color: #303030; + --tree-border-color: #303030; + --tree-hover-text-color: #d9d9d9; + --tree-hover-bg-color: #4e4a4a; + --tree-hover-border-color: #303030; + --tree-selected-text-color: #ccc; + --tree-selected-border-color: #222; + } +} + +/* --------------------------------- General -------------------------------- */ + +html{ + background-color: var(--offpage-bg-color); + font-family: "Lato","proxima-nova","Helvetica Neue",Arial,sans-serif; + font-weight: normal; + color: var(--main-text-color); +} + +a { + text-decoration: none; + color: var(--url-color); +} + +a:hover { + color: var(--url-color-hover); +} + +:not(html) { + line-height: inherit; +} + +h1, h2, h3, h4, h5, h6 { + font-weight: 700; + font-family: "Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif; + color: var(--main-text-color); +} + +table { + border: solid 1px var(--content-border-color); + border-collapse: collapse; + empty-cells: show; + margin-top: 1em; +} + +th { + border-bottom: solid 2px var(--content-border-color); + font-weight: bold; +} + +td, th { + border-color: var(--content-border-color); + padding: 0.5em; +} + +td:first-child, th:first-child { + border-left-width: 0; +} + +tr:nth-child(2n) td { + background-color: var(--alt-row-bg-color); +} + +tr.reserved-field, tr.reserved-addr { + color: var(--reserved-text-color); +} + +td > p:first-child { + margin-top: 0px; +} + +td > p:last-child { + margin-bottom: 0px; +} + +hr { + border: 0; + border-top: solid 1px var(--content-border-color); + margin: 1em 0em; +} + +dt { + font-weight: bold; +} + +blockquote { + margin-left: 0px; + padding-left: 0.25em; + border-left: solid 0.313em var(--blockquote-bar-color); +} + +pre { + background-color: var(--code-block-bg-color); + border: solid 1px var(--content-border-color); + padding: 0.75em; +} + +code { + font-family: SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",Courier,monospace; + font-size: 0.75em; + line-height: 1.4; + + /* inline code format */ + background-color: var(--inline-code-block-bg-color); + border: solid 1px var(--content-border-color); + padding: 0.17em 0.41em;; + font-weight: bold; +} + +pre code { + /* undo inline formatting for code block */ + background-color: inherit; + border: none; + padding: 0em; + font-weight: normal; +} + +input { + background-color: var(--input-bg-color); + color: var(--main-text-color); +} + +input.invalid { + background-color: var(--input-invalid-bg-color); +} + +button { + border-style: solid; + border-width: 1px; + border-color: var(--button-border-color); + color: var(--button-text-color); + border-radius: 2px; + background-image: linear-gradient(var(--button-gradient-top-color), var(--button-gradient-bottom-color)); + padding: 0.25em 0.9em; +} + +button:disabled { + border-color: var(--button-disabled-border-color); + color: var(--button-disabled-text-color); + background-color: var(--button-disabled-bg-color); + background-image: none; +} + + +/*:target, :target td {*/ +.target-highlight, .target-highlight td { + background-color: var(--highlight-color)!important; +} + +mark { + background-color: var(--highlight-color); +} + +#_ProgressBar { + width: 15em; + margin: auto; +} + +#_ProgressBar path { + stroke: var(--strong-content-border-color); + stroke-width: 3; +} + +#_ProgressBar path + path { + stroke: var(--progressbar-color); + stroke-width: 8; +} + +.progressbar-text { + color: var(--main-text-color)!important; +} + +/* ------------------------------- Admonitions ------------------------------ */ +.admonition-title:before { + font-family: "Font Awesome 5 Free"; + font-weight: bold; + content: "\f06a"; + margin-right:4px; +} + +.admonition { + padding:12px; + line-height:24px; + margin-bottom:24px; + background: var(--admonition-bg-color); +} + +.admonition-title { + font-weight:bold; + display:block; + color: var(--admonition-title-text-color); + background: var(--admonition-title-bg-color); + margin:-12px; + padding:6px 12px; + margin-bottom:12px; +} + +.admonition p:last-child { + margin-bottom:0; +} + +.admonition.danger, +.admonition.error{ + background: var(--admonition-error-bg-color); +} + +.admonition.danger .admonition-title, +.admonition.error .admonition-title{ + background: var(--admonition-error-title-bg-color); +} + +.admonition.attention, +.admonition.caution, +.admonition.warning { + background: var(--admonition-warning-bg-color); +} + +.admonition.attention .admonition-title, +.admonition.caution .admonition-title, +.admonition.warning .admonition-title { + background: var(--admonition-warning-title-bg-color); +} + +.admonition.note, +.admonition.seealso { + background: var(--admonition-note-bg-color); +} + +.admonition.note .admonition-title, +.admonition.seealso .admonition-title { + background: var(--admonition-note-title-bg-color); +} + +.admonition.hint, +.admonition.important, +.admonition.tip { + background: var(--admonition-hint-bg-color); +} + +.admonition.hint .admonition-title, +.admonition.important .admonition-title, +.admonition.tip .admonition-title { + background: var(--admonition-hint-title-bg-color); +} + +/* ------------------------------- Button Icons ----------------------------- */ + +.collapse-button::before { + font-family: "Font Awesome 5 Free"; + font-weight: bold; + content: "\f146"; +} + +.search-button::before { + font-family: "Font Awesome 5 Free"; + font-weight: bold; + content: "\f002"; +} + +.close-button::before { + font-family: "Font Awesome 5 Free"; + font-weight: bold; + content: "\f00d"; +} + +.menu-button::before { + font-family: "Font Awesome 5 Free"; + font-weight: bold; + content: "\f0c9"; +} + +.home-button::before { + font-family: "Font Awesome 5 Free"; + font-weight: bold; + content: "\f015"; +} + +.help-button::before { + font-family: "Font Awesome 5 Free"; + font-weight: bold; + content: "\f059"; +} + +.copy-button::before { + font-family: "Font Awesome 5 Free"; + font-weight: normal; + content: "\f0c5"; +} + +.reset-button::before { + font-family: "Font Awesome 5 Free"; + font-weight: bold; + content: "\f2ea"; +} + +/* --------------------------------- Sidebar -------------------------------- */ +#_SBTitlebar { + background-color: var(--title-bg-color); +} + +#_SBTitlebox { + font-size: 1.125em; + font-weight: bold; + text-align: center; + vertical-align: middle; + line-height: 2.2em; + + color: var(--title-text-color); +} + +#_Overlay { + background-color: rgba(var(--overlay-bg-rgba)); +} + +#_SBResizer:hover { + background-color: rgba(128, 128, 128, 0.5); +} + +.sb-button-strip { + padding: 0em 0.3em 0.3em 0.3em; +} + +.sb-button-strip button, .sb-button-strip a.button-link{ + background-color: inherit; + background-image: none; + border: none; + width: 1.25em; + height: 1.25em; + font-size: 1.5em; + text-align: center; + vertical-align: middle; + color: var(--title-text-color); + padding: 0em; + border-radius: 3px; +} + +.sb-button-strip button:hover, .sb-button-strip a.button-link:hover{ + color: var(--title-text-color-hover); + background-color: var(--title-bg-color-hover); + border: none; +} + +#_SBTreeContainer { + background-color: var(--tree-bg-color); + color: var(--tree-text-color); +} + +#_SBTree { + padding-top: 0.5em; +} + +#_SBTree a { + color: inherit; +} + +.node { + line-height: 1.3em; + border-color: var(--tree-border-color); + border-top-style: solid; + border-top-width: 1px; + border-bottom-style: solid; + border-bottom-width: 1px; + border-left-style: solid; + border-left-width: 1px; +} + +.node-icon { + width: 1.25em; + text-align: center; +} + +.node:hover{ + color: var(--tree-hover-text-color); + border-color: var(--tree-hover-border-color); + background-color: var(--tree-hover-bg-color); +} + +.node.open .node-icon::before { + font-family: "Font Awesome 5 Free"; + font-weight: normal; + content: "\f146"; +} + +.node.closed .node-icon::before { + font-family: "Font Awesome 5 Free"; + font-weight: normal; + content: "\f0fe"; +} + +.node.leaf .node-icon::before { + font-weight: normal; + content: "\2022"; +} + +.node.selected { + background-color: var(--main-bg-color); + color: var(--tree-selected-text-color); + font-weight: bold; + border-color: var(--tree-selected-border-color); +} + +.node.selected a:focus { + outline: none; +} + +/* ----------------------------- Mobile Titlebar ---------------------------- */ +#_MobiTitlebar { + background-color: var(--title-bg-color); + color: var(--title-text-color); +} + +#_MobiTitlebox { + vertical-align: middle; + font-size: 1.125em; + font-weight: bold; + text-align: center; + line-height: 2em; +} + +#_MobiTitlebar button{ + background-color: inherit; + background-image: none; + border: none; + font-size: 1.5em; + width: 1.5em; + height: 1.5em; + line-height: 1.5em; + text-align: center; + vertical-align: middle; + color: var(--title-text-color); + padding: 0em; +} + +#_MobiTitlebar button:hover{ + color: var(--title-text-color-hover); + background-color: var(--title-bg-color-hover); + border: none; +} +/* ------------------------------- Main Window ------------------------------ */ + +.main { + background-color: var(--main-bg-color); + padding-left: 1.875em; + padding-right: 1.875em; +} + +#_Crumbtrail { + padding-top: 0.875em; +} + +.crumb-separator { + padding: 0em 0.25em; +} + +.crumb-idx { + font-weight: bold; + padding: 0.07em; +} + +.crumb-idx:hover{ + background-color: var(--crumb-idx-hover-bg-color); + color: var(--crumb-idx-hover-text-color); +} + +dl.node-info { + display: grid; + justify-content: start; +} + +.node-info dt{ + grid-column: 1; +} + +.node-info dd { + grid-column: 2; + margin-left: 0.5em; +} + +#_AbsAddr div { + display: inline; + visibility: hidden; + color: var(--url-color); + margin-left: 1em; +} +#_AbsAddr div:hover { + color: var(--url-color-hover); +} + +#_AbsAddr:hover div { + visibility: visible; +} + +#_AbsAddr div::after { + font-family: "Font Awesome 5 Free"; + font-weight: bold; + content: "\f05a"; +} + +div#_AbsAddrDetails { + display: none; + grid-column: 2; + margin-left: 0.5em; + border-left: solid 0.313em var(--blockquote-bar-color); + padding-left: 0.5em; +} + +div#_AbsAddrDetails.open { + display: grid; +} + +#_AbsAddrDetails dt{ + grid-column: 1; +} + +#_AbsAddrDetails dd { + grid-column: 2; + margin-left: 0.5em; +} + + +input.field-value-tester { + border: solid 1px var(--strong-content-border-color); + padding: 0.25em 0.5em; + width: 9em; +} + +select.field-value-enum-tester { + padding: 0.0em 0.25em; + width: 12em; + height: 2.3em; + font-size: 0.75em; +} + +input#_RegValueTester { + border: solid 1px var(--strong-content-border-color); + padding: 0.25em 0.5em; + width: 8em; +} + +footer { + padding-bottom: 0.875em; + color: var(--footer-text-color); +} + +.headerlink { + visibility: hidden; +} + +.headerlink::after { + font-family: "Font Awesome 5 Free"; + font-size: 0.75em; + font-weight: bold; + content: "\f0c1"; +} + +.radix-button { + font-size: 0.79em; + font-weight: bold; + padding: 0.25em 0.48em; + border-style: solid; + border-width: 1px; + border-color: var(--button-border-color); + color: var(--button-text-color); + border-radius: 2px; + background-image: linear-gradient(var(--button-gradient-top-color), var(--button-gradient-bottom-color)); +} + +.reset-button { + font-size: 0.90em; + padding: 0.30em 0.50em; + border-style: solid; + border-width: 1px; + border-color: var(--button-border-color); + color: var(--button-text-color); + border-radius: 2px; + background-image: linear-gradient(var(--button-gradient-top-color), var(--button-gradient-bottom-color)); +} + +h1:hover .headerlink::after, +h2:hover .headerlink::after, +h3:hover .headerlink::after, +h4:hover .headerlink::after, +tr:hover .headerlink::after { + visibility: visible; +} + +/* --------------------------------- Search --------------------------------- */ +#_SearchBar { + padding-top: 0.875em; + padding-bottom: 0.875em; +} + +#_SearchBar input { + border: solid 1px var(--strong-content-border-color); + padding: 0.5em 1em; + font-size: 1.125em; +} + +#_SearchResults { + padding: 0em; + width: 100%; +} + +#_SearchResults li:first-child { + border-top: solid 1px var(--content-border-color); +} + +#_SearchResults li { + display: block; + width: 100%; + padding: 0.5em 0em; + border-bottom: solid 1px var(--content-border-color); +} + +#_SearchResults .selected { + background-color: var(--alt-row-bg-color); +} + +#_SearchResults a { + color: var(--main-text-color); +} + +.search-content-preview { + color: var(--content-preview-text-color); + padding-left: 2em; + padding-top: 0.5em; + } + +/* --------------------------- Index Editor Modal --------------------------- */ +#_IdxEditModal { + background-color: var(--idx-edit-bg-color); + box-shadow: rgba(0, 0, 0, 0.25) 1px 3px 6px 1px; +} + +#_IdxEditModal::before { + border-bottom-color: var(--idx-edit-bg-color); +} + +#_IdxEditInput { + border: solid 1px var(--idx-edit-input-border-color); + padding: 0.25em 0.5em; +} + +#_IdxEditRange { + color: var(--idx-edit-text-color); +} + +/* ------------------------------ Generic Modal ----------------------------- */ +.generic-modal-overlay { + background-color: rgba(var(--overlay-bg-rgba)); +} + +.generic-modal { + background-color: var(--main-bg-color); + border: 1px solid var(--strong-content-border-color); + padding: 0em 1em 1em 1em; +} + +.generic-modal h1 { + font-size: 1.5em; +} + +.generic-modal h2 { + font-size: 1.3em; +} + +.generic-modal h3 { + font-size: 1.1em; +} + +/* ------------------------------- Help Modal ------------------------------- */ +.kb-shortcut-key { + border: solid 1px var(--strong-content-border-color); + background-color: var(--alt-row-bg-color); + padding: 0.125em 0.25em; + margin-left: 0.125em; + margin-right: 0.125em; + border-radius: 0.25em; +} + +.generic-modal dt { + margin-top: 1em; + margin-bottom: 0.1em; +} + +/* ---------------------------------- Fonts --------------------------------- */ +@font-face { + font-family:"Lato"; + font-weight:400; + font-style:normal; + src:url("../fonts/Lato/lato-regular.eot"); + src:url("../fonts/Lato/lato-regular.eot?#iefix") format("embedded-opentype"), + url("../fonts/Lato/lato-regular.woff2") format("woff2"), + url("../fonts/Lato/lato-regular.woff") format("woff"), + url("../fonts/Lato/lato-regular.ttf") format("truetype"); +} +@font-face { + font-family:"Lato"; + font-weight:700; + font-style:normal; + src:url("../fonts/Lato/lato-bold.eot"); + src:url("../fonts/Lato/lato-bold.eot?#iefix") format("embedded-opentype"), + url("../fonts/Lato/lato-bold.woff2") format("woff2"), + url("../fonts/Lato/lato-bold.woff") format("woff"), + url("../fonts/Lato/lato-bold.ttf") format("truetype"); +} +@font-face { + font-family:"Lato"; + font-weight:700; + font-style:italic; + src:url("../fonts/Lato/lato-bolditalic.eot"); + src:url("../fonts/Lato/lato-bolditalic.eot?#iefix") format("embedded-opentype"), + url("../fonts/Lato/lato-bolditalic.woff2") format("woff2"), + url("../fonts/Lato/lato-bolditalic.woff") format("woff"), + url("../fonts/Lato/lato-bolditalic.ttf") format("truetype"); +} +@font-face { + font-family:"Lato"; + font-weight:400; + font-style:italic; + src:url("../fonts/Lato/lato-italic.eot"); + src:url("../fonts/Lato/lato-italic.eot?#iefix") format("embedded-opentype"), + url("../fonts/Lato/lato-italic.woff2") format("woff2"), + url("../fonts/Lato/lato-italic.woff") format("woff"), + url("../fonts/Lato/lato-italic.ttf") format("truetype"); +} +@font-face { + font-family:"Roboto Slab"; + font-weight:400; + font-style:normal; + src:url("../fonts/RobotoSlab/roboto-slab.eot"); + src:url("../fonts/RobotoSlab/roboto-slab-v7-regular.eot?#iefix") format("embedded-opentype"), + url("../fonts/RobotoSlab/roboto-slab-v7-regular.woff2") format("woff2"), + url("../fonts/RobotoSlab/roboto-slab-v7-regular.woff") format("woff"), + url("../fonts/RobotoSlab/roboto-slab-v7-regular.ttf") format("truetype") +} +@font-face { + font-family:"Roboto Slab"; + font-weight:700; + font-style:normal; + src:url("../fonts/RobotoSlab/roboto-slab-v7-bold.eot"); + src:url("../fonts/RobotoSlab/roboto-slab-v7-bold.eot?#iefix") format("embedded-opentype"), + url("../fonts/RobotoSlab/roboto-slab-v7-bold.woff2") format("woff2"), + url("../fonts/RobotoSlab/roboto-slab-v7-bold.woff") format("woff"), + url("../fonts/RobotoSlab/roboto-slab-v7-bold.ttf") format("truetype") +} + + +/*! + * Font Awesome Free 5.3.1 by @fontawesome - https://fontawesome.com + * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */ +@font-face { + font-family: 'Font Awesome 5 Free'; + font-weight: 900; + font-style: normal; + src:url("../fonts/FontAwesome/fa-solid-900.eot"); + src:url("../fonts/FontAwesome/fa-solid-900.eot?#iefix") format("embedded-opentype"), + url("../fonts/FontAwesome/fa-solid-900.woff2") format("woff2"), + url("../fonts/FontAwesome/fa-solid-900.woff") format("woff"), + url("../fonts/FontAwesome/fa-solid-900.ttf") format("truetype"), + url("../fonts/FontAwesome/fa-solid-900.svg#fontawesome") format("svg"); +} + +@font-face { + font-family: 'Font Awesome 5 Free'; + font-weight: 400; + font-style: normal; + src:url("../fonts/FontAwesome/fa-regular-400.eot"); + src:url("../fonts/FontAwesome/fa-regular-400.eot?#iefix") format("embedded-opentype"), + url("../fonts/FontAwesome/fa-regular-400.woff2") format("woff2"), + url("../fonts/FontAwesome/fa-regular-400.woff") format("woff"), + url("../fonts/FontAwesome/fa-regular-400.ttf") format("truetype"), + url("../fonts/FontAwesome/fa-regular-400.svg#fontawesome") format("svg"); +} diff --git a/rdl/outputs/docs/html/data/data_index.js b/rdl/outputs/docs/html/data/data_index.js new file mode 100644 index 0000000..b121232 --- /dev/null +++ b/rdl/outputs/docs/html/data/data_index.js @@ -0,0 +1,4 @@ +var N_RAL_FILES = 1; +var N_RAL_NODES_PER_FILE = 16384; +var RootNodeIds = [0]; +var PageInfo = {"title":null}; diff --git a/rdl/outputs/docs/html/data/ral-data-0.json b/rdl/outputs/docs/html/data/ral-data-0.json new file mode 100644 index 0000000..ca3c1e5 --- /dev/null +++ b/rdl/outputs/docs/html/data/ral-data-0.json @@ -0,0 +1 @@ +[{"parent":null,"children":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39],"name":"msk_top_regs","offset":"0","size":"9c"},{"parent":0,"children":[],"name":"Hash_ID_Low","offset":"0","size":"4","fields":[{"name":"hash_id_lo","lsb":0,"msb":31,"reset":"aaaa5555","disp":"H"}]},{"parent":0,"children":[],"name":"Hash_ID_High","offset":"4","size":"4","fields":[{"name":"hash_id_hi","lsb":0,"msb":31,"reset":"5555aaaa","disp":"H"}]},{"parent":0,"children":[],"name":"MSK_Init","offset":"8","size":"4","fields":[{"name":"txrxinit","lsb":0,"msb":0,"reset":"1","disp":"H"},{"name":"txinit","lsb":1,"msb":1,"reset":"1","disp":"H"},{"name":"rxinit","lsb":2,"msb":2,"reset":"1","disp":"H"}]},{"parent":0,"children":[],"name":"MSK_Control","offset":"c","size":"4","fields":[{"name":"ptt","lsb":0,"msb":0,"reset":"0","disp":"H"},{"name":"loopback_ena","lsb":1,"msb":1,"reset":"0","disp":"H"},{"name":"rx_invert","lsb":2,"msb":2,"reset":"0","disp":"H"},{"name":"clear_counts","lsb":3,"msb":3,"reset":"0","disp":"H"},{"name":"diff_encoder_loopback","lsb":4,"msb":4,"reset":"0","disp":"H"}]},{"parent":0,"children":[],"name":"MSK_Status","offset":"10","size":"4","fields":[{"name":"demod_sync_lock","lsb":0,"msb":0,"reset":"0","disp":"H"},{"name":"tx_enable","lsb":1,"msb":1,"reset":"0","disp":"H"},{"name":"rx_enable","lsb":2,"msb":2,"reset":"0","disp":"H"},{"name":"tx_axis_valid","lsb":3,"msb":3,"reset":"0","disp":"H"}]},{"parent":0,"children":[],"name":"Tx_Bit_Count","offset":"14","size":"4","fields":[{"name":"data","lsb":0,"msb":31,"reset":"0","disp":"H"}]},{"parent":0,"children":[],"name":"Tx_Enable_Count","offset":"18","size":"4","fields":[{"name":"data","lsb":0,"msb":31,"reset":"0","disp":"H"}]},{"parent":0,"children":[],"name":"Fb_FreqWord","offset":"1c","size":"4","fields":[{"name":"config_data","lsb":0,"msb":31,"reset":"0","disp":"H"}]},{"parent":0,"children":[],"name":"TX_F1_FreqWord","offset":"20","size":"4","fields":[{"name":"config_data","lsb":0,"msb":31,"reset":"0","disp":"H"}]},{"parent":0,"children":[],"name":"TX_F2_FreqWord","offset":"24","size":"4","fields":[{"name":"config_data","lsb":0,"msb":31,"reset":"0","disp":"H"}]},{"parent":0,"children":[],"name":"RX_F1_FreqWord","offset":"28","size":"4","fields":[{"name":"config_data","lsb":0,"msb":31,"reset":"0","disp":"H"}]},{"parent":0,"children":[],"name":"RX_F2_FreqWord","offset":"2c","size":"4","fields":[{"name":"config_data","lsb":0,"msb":31,"reset":"0","disp":"H"}]},{"parent":0,"children":[],"name":"LPF_Config_0","offset":"30","size":"4","fields":[{"name":"lpf_freeze","lsb":0,"msb":0,"reset":"0","disp":"H"},{"name":"lpf_zero","lsb":1,"msb":1,"reset":"0","disp":"H"},{"name":"prbs_reserved","lsb":2,"msb":7,"reset":"0","disp":"H"},{"name":"lpf_alpha","lsb":8,"msb":31,"reset":"0","disp":"H"}]},{"parent":0,"children":[],"name":"LPF_Config_1","offset":"34","size":"4","fields":[{"name":"i_gain","lsb":0,"msb":23,"reset":"0","disp":"H"},{"name":"i_shift","lsb":24,"msb":31,"reset":"0","disp":"H"}]},{"parent":0,"children":[],"name":"Tx_Data_Width","offset":"38","size":"4","fields":[{"name":"data_width","lsb":0,"msb":7,"reset":"8","disp":"H"}]},{"parent":0,"children":[],"name":"Rx_Data_Width","offset":"3c","size":"4","fields":[{"name":"data_width","lsb":0,"msb":7,"reset":"8","disp":"H"}]},{"parent":0,"children":[],"name":"PRBS_Control","offset":"40","size":"4","fields":[{"name":"prbs_sel","lsb":0,"msb":0,"reset":"0","disp":"H"},{"name":"prbs_error_insert","lsb":1,"msb":1,"reset":"0","disp":"H"},{"name":"prbs_clear","lsb":2,"msb":2,"reset":"0","disp":"H"},{"name":"prbs_manual_sync","lsb":3,"msb":3,"reset":"0","disp":"H"},{"name":"prbs_reserved","lsb":4,"msb":15,"reset":"0","disp":"H"},{"name":"prbs_sync_threshold","lsb":16,"msb":31,"reset":"0","disp":"H"}]},{"parent":0,"children":[],"name":"PRBS_Initial_State","offset":"44","size":"4","fields":[{"name":"config_data","lsb":0,"msb":31,"reset":"0","disp":"H"}]},{"parent":0,"children":[],"name":"PRBS_Polynomial","offset":"48","size":"4","fields":[{"name":"config_data","lsb":0,"msb":31,"reset":"0","disp":"H"}]},{"parent":0,"children":[],"name":"PRBS_Error_Mask","offset":"4c","size":"4","fields":[{"name":"config_data","lsb":0,"msb":31,"reset":"0","disp":"H"}]},{"parent":0,"children":[],"name":"PRBS_Bit_Count","offset":"50","size":"4","fields":[{"name":"data","lsb":0,"msb":31,"reset":"0","disp":"H"}]},{"parent":0,"children":[],"name":"PRBS_Error_Count","offset":"54","size":"4","fields":[{"name":"data","lsb":0,"msb":31,"reset":"0","disp":"H"}]},{"parent":0,"children":[],"name":"LPF_Accum_F1","offset":"58","size":"4","fields":[{"name":"data","lsb":0,"msb":31,"reset":"0","disp":"H"}]},{"parent":0,"children":[],"name":"LPF_Accum_F2","offset":"5c","size":"4","fields":[{"name":"data","lsb":0,"msb":31,"reset":"0","disp":"H"}]},{"parent":0,"children":[],"name":"axis_xfer_count","offset":"60","size":"4","fields":[{"name":"data","lsb":0,"msb":31,"reset":"0","disp":"H"}]},{"parent":0,"children":[],"name":"Rx_Sample_Discard","offset":"64","size":"4","fields":[{"name":"rx_sample_discard","lsb":0,"msb":7,"reset":"0","disp":"H"},{"name":"rx_nco_discard","lsb":8,"msb":15,"reset":"0","disp":"H"}]},{"parent":0,"children":[],"name":"LPF_Config_2","offset":"68","size":"4","fields":[{"name":"p_gain","lsb":0,"msb":23,"reset":"0","disp":"H"},{"name":"p_shift","lsb":24,"msb":31,"reset":"0","disp":"H"}]},{"parent":0,"children":[],"name":"f1_nco_adjust","offset":"6c","size":"4","fields":[{"name":"data","lsb":0,"msb":31,"reset":"0","disp":"H"}]},{"parent":0,"children":[],"name":"f2_nco_adjust","offset":"70","size":"4","fields":[{"name":"data","lsb":0,"msb":31,"reset":"0","disp":"H"}]},{"parent":0,"children":[],"name":"f1_error","offset":"74","size":"4","fields":[{"name":"data","lsb":0,"msb":31,"reset":"0","disp":"H"}]},{"parent":0,"children":[],"name":"f2_error","offset":"78","size":"4","fields":[{"name":"data","lsb":0,"msb":31,"reset":"0","disp":"H"}]},{"parent":0,"children":[],"name":"Tx_Sync_Ctrl","offset":"7c","size":"4","fields":[{"name":"tx_sync_ena","lsb":0,"msb":0,"reset":"0","disp":"H"},{"name":"tx_sync_force","lsb":1,"msb":1,"reset":"0","disp":"H"}]},{"parent":0,"children":[],"name":"Tx_Sync_Cnt","offset":"80","size":"4","fields":[{"name":"tx_sync_cnt","lsb":0,"msb":23,"reset":"0","disp":"H"}]},{"parent":0,"children":[],"name":"lowpass_ema_alpha1","offset":"84","size":"4","fields":[{"name":"alpha","lsb":0,"msb":17,"reset":"0","disp":"H"}]},{"parent":0,"children":[],"name":"lowpass_ema_alpha2","offset":"88","size":"4","fields":[{"name":"alpha","lsb":0,"msb":17,"reset":"0","disp":"H"}]},{"parent":0,"children":[],"name":"rx_power","offset":"8c","size":"4","fields":[{"name":"data","lsb":0,"msb":22,"reset":"0","disp":"H"}]},{"parent":0,"children":[],"name":"tx_async_fifo_rd_wr_ptr","offset":"90","size":"4","fields":[{"name":"data","lsb":0,"msb":31,"reset":"0","disp":"H"}]},{"parent":0,"children":[],"name":"rx_async_fifo_rd_wr_ptr","offset":"94","size":"4","fields":[{"name":"data","lsb":0,"msb":31,"reset":"0","disp":"H"}]},{"parent":0,"children":[],"name":"rx_frame_sync_status","offset":"98","size":"4","fields":[{"name":"frame_sync_locked","lsb":0,"msb":0,"reset":"0","disp":"H"},{"name":"frame_buffer_overflow","lsb":1,"msb":1,"reset":"0","disp":"H"},{"name":"frames_received","lsb":2,"msb":25,"reset":"0","disp":"H"},{"name":"frame_sync_errors","lsb":26,"msb":31,"reset":"0","disp":"H"}]}] \ No newline at end of file diff --git a/rdl/outputs/docs/html/favicon.png b/rdl/outputs/docs/html/favicon.png new file mode 100644 index 0000000..d2a8088 Binary files /dev/null and b/rdl/outputs/docs/html/favicon.png differ diff --git a/rdl/outputs/docs/html/fonts/FontAwesome/fa-regular-400.eot b/rdl/outputs/docs/html/fonts/FontAwesome/fa-regular-400.eot new file mode 100644 index 0000000..656e9a0 Binary files /dev/null and b/rdl/outputs/docs/html/fonts/FontAwesome/fa-regular-400.eot differ diff --git a/rdl/outputs/docs/html/fonts/FontAwesome/fa-regular-400.svg b/rdl/outputs/docs/html/fonts/FontAwesome/fa-regular-400.svg new file mode 100644 index 0000000..0085843 --- /dev/null +++ b/rdl/outputs/docs/html/fonts/FontAwesome/fa-regular-400.svg @@ -0,0 +1,467 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/rdl/outputs/docs/html/fonts/FontAwesome/fa-regular-400.ttf b/rdl/outputs/docs/html/fonts/FontAwesome/fa-regular-400.ttf new file mode 100644 index 0000000..36a7de3 Binary files /dev/null and b/rdl/outputs/docs/html/fonts/FontAwesome/fa-regular-400.ttf differ diff --git a/rdl/outputs/docs/html/fonts/FontAwesome/fa-regular-400.woff b/rdl/outputs/docs/html/fonts/FontAwesome/fa-regular-400.woff new file mode 100644 index 0000000..f7fab85 Binary files /dev/null and b/rdl/outputs/docs/html/fonts/FontAwesome/fa-regular-400.woff differ diff --git a/rdl/outputs/docs/html/fonts/FontAwesome/fa-regular-400.woff2 b/rdl/outputs/docs/html/fonts/FontAwesome/fa-regular-400.woff2 new file mode 100644 index 0000000..719a712 Binary files /dev/null and b/rdl/outputs/docs/html/fonts/FontAwesome/fa-regular-400.woff2 differ diff --git a/rdl/outputs/docs/html/fonts/FontAwesome/fa-solid-900.eot b/rdl/outputs/docs/html/fonts/FontAwesome/fa-solid-900.eot new file mode 100644 index 0000000..4e4cbb2 Binary files /dev/null and b/rdl/outputs/docs/html/fonts/FontAwesome/fa-solid-900.eot differ diff --git a/rdl/outputs/docs/html/fonts/FontAwesome/fa-solid-900.svg b/rdl/outputs/docs/html/fonts/FontAwesome/fa-solid-900.svg new file mode 100644 index 0000000..4f5aa88 --- /dev/null +++ b/rdl/outputs/docs/html/fonts/FontAwesome/fa-solid-900.svg @@ -0,0 +1,2444 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/rdl/outputs/docs/html/fonts/FontAwesome/fa-solid-900.ttf b/rdl/outputs/docs/html/fonts/FontAwesome/fa-solid-900.ttf new file mode 100644 index 0000000..2a05512 Binary files /dev/null and b/rdl/outputs/docs/html/fonts/FontAwesome/fa-solid-900.ttf differ diff --git a/rdl/outputs/docs/html/fonts/FontAwesome/fa-solid-900.woff b/rdl/outputs/docs/html/fonts/FontAwesome/fa-solid-900.woff new file mode 100644 index 0000000..839528c Binary files /dev/null and b/rdl/outputs/docs/html/fonts/FontAwesome/fa-solid-900.woff differ diff --git a/rdl/outputs/docs/html/fonts/FontAwesome/fa-solid-900.woff2 b/rdl/outputs/docs/html/fonts/FontAwesome/fa-solid-900.woff2 new file mode 100644 index 0000000..3aae386 Binary files /dev/null and b/rdl/outputs/docs/html/fonts/FontAwesome/fa-solid-900.woff2 differ diff --git a/rdl/outputs/docs/html/fonts/Lato/lato-bold.eot b/rdl/outputs/docs/html/fonts/Lato/lato-bold.eot new file mode 100644 index 0000000..3361183 Binary files /dev/null and b/rdl/outputs/docs/html/fonts/Lato/lato-bold.eot differ diff --git a/rdl/outputs/docs/html/fonts/Lato/lato-bold.ttf b/rdl/outputs/docs/html/fonts/Lato/lato-bold.ttf new file mode 100644 index 0000000..29f691d Binary files /dev/null and b/rdl/outputs/docs/html/fonts/Lato/lato-bold.ttf differ diff --git a/rdl/outputs/docs/html/fonts/Lato/lato-bold.woff b/rdl/outputs/docs/html/fonts/Lato/lato-bold.woff new file mode 100644 index 0000000..c6dff51 Binary files /dev/null and b/rdl/outputs/docs/html/fonts/Lato/lato-bold.woff differ diff --git a/rdl/outputs/docs/html/fonts/Lato/lato-bold.woff2 b/rdl/outputs/docs/html/fonts/Lato/lato-bold.woff2 new file mode 100644 index 0000000..bb19504 Binary files /dev/null and b/rdl/outputs/docs/html/fonts/Lato/lato-bold.woff2 differ diff --git a/rdl/outputs/docs/html/fonts/Lato/lato-bolditalic.eot b/rdl/outputs/docs/html/fonts/Lato/lato-bolditalic.eot new file mode 100644 index 0000000..3d41549 Binary files /dev/null and b/rdl/outputs/docs/html/fonts/Lato/lato-bolditalic.eot differ diff --git a/rdl/outputs/docs/html/fonts/Lato/lato-bolditalic.ttf b/rdl/outputs/docs/html/fonts/Lato/lato-bolditalic.ttf new file mode 100644 index 0000000..f402040 Binary files /dev/null and b/rdl/outputs/docs/html/fonts/Lato/lato-bolditalic.ttf differ diff --git a/rdl/outputs/docs/html/fonts/Lato/lato-bolditalic.woff b/rdl/outputs/docs/html/fonts/Lato/lato-bolditalic.woff new file mode 100644 index 0000000..88ad05b Binary files /dev/null and b/rdl/outputs/docs/html/fonts/Lato/lato-bolditalic.woff differ diff --git a/rdl/outputs/docs/html/fonts/Lato/lato-bolditalic.woff2 b/rdl/outputs/docs/html/fonts/Lato/lato-bolditalic.woff2 new file mode 100644 index 0000000..c4e3d80 Binary files /dev/null and b/rdl/outputs/docs/html/fonts/Lato/lato-bolditalic.woff2 differ diff --git a/rdl/outputs/docs/html/fonts/Lato/lato-italic.eot b/rdl/outputs/docs/html/fonts/Lato/lato-italic.eot new file mode 100644 index 0000000..3f82642 Binary files /dev/null and b/rdl/outputs/docs/html/fonts/Lato/lato-italic.eot differ diff --git a/rdl/outputs/docs/html/fonts/Lato/lato-italic.ttf b/rdl/outputs/docs/html/fonts/Lato/lato-italic.ttf new file mode 100644 index 0000000..b4bfc9b Binary files /dev/null and b/rdl/outputs/docs/html/fonts/Lato/lato-italic.ttf differ diff --git a/rdl/outputs/docs/html/fonts/Lato/lato-italic.woff b/rdl/outputs/docs/html/fonts/Lato/lato-italic.woff new file mode 100644 index 0000000..76114bc Binary files /dev/null and b/rdl/outputs/docs/html/fonts/Lato/lato-italic.woff differ diff --git a/rdl/outputs/docs/html/fonts/Lato/lato-italic.woff2 b/rdl/outputs/docs/html/fonts/Lato/lato-italic.woff2 new file mode 100644 index 0000000..3404f37 Binary files /dev/null and b/rdl/outputs/docs/html/fonts/Lato/lato-italic.woff2 differ diff --git a/rdl/outputs/docs/html/fonts/Lato/lato-regular.eot b/rdl/outputs/docs/html/fonts/Lato/lato-regular.eot new file mode 100644 index 0000000..11e3f2a Binary files /dev/null and b/rdl/outputs/docs/html/fonts/Lato/lato-regular.eot differ diff --git a/rdl/outputs/docs/html/fonts/Lato/lato-regular.ttf b/rdl/outputs/docs/html/fonts/Lato/lato-regular.ttf new file mode 100644 index 0000000..74decd9 Binary files /dev/null and b/rdl/outputs/docs/html/fonts/Lato/lato-regular.ttf differ diff --git a/rdl/outputs/docs/html/fonts/Lato/lato-regular.woff b/rdl/outputs/docs/html/fonts/Lato/lato-regular.woff new file mode 100644 index 0000000..ae1307f Binary files /dev/null and b/rdl/outputs/docs/html/fonts/Lato/lato-regular.woff differ diff --git a/rdl/outputs/docs/html/fonts/Lato/lato-regular.woff2 b/rdl/outputs/docs/html/fonts/Lato/lato-regular.woff2 new file mode 100644 index 0000000..3bf9843 Binary files /dev/null and b/rdl/outputs/docs/html/fonts/Lato/lato-regular.woff2 differ diff --git a/rdl/outputs/docs/html/fonts/RobotoSlab/roboto-slab-v7-bold.eot b/rdl/outputs/docs/html/fonts/RobotoSlab/roboto-slab-v7-bold.eot new file mode 100644 index 0000000..79dc8ef Binary files /dev/null and b/rdl/outputs/docs/html/fonts/RobotoSlab/roboto-slab-v7-bold.eot differ diff --git a/rdl/outputs/docs/html/fonts/RobotoSlab/roboto-slab-v7-bold.ttf b/rdl/outputs/docs/html/fonts/RobotoSlab/roboto-slab-v7-bold.ttf new file mode 100644 index 0000000..df5d1df Binary files /dev/null and b/rdl/outputs/docs/html/fonts/RobotoSlab/roboto-slab-v7-bold.ttf differ diff --git a/rdl/outputs/docs/html/fonts/RobotoSlab/roboto-slab-v7-bold.woff b/rdl/outputs/docs/html/fonts/RobotoSlab/roboto-slab-v7-bold.woff new file mode 100644 index 0000000..6cb6000 Binary files /dev/null and b/rdl/outputs/docs/html/fonts/RobotoSlab/roboto-slab-v7-bold.woff differ diff --git a/rdl/outputs/docs/html/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 b/rdl/outputs/docs/html/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 new file mode 100644 index 0000000..7059e23 Binary files /dev/null and b/rdl/outputs/docs/html/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 differ diff --git a/rdl/outputs/docs/html/fonts/RobotoSlab/roboto-slab-v7-regular.eot b/rdl/outputs/docs/html/fonts/RobotoSlab/roboto-slab-v7-regular.eot new file mode 100644 index 0000000..2f7ca78 Binary files /dev/null and b/rdl/outputs/docs/html/fonts/RobotoSlab/roboto-slab-v7-regular.eot differ diff --git a/rdl/outputs/docs/html/fonts/RobotoSlab/roboto-slab-v7-regular.ttf b/rdl/outputs/docs/html/fonts/RobotoSlab/roboto-slab-v7-regular.ttf new file mode 100644 index 0000000..eb52a79 Binary files /dev/null and b/rdl/outputs/docs/html/fonts/RobotoSlab/roboto-slab-v7-regular.ttf differ diff --git a/rdl/outputs/docs/html/fonts/RobotoSlab/roboto-slab-v7-regular.woff b/rdl/outputs/docs/html/fonts/RobotoSlab/roboto-slab-v7-regular.woff new file mode 100644 index 0000000..f815f63 Binary files /dev/null and b/rdl/outputs/docs/html/fonts/RobotoSlab/roboto-slab-v7-regular.woff differ diff --git a/rdl/outputs/docs/html/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 b/rdl/outputs/docs/html/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 new file mode 100644 index 0000000..f2c76e5 Binary files /dev/null and b/rdl/outputs/docs/html/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 differ diff --git a/rdl/outputs/docs/html/index.html b/rdl/outputs/docs/html/index.html new file mode 100644 index 0000000..8fdb151 --- /dev/null +++ b/rdl/outputs/docs/html/index.html @@ -0,0 +1,123 @@ + + + + + + + + None + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
None
+
+ + + + + +
+
+
+
+
+
+
+
+ +
+
+ +
None
+ +
+ + + +
+
+
+
+
+
+ + + + +
+
+
+
+ +
+
+
+ Generated by PeakRDL-html v2.11.0 +
+
+ +
+
+ +
+
+

Keyboard Shortcuts

+
+
/
Open Search
+
Ctrl+/
Open Search relative to current page
+
Ctrl+[ and Ctrl+]
Cycle through path index editors
+
Ctrl+\
Navigate to parent page
+
+
+
+ + +
+
+ +
+ +
+ \ No newline at end of file diff --git a/rdl/outputs/docs/html/js/address_search.js b/rdl/outputs/docs/html/js/address_search.js new file mode 100644 index 0000000..eeb4d11 --- /dev/null +++ b/rdl/outputs/docs/html/js/address_search.js @@ -0,0 +1,33 @@ +// This file is part of PeakRDL-html . +// and can be redistributed under the terms of GNU GPL v3 . + +class AddressSearch { + static start(query){ + query = query.slice(1, query.length); + if(query == "") return; + + var addr; + try { + addr = BigInt(query); + } catch(error) { + addr = -1n; + } + + if(addr < 0) return; + + RootNodeIds.forEach(function(id) { + var result = RAL.lookup_by_address(addr, id); + if(result != null) { + var result_id = result[0]; + var idx_stack = result[1]; + var text_segments = [RAL.get_path(result_id, idx_stack)]; + + add_search_result( + text_segments, + result_id, + idx_stack + ); + } + }); + } +} diff --git a/rdl/outputs/docs/html/js/content_search.js b/rdl/outputs/docs/html/js/content_search.js new file mode 100644 index 0000000..2555c74 --- /dev/null +++ b/rdl/outputs/docs/html/js/content_search.js @@ -0,0 +1,370 @@ +// This file is part of PeakRDL-html . +// and can be redistributed under the terms of GNU GPL v3 . + +class ContentSearch { + static #MAX_RESULTS = 25; + static #ITER_BREAK_INTERVAL = 1000; + static #PREVIEW_MAX_RUN_LENGTH = 200; + static #bucket_files = new Array(SearchBucketIndex.length).fill(null); + + static async start(query, abortSignal){ + var keywords = this.#get_query_words(query); + + // determine which bucket files need to be fetched, if any + // Discard any keywords definitely not in the index + var bidxs_to_fetch = new Set(); + var filtered_keywords = []; + for(var i=0; i= 2){ + for(var j=0; j { + this.#bucket_files[bidx] = data; + }); + return awaitable; + } + + + static async #get_matches(keywords, abortSignal){ + + // Find locations of matching keywords + var match_list = []; + var match_hashtable = {}; + var itercount = 0; + for(var i=0; i { + return a.compare_rank_to(b); + }); + + return match_list; + } + + + static async #fetch_match_preview_text(match){ + return fetch_page_content(match.page_id).then(text => { + var dp = new DOMParser(); + var doc = dp.parseFromString(text, "text/html"); + + // Prune out the element that is most relevant to the content match + var el; + var el_id; + if(match.is_field) { + if(match.is_name) { + // use field's row in table, since it contains the name + el_id = match.field_name; + } else { + // field's description block + el_id = "_Content." + match.field_name + ".desc"; + } + } else { + // Not a field + if(match.is_name) { + // Use page title + el_id = "_Content.name"; + } else { + // main description block + el_id = "_Content.desc"; + } + } + var el = doc.getElementById(el_id); + + // strip HTML tags + text = el.textContent; + + // Reduce excess whitespace + text = text.replace(/\s+/g, " "); + + // Mark all keywords in content + var keywords = Array.from(new Set([...match.full_match_keywords, ...match.partial_match_keywords])); + var regex = new RegExp("(?:\\b|_)(" + keywords.join("|") + ")", "ig"); + var marked_text = ""; + var prev_idx = 0; + for (const m of text.matchAll(regex)) { + var m_idx = m.index; + + // advance match past underscore if it is in match + if(text[m_idx] == "_") m_idx += 1; + + // Pass through prior segment + if(prev_idx < m_idx) { + var unmarked_segment = text.slice(prev_idx, m_idx); + if(unmarked_segment.length > this.#PREVIEW_MAX_RUN_LENGTH) { + // shorten the segment + if(marked_text == ""){ + // is first + unmarked_segment = this.#shorten_text_first(unmarked_segment); + } else { + // is middle + unmarked_segment = this.#shorten_text_middle(unmarked_segment); + } + } + marked_text += unmarked_segment; + } + + // highlight segment + marked_text += "" + m[1] + ""; + prev_idx = m_idx + m[1].length; + } + + if(prev_idx < text.length){ + // pass through last unmarked segment + var unmarked_segment = text.slice(prev_idx, text.index); + if(unmarked_segment.length > this.#PREVIEW_MAX_RUN_LENGTH) { + // shorten the segment + unmarked_segment = this.#shorten_text_last(unmarked_segment); + } + marked_text += unmarked_segment; + } + + return marked_text; + }); + } + + static #shorten_text_first(text){ + var L = this.#PREVIEW_MAX_RUN_LENGTH; + return "\u22ef" + text.slice(text.length - L, text.length); + } + + static #shorten_text_middle(text){ + var L = this.#PREVIEW_MAX_RUN_LENGTH; + return text.slice(0, L/2) + "\u22ef \u22ef" + text.slice(text.length - L/2, text.length); + } + + static #shorten_text_last(text){ + var L = this.#PREVIEW_MAX_RUN_LENGTH; + return text.slice(0, L) + "\u22ef"; + } +} + + +class ContentSearchMatch { + constructor(location_entry){ + this.full_match_keywords = new Set(); + this.partial_match_keywords = new Set(); + this.page_id = location_entry[0]; + + var location_code = location_entry[1]; + this.is_name = Boolean(location_code & 0x1); + this.is_enum = Boolean(location_code & 0x4); + this.is_field = Boolean(location_code & 0x2); + if(this.is_field){ + var field_idx = (location_code >> 3); + this.field_name = RAL.get_node(this.page_id).fields[field_idx].name; + } else { + this.field_name = null; + } + } + + get_location_key(){ + // unique key that represents mergeable match location + return String([this.page_id, this.field_name]); + } + + get_matched_keywords(){ + return new Set([...this.full_match_keywords, ...this.partial_match_keywords]); + } + + compare_rank_to(other){ + // +1: other has higher rank than this + // -1: other has lower rank than this + // 0: Other is the same rank + var this_merged_keywords = this.get_matched_keywords(); + var other_merged_keywords = other.get_matched_keywords(); + + // Total number of matching keywords is most important + if(this_merged_keywords.size < other_merged_keywords.size) return 1; + if(this_merged_keywords.size > other_merged_keywords.size) return -1; + + // then whichever has more full matches + if(this.full_match_keywords.size < other.full_match_keywords.size) return 1; + if(this.full_match_keywords.size > other.full_match_keywords.size) return -1; + + // then whichever has more partial matches + if(this.partial_match_keywords.size < other.partial_match_keywords.size) return 1; + if(this.partial_match_keywords.size > other.partial_match_keywords.size) return -1; + + return 0; + } +} diff --git a/rdl/outputs/docs/html/js/field_testers.js b/rdl/outputs/docs/html/js/field_testers.js new file mode 100644 index 0000000..4418cd9 --- /dev/null +++ b/rdl/outputs/docs/html/js/field_testers.js @@ -0,0 +1,213 @@ +// This file is part of PeakRDL-html . +// and can be redistributed under the terms of GNU GPL v3 . + +// registry of register values by address string in hex +var RegValueRegistery = {}; + +function init_reg_value(){ + var state = get_reg_state(); + if(state != null) { + var reg_el = document.getElementById("_RegValueTester"); + reg_el.value = "0x" + state.value.toString(16); + reg_el.classList.remove("invalid"); + update_field_value_testers(); + } else { + reset_field_inputs(); + } + + for(var i=0; i> lsb; + var mask = (1n << (msb - lsb + 1n)) - 1n; + value = value & mask; + var el = document.getElementById("_FieldValueTester" + node.fields[idx].name); + el.value = format_field_value(idx, value); + el.classList.remove("invalid"); + + if("encode" in RAL.get_node(CurrentID).fields[idx]) { + var el = document.getElementById("_FieldValueEnumTester" + node.fields[idx].name); + el.value = "0x" + value.toString(16); + } +} + +function format_field_value(idx, value) { + if(RAL.get_node(CurrentID).fields[idx].disp == "D"){ + return(value.toString()); + } else { + return("0x" + value.toString(16)); + } +} + +function update_field_enum_visibility(idx){ + var node = RAL.get_node(CurrentID); + + if(!("encode" in node.fields[idx])) return; + + var d = node.fields[idx].disp; + var enum_el = document.getElementById("_FieldValueEnumTester" + node.fields[idx].name); + var txt_el = document.getElementById("_FieldValueTester" + node.fields[idx].name); + if(d == "E") { + enum_el.style.display = "inline"; + txt_el.style.display = "none"; + } else { + enum_el.style.display = "none"; + txt_el.style.display = "inline"; + } +} + +//============================================================================== +// Events +//============================================================================== + +function onRadixSwitch(el){ + var idx = RAL.lookup_field_idx(el.dataset.name); + var node = RAL.get_node(CurrentID); + var d = node.fields[idx].disp; + if(d == "H") { + d = "D"; + } else if((d == "D") && ("encode" in node.fields[idx])) { + d = "E"; + } else { + d = "H"; + } + + el.innerHTML = d; + node.fields[idx].disp = d; + update_field_enum_visibility(idx); + update_field_value_tester(idx); +} + +function onDecodedFieldEnumChange(el) { + var idx = RAL.lookup_field_idx(el.dataset.name); + var el2 = document.getElementById("_FieldValueTester" + RAL.get_node(CurrentID).fields[idx].name); + el2.value = el.value; + update_reg_value_tester(); + save_reg_state(); +} + +function onDecodedFieldInput(el){ + var idx = RAL.lookup_field_idx(el.dataset.name); + var node = RAL.get_node(CurrentID); + var msb = BigInt(node.fields[idx].msb); + var lsb = BigInt(node.fields[idx].lsb); + var value; + + try { + value = BigInt(el.value); + } catch(error) { + value = -1n; + } + + var max_value = 1n << (msb - lsb + 1n); + if((value < 0) || (value >= max_value)){ + if(!el.classList.contains("invalid")) el.classList.add("invalid"); + return; + } + el.classList.remove("invalid"); + + if("encode" in node.fields[idx]) { + var el2 = document.getElementById("_FieldValueEnumTester" + node.fields[idx].name); + el2.value = "0x" + value.toString(16); + } + update_reg_value_tester(); + save_reg_state(); +} + +function onEncodedRegInput(el){ + var value; + try { + value = BigInt(el.value); + } catch(error) { + value = -1n; + } + + if(value < 0){ + if(!el.classList.contains("invalid")) el.classList.add("invalid"); + return; + } + el.classList.remove("invalid"); + update_field_value_testers(); + save_reg_state(); +} + +function onResetRegValue(el){ + reset_field_inputs(); + save_reg_state(); +} diff --git a/rdl/outputs/docs/html/js/index_edit.js b/rdl/outputs/docs/html/js/index_edit.js new file mode 100644 index 0000000..e99f809 --- /dev/null +++ b/rdl/outputs/docs/html/js/index_edit.js @@ -0,0 +1,162 @@ +// This file is part of PeakRDL-html . +// and can be redistributed under the terms of GNU GPL v3 . + +var IndexEditState = {}; +IndexEditState.active = false; +IndexEditState.id = 0; +IndexEditState.dim = 0; +IndexEditState.span_idx = 0; + +function init_index_edit(){ + + // Register index edit modal events: + // ... close if clicking off of it + window.onclick = function(ev) { + var modal_el = document.getElementById('_IdxEditModal'); + if(!(isDescendant(modal_el, ev.target) || modal_el==ev.target)){ + exitIndexEditModal(); + } + }; + // ... close if press enter in input. Cancel if esc + document.getElementById('_IdxEditInput').onkeypress = onIndexEditKeypress; +} + +function onIndexEditKeypress(ev){ + if(!ev) ev = window.event; + var keyCode = ev.keyCode || ev.which; + + if(keyCode == 13){ // Enter key + exitIndexEditModal(); + return false; + } else if(keyCode == 27){ // ESC + // Exit and cancel modal + exitIndexEditModal(true); + return false; + } +} + +function exitIndexEditModal(cancel) { + if(typeof cancel === "undefined") cancel = false; + + var modal_el = document.getElementById('_IdxEditModal'); + var input_el = document.getElementById('_IdxEditInput'); + + if(IndexEditState.active){ + modal_el.style.display = "none"; + IndexEditState.active = false; + + if(!cancel){ + // Commit modal input value + var val = Number(input_el.value); + if(!isPositiveInteger(val)) return; + if((val < 0) || (val >= RAL.get_node(IndexEditState.id).dims[IndexEditState.dim])) return; + RAL.get_node(IndexEditState.id).idxs[IndexEditState.dim] = val; + + update_crumbtrail(); + update_rdlfc_indexes(); + patch_url_path(); + update_absolute_addr(); + if(RAL.is_register(CurrentID)){ + init_reg_value(); + } + userHooks.onAddressUpdate(); + } + } +} + +function showIndexEditModal(idx){ + var span_el = document.getElementById('_CrumbIdxSpan' + idx); + var modal_el = document.getElementById('_IdxEditModal'); + var input_el = document.getElementById('_IdxEditInput'); + var range_el = document.getElementById('_IdxEditRange'); + + if(span_el == null) return; + + // Show Modal + modal_el.style.display = "block"; + var rect = span_el.getBoundingClientRect(); + modal_el.style.left = (rect.left + rect.right)/2 - modal_el.offsetWidth/2 + "px"; + modal_el.style.top = rect.bottom + 10 + "px"; + + // Initialize modal + IndexEditState.active = true; + IndexEditState.id = parseInt(span_el.dataset.id); + IndexEditState.dim = parseInt(span_el.dataset.dim); + IndexEditState.span_idx = idx; + input_el.value = RAL.get_node(IndexEditState.id).idxs[IndexEditState.dim]; + range_el.innerHTML = "0-" + (RAL.get_node(IndexEditState.id).dims[IndexEditState.dim]-1); + + input_el.focus(); + input_el.select(); +} + +function onClickCrumbtrailIdx(ev) { + ev.stopPropagation(); + + // Get index of span that was clicked + // Need to save it in case crumbtrail get re-constructed + var span_idx = ev.target.dataset.span_idx; + + if(IndexEditState.active){ + // Exit previous modal box + exitIndexEditModal(); + } + showIndexEditModal(span_idx); + + return(false); +} + +function onKeyDownIdxEdit(ev) { + // return True if event was not handled here + if(ev.ctrlKey && ev.key == "["){ + switch_to_prev_idx_edit(); + return false; + } + + if(ev.ctrlKey && ev.key == "]"){ + switch_to_next_idx_edit(); + return false; + } + + if(IndexEditState.active) { + if(ev.key == "Escape"){ + exitIndexEditModal(true); + return false; + } + } + + return true; +} + + +function switch_to_prev_idx_edit() { + var span_idx; + if(IndexEditState.active){ + // Close current modal and flip to next index to the left + if(IndexEditState.span_idx == 0) return; + span_idx = IndexEditState.span_idx - 1; + exitIndexEditModal(); + } else { + // Open first index + span_idx = 0; + } + showIndexEditModal(span_idx); +} + +function switch_to_next_idx_edit() { + var span_idx; + + // Determine max idx allowed + var n_idx_spans = document.getElementsByClassName("crumb-idx").length; + + if(IndexEditState.active){ + // Close current modal and flip to next index to the right + if(IndexEditState.span_idx == n_idx_spans-1) return; + span_idx = IndexEditState.span_idx + 1; + exitIndexEditModal(); + } else { + // Open last index + span_idx = n_idx_spans-1; + } + showIndexEditModal(span_idx); +} diff --git a/rdl/outputs/docs/html/js/main.js b/rdl/outputs/docs/html/js/main.js new file mode 100644 index 0000000..48e4534 --- /dev/null +++ b/rdl/outputs/docs/html/js/main.js @@ -0,0 +1,451 @@ +// This file is part of PeakRDL-html . +// and can be redistributed under the terms of GNU GPL v3 . + +var CurrentID; + +//============================================================================== +// User-overridable hooks +//============================================================================== +var userHooks = { + // Triggered when page is loaded the first time + onPageLoad: function() { + }, + + // Triggered when main pane is loaded with new content and page finished + // updating + onContentLoad: function() { + }, + + // Triggered when page's absolute address was updated due to an index-edit + // value change + onAddressUpdate: function() { + }, + + // Triggered when any of the register's encoded or decoded value form fields + // were changed + onRegValueEditorChange: function() { + }, + + // When saving register state, provide additional data to the state object + save_extra_reg_state: function(state) { + return state; + }, + + // Global keystroke event + onKeyDown: function(ev) { + // return True if event was not handled here + return true; + } +}; + +//============================================================================== +// Page actions +//============================================================================== + +function onPageLoad() { + if(test_browser_incompatible()) { + show_incompatibility_nag(); + return; + } + + window.onpopstate = onPopState; + window.onkeydown = onKeyDownMain; + + RAL.load_ral_data().then(() => { + // Determine what page id will be loaded + var url = new URL(window.location.href); + var path = url.searchParams.get("p", path); + var parsed_path = RAL.parse_path(path); + var id; + if(parsed_path == null) { + id = 0; + } else { + id = parsed_path[0]; + } + + // Load content + Sidebar.init(id); + load_page_via_url(); + init_index_edit(); + userHooks.onPageLoad(); + }) + .catch(e => { + // Page load failed + if(window.location.protocol == "file:"){ + show_file_protocol_nag(); + } + }); +} + +function onKeyDownMain(ev) { + if(!ev) ev = window.event; + var unhandled; + + if(ev.ctrlKey && ev.key == "\\"){ + // Navigate to parent node + load_parent_page(); + return false; + } + + unhandled = onKeyDownSearch(ev); + if(!unhandled) return false; + + unhandled = onKeyDownIdxEdit(ev); + if(!unhandled) return false; + + unhandled = userHooks.onKeyDown(ev); + if(!unhandled) return false; +} + +function platform_is_windows() { + try { + if(navigator.userAgentData.platform == "Windows") { + return true; + } + } catch(error) { + // fall-back to legacy api + if((navigator.platform == "Win32") || (navigator.platform == "Win64")) { + return true; + } + } + return false +} + +function show_file_protocol_nag() { + var this_dir = window.location.pathname.replace(/[\\/]index.html/g, "") + if(platform_is_windows()) { + // remove leading slash that shows up ahead of path: "/C:/Users/..." + this_dir = this_dir.replace(/^\/(\w:)/g, "$1"); + } + var html_str; + + html_str = + "

Oops!

" + + "

Most modern browser's security policies " + + "prevent this page from loading properly when using the file:// protocol.

" + + "

If possible, host this page on a web server and access using the http:// protocol.

" + + + "

Alternatives

" + ; + + if(platform_is_windows()) { + html_str += + "

Use one of the included launcher scripts

" + + "

" + + "In the folder that contains these docs, double-click the launcher for the browser of your choice:" + + "

    " + + "
  • launcher-windows-chrome.bat
  • " + + "
  • launcher-windows-edge.bat
  • " + + "
  • launcher-windows-firefox.bat
  • " + + "
" + + "These launcher scripts will temporarily disable the security setting so you can view this page locally." + + "

" + ; + } + + if(platform_is_windows()) { + html_str += + "

Python http server

" + + "

" + + "Launch a temporary http server using Python:" + + "

    " + + "
  1. If you haven't already, download and install Python
  2. " + + "
  3. " + + " Press WIN+R and paste the following into the text box:" + + "

    " + + "
  4. " + + "
  5. Click 'Ok'
  6. " + + "
  7. Re-open this page via: http://localhost:8000/
  8. " + + "
" + + "

" + ; + } else { + html_str += + "

Python http server

" + + "

" + + "Launch a temporary http server using Python:" + + "

"
+            + 'python3 -m http.server -d "' + this_dir + '"'
+            + "
" + + "Then view via: http://localhost:8000/" + + "

" + ; + } + + html_str += + "

Firefox

" + + "

" + + "Change your Firefox security settings:" + + "

    " + + "
  1. In your address bar, type about:config
  2. " + + "
  3. Set security.fileuri.strict_origin_policy to false
  4. " + + "
  5. Refresh this page
  6. " + + "
" + + "

" + ; + + if(platform_is_windows()) { + html_str += + "

Chrome or Edge

" + + "

" + + "

    " + + "
  1. Close your current Chrome or Edge browser session completely
  2. " + + "
  3. " + + " Press WIN+R and paste the following into the text box:" + + "

    " + + " For Microsoft Edge, replace 'chrome.exe' with 'msedge.exe'" + + "
  4. " + + "
  5. Click 'Ok'
  6. " + + "
" + + "

" + ; + } else { + html_str += + "

Chrome

" + + "

" + + "Close your current Chrome session and re-launch it from the command-line using:" + + "

"
+            + "google-chrome --allow-file-access-from-files \\\n"
+            + '    "' + window.location.href + '"'
+            + "
" + + "

" + ; + } + + var el = document.getElementById("_ContentContainer"); + el.innerHTML = html_str; +} + +function show_incompatibility_nag() { + var el = document.getElementById("_ContentContainer"); + el.innerHTML + = "

Nope!

" + + "

It looks like the browser you are using is not supported.

" + + "

Please use a modern browser such as " + + "Firefox" + + " or Chrome.

" + ; +} + +function test_browser_incompatible() { + // Test for browser features that absolutely have to exist + try { + var url = new URL(window.location.href); + } catch(error) { + return true; + } + return false; +} + +function update_crumbtrail(){ + var crumb_el = document.getElementById("_Crumbtrail"); + var id = CurrentID; + + // Delete old crumbtrail + while (crumb_el.hasChildNodes()) { + crumb_el.removeChild(crumb_el.lastChild); + } + + var path_ids = RAL.get_ids_in_path(id); + var crumb_idx_span_idx = 0; + + for(var i=0; i setTimeout(r, 1)); +} + +function difference(setA, setB) { + const _difference = new Set(setA); + for (const elem of setB) { + _difference.delete(elem); + } + return _difference; +} + +function toBigInt(str) { + // bigInt doesn't handle large hex strings if they use the 0x prefix + // Wrap auto-base handling + str = str.trim().toLowerCase(); + if(str.startsWith("0x")) { + return(bigInt(str.substring(2), 16)); + } else if(str.startsWith("0o")) { + return(bigInt(str.substring(2), 8)); + } else if(str.startsWith("0b")) { + return(bigInt(str.substring(2), 2)); + } else { + return(bigInt(str)); + } +} + +function page_specific_key(key){ + var url = new URL(window.location.href); + key = url.origin + url.pathname + "::" + key; + return key; +} + +//============================================================================== +// Compatibility Workarounds +//============================================================================== +// IE does not support Number.isInteger +function isPositiveInteger(num) { + return ((num ^ 0) >>> 0) === num; +} + +// IE does not support .startsWith +if(!String.prototype.startsWith) { + String.prototype.startsWith = function(searchString, position) { + position = position || 0; + return this.indexOf(searchString, position) === position; + }; +} diff --git a/rdl/outputs/docs/html/js/nav.js b/rdl/outputs/docs/html/js/nav.js new file mode 100644 index 0000000..e6e37e9 --- /dev/null +++ b/rdl/outputs/docs/html/js/nav.js @@ -0,0 +1,209 @@ +// This file is part of PeakRDL-html . +// and can be redistributed under the terms of GNU GPL v3 . + +async function load_page(id) { + var awaitable = fetch_page_content(id); + awaitable.then(text => { + // Page loaded successfully + CurrentID = id; + update_crumbtrail(); + + var main_el = document.getElementById("_ContentContainer"); + main_el.innerHTML = text; + update_absolute_addr(); + update_rdlfc_indexes(); + if(RAL.is_register(id)) { + init_reg_value(); + init_radix_buttons(); + } + MathJax.Hub.Queue(["Typeset", MathJax.Hub]); + userHooks.onContentLoad(); + }); + + return awaitable; +} + +async function fetch_page_content(id){ + var path = "content/" + RAL.get_node_uid(id) + ".html?ts=" + BUILD_TS; + var awaitable = fetch(path) + .then(response => { + if(!response.ok){ + throw new Error("page fetch failed"); + } + return response.text(); + }); + return awaitable; +} + +async function load_page_via_url(){ + // An event triggered such that the page should be loaded based on the URL + var prev_id = CurrentID; + + var url = new URL(window.location.href); + var path = url.searchParams.get("p", path); + var parsed_path = RAL.parse_path(path); + var new_path; + if(parsed_path == null) { + // Bad path. Discard it + new_path = ""; + CurrentID = 0; + } else { + // Path is good. + var id, idx_stack; + id = parsed_path[0]; + idx_stack = parsed_path[1]; + RAL.apply_idx_stack(id, idx_stack); + + // Recompute the path in case it needs to be cleaned up + new_path = RAL.get_path(id); + CurrentID = id; + } + + if(path != new_path){ + // Path was sanitized. Patch URL + url.searchParams.set("p", new_path); + window.history.replaceState({}, "", url.toString()) + } + + if(prev_id != CurrentID) { + await load_page(CurrentID).then(() => { + Sidebar.expand_to_id(CurrentID); + Sidebar.select_node(CurrentID); + Sidebar.scroll_into_view(CurrentID); + refresh_title(); + refresh_target_scroll(); + }); + } else { + refresh_target_scroll(); + } +} + +function load_page_via_path(path, url_hash){ + if(typeof url_hash === "undefined") url_hash = ""; + var prev_path = RAL.get_path(CurrentID); + var prev_url_hash = window.location.hash; + var parsed_path = RAL.parse_path(path); + var new_path; + if(parsed_path == null) { + // Bad path. Give up + return + } else { + // Path is good. + var id, idx_stack; + id = parsed_path[0]; + idx_stack = parsed_path[1]; + RAL.apply_idx_stack(id, idx_stack); + + // Recompute the path in case it needs to be cleaned up + new_path = RAL.get_path(id); + RAL.reset_indexes_to_next(id); + CurrentID = id; + } + + if(prev_path != new_path) { + load_page(CurrentID).then(() => { + Sidebar.expand_to_id(CurrentID); + Sidebar.select_node(CurrentID); + Sidebar.scroll_into_view(CurrentID); + refresh_url(url_hash); + refresh_title(); + refresh_target_scroll(); + }); + } else if (prev_url_hash != url_hash){ + refresh_url(url_hash); + refresh_target_scroll(); + } +} + + +function onClickNodeLink(ev) { + var el = ev.target; + var id = parseInt(el.dataset.id); + if(id == CurrentID) return(false); + + RAL.reset_indexes_to_next(id); + load_page(id).then(() => { + Sidebar.expand_to_id(id); + Sidebar.select_node(id); + Sidebar.scroll_into_view(id); + refresh_url(); + refresh_title(); + refresh_target_scroll(); + }); + + return(false); +} + +function onClickPathLink(ev) { + var el = ev.target; + var path = el.dataset.path; + var url_hash = el.dataset.url_hash; + + load_page_via_path(path, url_hash); + + return(false); +} + +function load_parent_page(){ + var id = RAL.get_node(CurrentID).parent; + if(id == null) return; + load_page(id).then(() => { + Sidebar.expand_to_id(id); + Sidebar.select_node(id); + Sidebar.scroll_into_view(id); + refresh_url(); + refresh_title(); + refresh_target_scroll(); + }); +} + +function refresh_url(url_hash) { + // Given current state, refresh the URL + if(typeof url_hash === "undefined") url_hash = ""; + var path = RAL.get_path(CurrentID); + + var url = new URL(window.location.href); + url.searchParams.set("p", path); + url.hash = url_hash; + window.history.pushState({}, "", url.toString()) +} + +function patch_url_path() { + // refresh only the URL's hier path without affecting history + var path = RAL.get_path(CurrentID); + var url = new URL(window.location.href); + url.searchParams.set("p", path); + window.history.replaceState({}, "", url.toString()) +} + +function refresh_title() { + // Given current state, refresh the page title text + document.title = RAL.get_node(CurrentID).name + " \u2014 " + PageInfo.title; +} + +function onPopState(event) { + load_page_via_url(); +} + +function refresh_target_scroll() { + // Manually implement scroll to hash targets since AJAX-based page loads + // make the normal mechanism a little unreliable + + // Clear any target-highlight elements + var target_els = document.getElementsByClassName("target-highlight"); + for(var i=target_els.length-1; i>=0; i--){ + target_els[i].classList.remove("target-highlight"); + } + + if(window.location.hash){ + // URL has hash! Scroll to it and apply highlight class + var el = document.getElementById(window.location.hash.slice(1)); + if(el){ + el.scrollIntoView(); + el.classList.add("target-highlight"); + } + + } else { + document.getElementById("_Content").parentElement.scrollTop = 0; + } +} diff --git a/rdl/outputs/docs/html/js/path_search.js b/rdl/outputs/docs/html/js/path_search.js new file mode 100644 index 0000000..6312721 --- /dev/null +++ b/rdl/outputs/docs/html/js/path_search.js @@ -0,0 +1,84 @@ +// This file is part of PeakRDL-html . +// and can be redistributed under the terms of GNU GPL v3 . + +class PathSearch { + static #MAX_RESULTS = 100; + static #SEARCH_CHOMP_SIZE = 100; + + static async start(query, abortSignal){ + if(query.length < 2) return; + + // Sanitize query + var sp_query = query.split(" "); + var keywords = []; + for(var i=0; i= this.#MAX_RESULTS) { + break; + } + } + } + + static #test_path(path, keywords){ + // If match, returns text_segments. + // Otherwise, null + var path_lc = path.toLowerCase(); + var text_segments = []; + var start = 0; + + // Scan path to see if all keywords match + for(var i=0; i0&&void 0!==arguments[0]?arguments[0]:{},b=new v,c=b.tween(a);return c.tweenable=b,c}c.d(b,"e",function(){return q}),c.d(b,"c",function(){return s}),c.d(b,"b",function(){return t}),c.d(b,"a",function(){return v}),c.d(b,"d",function(){return i});var j=c(1),k="undefined"!=typeof window?window:a,l=k.requestAnimationFrame||k.webkitRequestAnimationFrame||k.oRequestAnimationFrame||k.msRequestAnimationFrame||k.mozCancelRequestAnimationFrame&&k.mozRequestAnimationFrame||setTimeout,m=function(){},n=null,o=null,p=g({},j),q=function(a,b,c,d,e,f,g){var h=al?l:b,n=h-(l-m);m>=l?(i(j,c,n),a.stop(!0)):(a._applyFilter("beforeTween"),m1&&void 0!==arguments[1]?arguments[1]:"linear",c={},d=e(b);if("string"===d||"function"===d)for(var f in a)c[f]=b;else for(var g in a)c[g]=b[g]||"linear";return c},u=function(a){if(a===n)(n=a._next)?n._previous=null:o=null;else if(a===o)(o=a._previous)?o._next=null:n=null;else{var b=a._previous,c=a._next;b._next=c,c._previous=b}a._previous=a._next=null},v=function(){function a(){var b=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},c=arguments.length>1&&void 0!==arguments[1]?arguments[1]:void 0;!function(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}(this,a),this._currentState=b,this._configured=!1,this._filters=[],this._timestamp=null,this._next=null,this._previous=null,c&&this.setConfig(c)}var b,c,e;return b=a,(c=[{key:"_applyFilter",value:function(a){var b=!0,c=!1,d=void 0;try{for(var e,f=this._filters[Symbol.iterator]();!(b=(e=f.next()).done);b=!0){var g=e.value[a];g&&g(this)}}catch(a){c=!0,d=a}finally{try{b||null==f.return||f.return()}finally{if(c)throw d}}}},{key:"tween",value:function(){var b=arguments.length>0&&void 0!==arguments[0]?arguments[0]:void 0,c=this._attachment,d=this._configured;return!b&&d||this.setConfig(b),this._pausedAtTime=null,this._timestamp=a.now(),this._start(this.get(),c),this.resume()}},{key:"setConfig",value:function(){var b=this,c=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},d=c.attachment,e=c.delay,f=void 0===e?0:e,h=c.duration,i=void 0===h?500:h,j=c.easing,k=c.from,l=c.promise,n=void 0===l?Promise:l,o=c.start,p=void 0===o?m:o,q=c.step,r=void 0===q?m:q,s=c.to;this._configured=!0,this._attachment=d,this._isPlaying=!1,this._pausedAtTime=null,this._scheduleId=null,this._delay=f,this._start=p,this._step=r,this._duration=i,this._currentState=g({},k||this.get()),this._originalState=this.get(),this._targetState=g({},s||this.get());var u=this._currentState;this._targetState=g({},u,{},this._targetState),this._easing=t(u,j);var v=a.filters;for(var w in this._filters.length=0,v)v[w].doesApply(this)&&this._filters.push(v[w]);return this._applyFilter("tweenCreated"),this._promise=new n(function(a,c){b._resolve=a,b._reject=c}),this._promise.catch(m),this}},{key:"get",value:function(){return g({},this._currentState)}},{key:"set",value:function(a){this._currentState=a}},{key:"pause",value:function(){if(this._isPlaying)return this._pausedAtTime=a.now(),this._isPlaying=!1,u(this),this}},{key:"resume",value:function(){if(null===this._timestamp)return this.tween();if(this._isPlaying)return this._promise;var b=a.now();return this._pausedAtTime&&(this._timestamp+=b-this._pausedAtTime,this._pausedAtTime=null),this._isPlaying=!0,null===n?(n=this,o=this,function a(){n&&(l.call(k,a,1e3/60),s())}()):(this._previous=o,o._next=this,o=this),this._promise}},{key:"seek",value:function(b){b=Math.max(b,0);var c=a.now();return this._timestamp+b===0?this:(this._timestamp=c-b,this._isPlaying||r(this,c),this)}},{key:"stop",value:function(){var a=arguments.length>0&&void 0!==arguments[0]&&arguments[0],b=this._attachment,c=this._currentState,d=this._easing,e=this._originalState,f=this._targetState;if(this._isPlaying)return this._isPlaying=!1,u(this),a?(this._applyFilter("beforeTween"),q(1,c,e,f,1,0,d),this._applyFilter("afterTween"),this._applyFilter("afterTweenEnd"),this._resolve(c,b)):this._reject(c,b),this}},{key:"isPlaying",value:function(){return this._isPlaying}},{key:"setScheduleFunction",value:function(b){a.setScheduleFunction(b)}},{key:"dispose",value:function(){for(var a in this)delete this[a]}}])&&d(b.prototype,c),e&&d(b,e),a}();v.setScheduleFunction=function(a){return l=a},v.formulas=p,v.filters={},v.now=Date.now||function(){return+new Date}}).call(this,c(2))},function(a,b,c){"use strict";c.r(b),c.d(b,"linear",function(){return d}),c.d(b,"easeInQuad",function(){return e}),c.d(b,"easeOutQuad",function(){return f}),c.d(b,"easeInOutQuad",function(){return g}),c.d(b,"easeInCubic",function(){return h}),c.d(b,"easeOutCubic",function(){return i}),c.d(b,"easeInOutCubic",function(){return j}),c.d(b,"easeInQuart",function(){return k}),c.d(b,"easeOutQuart",function(){return l}),c.d(b,"easeInOutQuart",function(){return m}),c.d(b,"easeInQuint",function(){return n}),c.d(b,"easeOutQuint",function(){return o}),c.d(b,"easeInOutQuint",function(){return p}),c.d(b,"easeInSine",function(){return q}),c.d(b,"easeOutSine",function(){return r}),c.d(b,"easeInOutSine",function(){return s}),c.d(b,"easeInExpo",function(){return t}),c.d(b,"easeOutExpo",function(){return u}),c.d(b,"easeInOutExpo",function(){return v}),c.d(b,"easeInCirc",function(){return w}),c.d(b,"easeOutCirc",function(){return x}),c.d(b,"easeInOutCirc",function(){return y}),c.d(b,"easeOutBounce",function(){return z}),c.d(b,"easeInBack",function(){return A}),c.d(b,"easeOutBack",function(){return B}),c.d(b,"easeInOutBack",function(){return C}),c.d(b,"elastic",function(){return D}),c.d(b,"swingFromTo",function(){return E}),c.d(b,"swingFrom",function(){return F}),c.d(b,"swingTo",function(){return G}),c.d(b,"bounce",function(){return H}),c.d(b,"bouncePast",function(){return I}),c.d(b,"easeFromTo",function(){return J}),c.d(b,"easeFrom",function(){return K}),c.d(b,"easeTo",function(){return L});var d=function(a){return a},e=function(a){return Math.pow(a,2)},f=function(a){return-(Math.pow(a-1,2)-1)},g=function(a){return(a/=.5)<1?.5*Math.pow(a,2):-.5*((a-=2)*a-2)},h=function(a){return Math.pow(a,3)},i=function(a){return Math.pow(a-1,3)+1},j=function(a){return(a/=.5)<1?.5*Math.pow(a,3):.5*(Math.pow(a-2,3)+2)},k=function(a){return Math.pow(a,4)},l=function(a){return-(Math.pow(a-1,4)-1)},m=function(a){return(a/=.5)<1?.5*Math.pow(a,4):-.5*((a-=2)*Math.pow(a,3)-2)},n=function(a){return Math.pow(a,5)},o=function(a){return Math.pow(a-1,5)+1},p=function(a){return(a/=.5)<1?.5*Math.pow(a,5):.5*(Math.pow(a-2,5)+2)},q=function(a){return 1-Math.cos(a*(Math.PI/2))},r=function(a){return Math.sin(a*(Math.PI/2))},s=function(a){return-.5*(Math.cos(Math.PI*a)-1)},t=function(a){return 0===a?0:Math.pow(2,10*(a-1))},u=function(a){return 1===a?1:1-Math.pow(2,-10*a)},v=function(a){return 0===a?0:1===a?1:(a/=.5)<1?.5*Math.pow(2,10*(a-1)):.5*(2-Math.pow(2,-10*--a))},w=function(a){return-(Math.sqrt(1-a*a)-1)},x=function(a){return Math.sqrt(1-Math.pow(a-1,2))},y=function(a){return(a/=.5)<1?-.5*(Math.sqrt(1-a*a)-1):.5*(Math.sqrt(1-(a-=2)*a)+1)},z=function(a){return a<1/2.75?7.5625*a*a:a<2/2.75?7.5625*(a-=1.5/2.75)*a+.75:a<2.5/2.75?7.5625*(a-=2.25/2.75)*a+.9375:7.5625*(a-=2.625/2.75)*a+.984375},A=function(a){var b=1.70158;return a*a*((b+1)*a-b)},B=function(a){var b=1.70158;return(a-=1)*a*((b+1)*a+b)+1},C=function(a){var b=1.70158;return(a/=.5)<1?a*a*((1+(b*=1.525))*a-b)*.5:.5*((a-=2)*a*((1+(b*=1.525))*a+b)+2)},D=function(a){return-1*Math.pow(4,-8*a)*Math.sin((6*a-1)*(2*Math.PI)/2)+1},E=function(a){var b=1.70158;return(a/=.5)<1?a*a*((1+(b*=1.525))*a-b)*.5:.5*((a-=2)*a*((1+(b*=1.525))*a+b)+2)},F=function(a){var b=1.70158;return a*a*((b+1)*a-b)},G=function(a){var b=1.70158;return(a-=1)*a*((b+1)*a+b)+1},H=function(a){return a<1/2.75?7.5625*a*a:a<2/2.75?7.5625*(a-=1.5/2.75)*a+.75:a<2.5/2.75?7.5625*(a-=2.25/2.75)*a+.9375:7.5625*(a-=2.625/2.75)*a+.984375},I=function(a){return a<1/2.75?7.5625*a*a:a<2/2.75?2-(7.5625*(a-=1.5/2.75)*a+.75):a<2.5/2.75?2-(7.5625*(a-=2.25/2.75)*a+.9375):2-(7.5625*(a-=2.625/2.75)*a+.984375)},J=function(a){return(a/=.5)<1?.5*Math.pow(a,4):-.5*((a-=2)*Math.pow(a,3)-2)},K=function(a){return Math.pow(a,4)},L=function(a){return Math.pow(a,.25)}},function(a,b){var c;c=function(){return this}();try{c=c||new Function("return this")()}catch(a){"object"==typeof window&&(c=window)}a.exports=c},function(a,b,c){"use strict";function d(a){return parseInt(a,16)}function e(a){var b=a._currentState;[b,a._originalState,a._targetState].forEach(B),a._tokenData=E(b)}function f(a){var b=a._currentState,c=a._originalState,d=a._targetState,e=a._easing,f=a._tokenData;K(e,f),[b,c,d].forEach(function(a){return F(a,f)})}function g(a){var b=a._currentState,c=a._originalState,d=a._targetState,e=a._easing,f=a._tokenData;[b,c,d].forEach(function(a){return J(a,f)}),L(e,f)}function h(a,b){var c=Object.keys(a);if(Object.getOwnPropertySymbols){var d=Object.getOwnPropertySymbols(a);b&&(d=d.filter(function(b){return Object.getOwnPropertyDescriptor(a,b).enumerable})),c.push.apply(c,d)}return c}function i(a){for(var b=1;b=0?a:0-a};return i=1-(k=3*b)-(j=3*(d-b)-k),l=1-(n=3*c)-(m=3*(e-c)-n),g=a,h=function(a){return 1/(200*a)}(f),function(a){return((l*a+m)*a+n)*a}(function(a,b){var c,d,e,f,g,h;for(e=a,h=0;h<8;h++){if(f=o(e)-a,q(f)(d=1))return d;for(;cf?c=e:d=e,e=.5*(d-c)+c}return e}(g,h))}c.r(b);var o={};c.r(o),c.d(o,"doesApply",function(){return M}),c.d(o,"tweenCreated",function(){return e}),c.d(o,"beforeTween",function(){return f}),c.d(o,"afterTween",function(){return g});var p,q,r=c(0),s=/(\d|-|\.)/,t=/([^\-0-9.]+)/g,u=/[0-9.-]+/g,v=(p=u.source,q=/,\s*/.source,new RegExp("rgb\\(".concat(p).concat(q).concat(p).concat(q).concat(p,"\\)"),"g")),w=/^.*\(/,x=/#([0-9]|[a-f]){3,6}/gi,y=function(a,b){return a.map(function(a,c){return"_".concat(b,"_").concat(c)})},z=function(a){return"rgb(".concat((b=a,3===(b=b.replace(/#/,"")).length&&(b=(b=b.split(""))[0]+b[0]+b[1]+b[1]+b[2]+b[2]),[d(b.substr(0,2)),d(b.substr(2,2)),d(b.substr(4,2))]).join(","),")");var b},A=function(a,b,c){var d=b.match(a),e=b.replace(a,"VAL");return d&&d.forEach(function(a){return e=e.replace("VAL",c(a))}),e},B=function(a){for(var b in a){var c=a[b];"string"==typeof c&&c.match(x)&&(a[b]=A(x,c,z))}},C=function(a){var b=a.match(u).map(Math.floor);return"".concat(a.match(w)[0]).concat(b.join(","),")")},D=function(a){return a.match(u)},E=function(a){var b,c,d={};for(var e in a){var f=a[e];"string"==typeof f&&(d[e]={formatString:(b=f,c=void 0,c=b.match(t),c?(1===c.length||b.charAt(0).match(s))&&c.unshift(""):c=["",""],c.join("VAL")),chunkNames:y(D(f),e)})}return d},F=function(a,b){var c=function(c){D(a[c]).forEach(function(d,e){return a[b[c].chunkNames[e]]=+d}),delete a[c]};for(var d in b)c(d)},G=function(a,b){var c={};return b.forEach(function(b){c[b]=a[b],delete a[b]}),c},H=function(a,b){return b.map(function(b){return a[b]})},I=function(a,b){return b.forEach(function(b){return a=a.replace("VAL",+b.toFixed(4))}),a},J=function(a,b){for(var c in b){var d=b[c],e=d.chunkNames,f=d.formatString,g=I(f,H(G(a,e),e));a[c]=A(v,g,C)}},K=function(a,b){var c=function(c){var d=b[c].chunkNames,e=a[c];if("string"==typeof e){var f=e.split(" "),g=f[f.length-1];d.forEach(function(b,c){return a[b]=f[c]||g})}else d.forEach(function(b){return a[b]=e});delete a[c]};for(var d in b)c(d)},L=function(a,b){for(var c in b){var d=b[c].chunkNames,e=a[d[0]];a[c]="string"==typeof e?d.map(function(b){var c=a[b];return delete a[b],c}).join(" "):e}},M=function(a){var b=a._currentState;return Object.keys(b).some(function(a){return"string"==typeof b[a]})},N=new r.a,O=r.a.filters,P=function(a,b,c,d){var e=arguments.length>4&&void 0!==arguments[4]?arguments[4]:0,f=i({},a),g=Object(r.b)(a,d);for(var h in N._filters.length=0,N.set({}),N._currentState=f,N._originalState=a,N._targetState=b,N._easing=g,O)O[h].doesApply(N)&&N._filters.push(O[h]);N._applyFilter("tweenCreated"),N._applyFilter("beforeTween");var j=Object(r.e)(c,f,a,b,1,e,g);return N._applyFilter("afterTween"),j},Q=function(){function a(){!function(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}(this,a),R.set(this,{writable:!0,value:[]});for(var b=arguments.length,c=new Array(b),d=0;da.strokeWidth&&(b=a.trailWidth);var c=50-b/2;return e.render(this._pathTemplate,{radius:c,"2radius":2*c})},f.prototype._trailString=function(a){return this._pathString(a)},b.exports=f},{"./shape":7,"./utils":9}],3:[function(a,b,c){var d=a("./shape"),e=a("./utils"),f=function(a,b){this._pathTemplate=b.vertical?"M {center},100 L {center},0":"M 0,{center} L 100,{center}",d.apply(this,arguments)};f.prototype=new d,f.prototype.constructor=f,f.prototype._initializeSvg=function(a,b){var c=b.vertical?"0 0 "+b.strokeWidth+" 100":"0 0 100 "+b.strokeWidth;a.setAttribute("viewBox",c),a.setAttribute("preserveAspectRatio","none")},f.prototype._pathString=function(a){return e.render(this._pathTemplate,{center:a.strokeWidth/2})},f.prototype._trailString=function(a){return this._pathString(a)},b.exports=f},{"./shape":7,"./utils":9}],4:[function(a,b,c){b.exports={Line:a("./line"),Circle:a("./circle"),SemiCircle:a("./semicircle"),Square:a("./square"),Path:a("./path"),Shape:a("./shape"),utils:a("./utils")}},{"./circle":2,"./line":3,"./path":5,"./semicircle":6,"./shape":7,"./square":8,"./utils":9}],5:[function(a,b,c){var d=a("shifty"),e=a("./utils"),f=d.Tweenable,g={easeIn:"easeInCubic",easeOut:"easeOutCubic",easeInOut:"easeInOutCubic"},h=function a(b,c){if(!(this instanceof a))throw new Error("Constructor was called without new keyword");c=e.extend({delay:0,duration:800,easing:"linear",from:{},to:{},step:function(){}},c);var d;d=e.isString(b)?document.querySelector(b):b,this.path=d,this._opts=c,this._tweenable=null;var f=this.path.getTotalLength();this.path.style.strokeDasharray=f+" "+f,this.set(0)};h.prototype.value=function(){var a=this._getComputedDashOffset(),b=this.path.getTotalLength(),c=1-a/b;return parseFloat(c.toFixed(6),10)},h.prototype.set=function(a){this.stop(),this.path.style.strokeDashoffset=this._progressToOffset(a);var b=this._opts.step;if(e.isFunction(b)){var c=this._easing(this._opts.easing);b(this._calculateTo(a,c),this._opts.shape||this,this._opts.attachment)}},h.prototype.stop=function(){this._stopTween(),this.path.style.strokeDashoffset=this._getComputedDashOffset()},h.prototype.animate=function(a,b,c){b=b||{},e.isFunction(b)&&(c=b,b={});var d=e.extend({},b),g=e.extend({},this._opts);b=e.extend(g,b);var h=this._easing(b.easing),i=this._resolveFromAndTo(a,h,d);this.stop(),this.path.getBoundingClientRect();var j=this._getComputedDashOffset(),k=this._progressToOffset(a),l=this;this._tweenable=new f,this._tweenable.tween({from:e.extend({offset:j},i.from),to:e.extend({offset:k},i.to),duration:b.duration,delay:b.delay,easing:h,step:function(a){l.path.style.strokeDashoffset=a.offset;var c=b.shape||l;b.step(a,c,b.attachment)}}).then(function(a){e.isFunction(c)&&c()}).catch(function(a){throw console.error("Error in tweening:",a),a})},h.prototype._getComputedDashOffset=function(){var a=window.getComputedStyle(this.path,null);return parseFloat(a.getPropertyValue("stroke-dashoffset"),10)},h.prototype._progressToOffset=function(a){var b=this.path.getTotalLength();return b-a*b},h.prototype._resolveFromAndTo=function(a,b,c){return c.from&&c.to?{from:c.from,to:c.to}:{from:this._calculateFrom(b),to:this._calculateTo(a,b)}},h.prototype._calculateFrom=function(a){return d.interpolate(this._opts.from,this._opts.to,this.value(),a)},h.prototype._calculateTo=function(a,b){return d.interpolate(this._opts.from,this._opts.to,a,b)},h.prototype._stopTween=function(){null!==this._tweenable&&(this._tweenable.stop(!0),this._tweenable=null)},h.prototype._easing=function(a){return g.hasOwnProperty(a)?g[a]:a},b.exports=h},{"./utils":9,shifty:1}],6:[function(a,b,c){var d=a("./shape"),e=a("./circle"),f=a("./utils"),g=function(a,b){this._pathTemplate="M 50,50 m -{radius},0 a {radius},{radius} 0 1 1 {2radius},0",this.containerAspectRatio=2,d.apply(this,arguments)};g.prototype=new d,g.prototype.constructor=g,g.prototype._initializeSvg=function(a,b){a.setAttribute("viewBox","0 0 100 50")},g.prototype._initializeTextContainer=function(a,b,c){a.text.style&&(c.style.top="auto",c.style.bottom="0",a.text.alignToBottom?f.setStyle(c,"transform","translate(-50%, 0)"):f.setStyle(c,"transform","translate(-50%, 50%)"))},g.prototype._pathString=e.prototype._pathString,g.prototype._trailString=e.prototype._trailString,b.exports=g},{"./circle":2,"./shape":7,"./utils":9}],7:[function(a,b,c){var d=a("./path"),e=a("./utils"),f="Object is destroyed",g=function a(b,c){if(!(this instanceof a))throw new Error("Constructor was called without new keyword");if(0!==arguments.length){this._opts=e.extend({color:"#555",strokeWidth:1,trailColor:null,trailWidth:null,fill:null,text:{style:{color:null,position:"absolute",left:"50%",top:"50%",padding:0,margin:0,transform:{prefix:!0,value:"translate(-50%, -50%)"}},autoStyleContainer:!0,alignToBottom:!0,value:null,className:"progressbar-text"},svgStyle:{display:"block",width:"100%"},warnings:!1},c,!0),e.isObject(c)&&void 0!==c.svgStyle&&(this._opts.svgStyle=c.svgStyle),e.isObject(c)&&e.isObject(c.text)&&void 0!==c.text.style&&(this._opts.text.style=c.text.style);var f,g=this._createSvgView(this._opts);if(!(f=e.isString(b)?document.querySelector(b):b))throw new Error("Container does not exist: "+b);this._container=f,this._container.appendChild(g.svg),this._opts.warnings&&this._warnContainerAspectRatio(this._container),this._opts.svgStyle&&e.setStyles(g.svg,this._opts.svgStyle),this.svg=g.svg,this.path=g.path,this.trail=g.trail,this.text=null;var h=e.extend({attachment:void 0,shape:this},this._opts);this._progressPath=new d(g.path,h),e.isObject(this._opts.text)&&null!==this._opts.text.value&&this.setText(this._opts.text.value)}};g.prototype.animate=function(a,b,c){if(null===this._progressPath)throw new Error(f);this._progressPath.animate(a,b,c)},g.prototype.stop=function(){if(null===this._progressPath)throw new Error(f);void 0!==this._progressPath&&this._progressPath.stop()},g.prototype.pause=function(){if(null===this._progressPath)throw new Error(f);void 0!==this._progressPath&&this._progressPath._tweenable&&this._progressPath._tweenable.pause()},g.prototype.resume=function(){if(null===this._progressPath)throw new Error(f);void 0!==this._progressPath&&this._progressPath._tweenable&&this._progressPath._tweenable.resume()},g.prototype.destroy=function(){if(null===this._progressPath)throw new Error(f);this.stop(),this.svg.parentNode.removeChild(this.svg),this.svg=null,this.path=null,this.trail=null,this._progressPath=null,null!==this.text&&(this.text.parentNode.removeChild(this.text),this.text=null)},g.prototype.set=function(a){if(null===this._progressPath)throw new Error(f);this._progressPath.set(a)},g.prototype.value=function(){if(null===this._progressPath)throw new Error(f);return void 0===this._progressPath?0:this._progressPath.value()},g.prototype.setText=function(a){if(null===this._progressPath)throw new Error(f);null===this.text&&(this.text=this._createTextContainer(this._opts,this._container),this._container.appendChild(this.text)),e.isObject(a)?(e.removeChildren(this.text),this.text.appendChild(a)):this.text.innerHTML=a},g.prototype._createSvgView=function(a){var b=document.createElementNS("http://www.w3.org/2000/svg","svg");this._initializeSvg(b,a);var c=null;(a.trailColor||a.trailWidth)&&(c=this._createTrail(a),b.appendChild(c));var d=this._createPath(a);return b.appendChild(d),{svg:b,path:d,trail:c}},g.prototype._initializeSvg=function(a,b){a.setAttribute("viewBox","0 0 100 100")},g.prototype._createPath=function(a){var b=this._pathString(a);return this._createPathElement(b,a)},g.prototype._createTrail=function(a){var b=this._trailString(a),c=e.extend({},a);return c.trailColor||(c.trailColor="#eee"),c.trailWidth||(c.trailWidth=c.strokeWidth),c.color=c.trailColor,c.strokeWidth=c.trailWidth,c.fill=null,this._createPathElement(b,c)},g.prototype._createPathElement=function(a,b){var c=document.createElementNS("http://www.w3.org/2000/svg","path");return c.setAttribute("d",a),c.setAttribute("stroke",b.color),c.setAttribute("stroke-width",b.strokeWidth),b.fill?c.setAttribute("fill",b.fill):c.setAttribute("fill-opacity","0"),c},g.prototype._createTextContainer=function(a,b){var c=document.createElement("div");c.className=a.text.className;var d=a.text.style;return d&&(a.text.autoStyleContainer&&(b.style.position="relative"),e.setStyles(c,d),d.color||(c.style.color=a.color)),this._initializeTextContainer(a,b,c),c},g.prototype._initializeTextContainer=function(a,b,c){},g.prototype._pathString=function(a){throw new Error("Override this function for each progress bar")},g.prototype._trailString=function(a){throw new Error("Override this function for each progress bar")},g.prototype._warnContainerAspectRatio=function(a){if(this.containerAspectRatio){var b=window.getComputedStyle(a,null),c=parseFloat(b.getPropertyValue("width"),10),d=parseFloat(b.getPropertyValue("height"),10);e.floatEquals(this.containerAspectRatio,c/d)||(console.warn("Incorrect aspect ratio of container","#"+a.id,"detected:",b.getPropertyValue("width")+"(width)","/",b.getPropertyValue("height")+"(height)","=",c/d),console.warn("Aspect ratio of should be",this.containerAspectRatio))}},b.exports=g},{"./path":5,"./utils":9}],8:[function(a,b,c){var d=a("./shape"),e=a("./utils"),f=function(a,b){this._pathTemplate="M 0,{halfOfStrokeWidth} L {width},{halfOfStrokeWidth} L {width},{width} L {halfOfStrokeWidth},{width} L {halfOfStrokeWidth},{strokeWidth}",this._trailTemplate="M {startMargin},{halfOfStrokeWidth} L {width},{halfOfStrokeWidth} L {width},{width} L {halfOfStrokeWidth},{width} L {halfOfStrokeWidth},{halfOfStrokeWidth}",d.apply(this,arguments)};f.prototype=new d,f.prototype.constructor=f,f.prototype._pathString=function(a){var b=100-a.strokeWidth/2;return e.render(this._pathTemplate,{width:b,strokeWidth:a.strokeWidth,halfOfStrokeWidth:a.strokeWidth/2})},f.prototype._trailString=function(a){var b=100-a.strokeWidth/2;return e.render(this._trailTemplate,{width:b,strokeWidth:a.strokeWidth,halfOfStrokeWidth:a.strokeWidth/2,startMargin:a.strokeWidth/2-a.trailWidth/2})},b.exports=f},{"./shape":7,"./utils":9}],9:[function(a,b,c){function d(a,b,c){a=a||{},b=b||{},c=c||!1;for(var e in b)if(b.hasOwnProperty(e)){var f=a[e],g=b[e];c&&l(f)&&l(g)?a[e]=d(f,g,c):a[e]=g}return a}function e(a,b){var c=a;for(var d in b)if(b.hasOwnProperty(d)){var e=b[d],f="\\{"+d+"\\}",g=new RegExp(f,"g");c=c.replace(g,e)}return c}function f(a,b,c){for(var d=a.style,e=0;e. +// and can be redistributed under the terms of GNU GPL v3 . + +class RAL { + static #ral_data_files = new Array(N_RAL_FILES).fill(null); + + static async load_ral_data(){ + this.#init_progressbar(); + + // Dispatch all JSON fetch requests in parallel + var fetches = []; + for(var i=0; i { + this.#increment_progressbar(); + this.#ral_data_files[idx] = data; + }) + .catch(e => { + this.#destroy_progressbar(); + throw new Error("fetch failed"); + }); + return awaitable; + } + + static #progress_points = 0; + static #progressbar = null; + static #init_progressbar(){ + this.#progressbar = new ProgressBar.Circle("#_ProgressBar", { + strokeWidth: 10, // forces extra padding + trailWidth: 3, + text: { + value: "Loading..." + } + }); + + if(N_RAL_FILES == 1){ + // Only one object to load. animate progress as stand-in. + this.#progressbar.animate(1, {duration:400}); + } + } + static #increment_progressbar(){ + this.#progress_points++; + this.#progressbar.set(this.#progress_points / N_RAL_FILES); + if(this.#progress_points == N_RAL_FILES) { + this.#destroy_progressbar(); + } + } + + static #destroy_progressbar(){ + this.#progressbar.destroy(); + this.#progressbar = null; + } + + static get_node(id){ + var file_idx = Math.floor(id / N_RAL_NODES_PER_FILE); + var idx = id % N_RAL_NODES_PER_FILE; + var node = this.#ral_data_files[file_idx][idx]; + this.#expand_bigint(node); + return node; + } + + static #expand_bigint(node){ + // Check if RAL entry has been converted yet + if(typeof node.offset !== 'string') return; + + // Needs conversion from base-16 string --> BigInt object + node.offset = BigInt("0x" + node.offset); + node.size = BigInt("0x" + node.size); + if('stride' in node) node.stride = BigInt("0x" + node.stride); + + if(RAL.is_register_node(node)) { + for(var i=0; i= segment_idxs[0].length){ + sanitized_idxs.push(0); + } else { + sanitized_idxs.push(Math.min(segment_idxs[0][dim], this.get_node(id).dims[dim]-1)); + } + } + segment_idxs[0] = sanitized_idxs; + } else { + if(segment_idxs[0].length != 0) segment_idxs[0] = []; + } + + // Validate the path and find the end ID + for(var i=1; i= segment_idxs[i].length){ + sanitized_idxs.push(0); + } else { + sanitized_idxs.push(Math.min(segment_idxs[i][dim], this.get_node(id).dims[dim]-1)); + } + } + segment_idxs[i] = sanitized_idxs; + } else { + if(segment_idxs[i].length != 0) segment_idxs[i] = []; + } + } + + return([id, segment_idxs]); + } + + static apply_idx_stack(id, idx_stack){ + // Applies the given index stack onto the RAL + // Assumes the indexes are valid + for(var i=idx_stack.length-1; i>=0; i--){ + if(idx_stack[i].length){ + this.get_node(id).idxs = idx_stack[i]; + } + id = this.get_node(id).parent; + } + } + + static get_path(id, idx_stack, show_idx){ + if(typeof idx_stack === "undefined") idx_stack = null; + if(typeof show_idx === "undefined") show_idx = true; + + // Get string representation of the hierarchical path + if(show_idx && (idx_stack == null)){ + idx_stack = this.get_current_idx_stack(id); + } + var ids = this.get_ids_in_path(id); + var pathparts = []; + for(var i=0; i= (this.get_node(id).offset + this.get_total_size(id))) return(null); + + while(iter_count < 100){ + iter_count++; + // addr is definitely inside this node + + // Adjust addr to be relative to this node + addr = addr - this.get_node(id).offset; + + // Determine index stack entry for this node + if(this.is_array(id)){ + var idxs = []; + + // First check if address lands between sparse array entries + if((addr % this.get_node(id).stride) >= this.get_node(id).size) { + // missed! Give up and just return the parent node + if(this.get_node(id).parent == null){ + return(null); + }else{ + return([this.get_node(id).parent, idx_stack]); + } + } + + // index of the flattened array + var flat_idx = Number(addr / this.get_node(id).stride); + + // Re-construct dimensions + for(var dim=this.get_node(id).dims.length-1; dim>=0; dim--){ + var idx; + idx = flat_idx % this.get_node(id).dims[dim]; + flat_idx = Math.floor(flat_idx / this.get_node(id).dims[dim]); + idxs.unshift(idx); + } + idx_stack.push(idxs); + + // Adjust addr offset to be relative to this index + addr = addr % this.get_node(id).stride; + } else { + idx_stack.push([]); + } + + // Search this node's children to see which child 'addr' is in + var found_match = false; + for(var i=0; i= this.get_node(child).offset) && (addr < (this.get_node(child).offset + this.get_total_size(child)))){ + // hit! + id = child; + found_match = true; + break; + } + } + if(!found_match){ + // No further match. Current node is the result + return([id, idx_stack]); + } + } + + // Hit iteration limit. Something is wrong :-( + throw "Agh! iteration limit reached while looking up by address"; + } + + static lookup_field_idx(name) { + var node = this.get_node(CurrentID); + for(var i=0; i. +// and can be redistributed under the terms of GNU GPL v3 . + +var SearchState = {}; +SearchState.active = false; +SearchState.results = []; +SearchState.selected_result = null; +SearchState.abortController = null; + + +function onSearchButtonClick() { + if(SearchState.active){ + // Close search + close_search(); + } else { + // Open search + open_search(); + } +} + +function open_search(query_text){ + if(typeof query_text === "undefined") query_text = ""; + document.getElementById("_SearchBar").style.display = "block"; + document.getElementById("_Search").style.display = "flex"; + document.getElementById("_Content").style.display = "none"; + document.getElementById("_SBSearchButton").classList.add("close-button"); + document.getElementById("_SBSearchButton").classList.remove("search-button"); + document.getElementById("_MobiSearchButton").classList.add("close-button"); + document.getElementById("_MobiSearchButton").classList.remove("search-button"); + SearchState.active = true; + + clear_search_results(); + + var input_el = document.getElementById('_SearchInput'); + input_el.onkeydown = onSearchInputKeypress; + input_el.oninput = onSearchInputUpdate; + input_el.value = query_text; + input_el.focus(); + + if(query_text != "") { + start_search(query_text); + } +} + +function close_search(){ + clear_search_results(); + document.getElementById("_SearchBar").style.display = "none"; + document.getElementById("_Search").style.display = "none"; + document.getElementById("_Content").style.display = "block"; + document.getElementById("_SBSearchButton").classList.add("search-button"); + document.getElementById("_SBSearchButton").classList.remove("close-button"); + document.getElementById("_MobiSearchButton").classList.add("search-button"); + document.getElementById("_MobiSearchButton").classList.remove("close-button"); + SearchState.active = false; + if(SearchState.abortController) { + SearchState.abortController.abort(); + SearchState.abortController = null; + } +} + +function onKeyDownSearch(ev) { + // return True if event was not handled here + if(!SearchState.active && ev.key == "/" && !ev.ctrlKey){ + open_search(); + return false; + } + + if(!SearchState.active && ev.key == "/" && ev.ctrlKey){ + open_search(RAL.get_path(CurrentID, undefined, false) + " "); + return false; + } + + if(SearchState.active){ + if(ev.key == "Escape"){ + close_search(); + return false; + } + } + + return true; +} + +function onSearchInputKeypress(ev){ + if(!ev) ev = window.event; + + if(ev.key == "Enter"){ + // Open current selection + if(SearchState.selected_result != null){ + open_search_result(SearchState.selected_result); + } else if(SearchState.results.length == 1){ + open_search_result(0); + } + return false; + } else if(ev.key == "ArrowUp"){ + // Move selection up + if((SearchState.selected_result != null) && (SearchState.selected_result != 0)){ + SearchState.results[SearchState.selected_result].el.classList.remove("selected"); + SearchState.selected_result--; + SearchState.results[SearchState.selected_result].el.classList.add("selected"); + } + + return false; + } else if(ev.key == "ArrowDown"){ + // Move selection down + if(SearchState.selected_result != null){ + // Selection already active + if(SearchState.selected_result < SearchState.results.length-1){ + SearchState.results[SearchState.selected_result].el.classList.remove("selected"); + SearchState.selected_result++; + SearchState.results[SearchState.selected_result].el.classList.add("selected"); + } + } else if(SearchState.results.length){ + // Select first + SearchState.selected_result = 0; + SearchState.results[0].el.classList.add("selected"); + } + + return false; + } +} + +function onSearchInputUpdate(ev){ + var query = ev.target.value.trim().toLowerCase(); + + clear_search_results(); + + start_search(query); +} + +function clear_search_results(){ + var results_el = document.getElementById("_SearchResults"); + + var range = document.createRange(); + range.selectNodeContents(results_el); + range.deleteContents(); + + SearchState.results = []; + SearchState.selected_result = null; +} + +async function start_search(query) { + + // Abort any prior search + if(SearchState.abortController){ + SearchState.abortController.abort(); + } + SearchState.abortController = new AbortController(); + var abortSignal = SearchState.abortController.signal; + + if(query.length == 0) return; + + if(query.startsWith("@")){ + AddressSearch.start(query); + } else { + await PathSearch.start(query, abortSignal); + if(abortSignal.aborted) return; + + // Start a content search if path search completed successfully + await ContentSearch.start(query, abortSignal); + } +} + +function add_search_result(text_segments, node_id, idx_stack=null, anchor="", content_preview=null){ + // text_segments is an array of segments that should/shouldn't be highlighted + // All odd segments are highlighted via tag. + // text_segments[0] --> not highlighted + // text_segments[1] --> highlighted + + var result_idx = SearchState.results.length; + var result_el = document.createElement("li"); + result_el.onmousemove = function() { + onSearchResultMousemove(result_idx) + }; + + // wrap in clickable link + result_link = document.createElement("a"); + result_link.href = "?p=" + RAL.get_path(node_id, idx_stack); + if(anchor != ""){ + result_link.href += "#" + anchor; + } + result_link.onclick = function(ev) { + open_search_result(result_idx); + return(false); + }; + result_el.appendChild(result_link); + + var path_div_el = document.createElement("div"); + result_link.appendChild(path_div_el); + + // Build highlighted path crumbtrail + for(var i=0; i { + Sidebar.expand_to_id(result.node_id); + Sidebar.select_node(result.node_id); + Sidebar.scroll_into_view(result.node_id); + refresh_url(url_hash); + refresh_title(); + refresh_target_scroll(); + }); +} diff --git a/rdl/outputs/docs/html/js/sha1.js b/rdl/outputs/docs/html/js/sha1.js new file mode 100644 index 0000000..8dd7141 --- /dev/null +++ b/rdl/outputs/docs/html/js/sha1.js @@ -0,0 +1,173 @@ +/** +* +* Secure Hash Algorithm (SHA1) +* http://www.webtoolkit.info/ +* +**/ + +function SHA1(msg) { + + function rotate_left(n,s) { + var t4 = ( n<>>(32-s)); + return t4; + }; + + function lsb_hex(val) { + var str=""; + var i; + var vh; + var vl; + + for( i=0; i<=6; i+=2 ) { + vh = (val>>>(i*4+4))&0x0f; + vl = (val>>>(i*4))&0x0f; + str += vh.toString(16) + vl.toString(16); + } + return str; + }; + + function cvt_hex(val) { + var str=""; + var i; + var v; + + for( i=7; i>=0; i-- ) { + v = (val>>>(i*4))&0x0f; + str += v.toString(16); + } + return str; + }; + + + function Utf8Encode(string) { + string = string.replace(/\r\n/g,"\n"); + var utftext = ""; + + for (var n = 0; n < string.length; n++) { + + var c = string.charCodeAt(n); + + if (c < 128) { + utftext += String.fromCharCode(c); + } + else if((c > 127) && (c < 2048)) { + utftext += String.fromCharCode((c >> 6) | 192); + utftext += String.fromCharCode((c & 63) | 128); + } + else { + utftext += String.fromCharCode((c >> 12) | 224); + utftext += String.fromCharCode(((c >> 6) & 63) | 128); + utftext += String.fromCharCode((c & 63) | 128); + } + + } + + return utftext; + }; + + var blockstart; + var i, j; + var W = new Array(80); + var H0 = 0x67452301; + var H1 = 0xEFCDAB89; + var H2 = 0x98BADCFE; + var H3 = 0x10325476; + var H4 = 0xC3D2E1F0; + var A, B, C, D, E; + var temp; + + msg = Utf8Encode(msg); + + var msg_len = msg.length; + + var word_array = new Array(); + for( i=0; i>>29 ); + word_array.push( (msg_len<<3)&0x0ffffffff ); + + + for ( blockstart=0; blockstart. +// and can be redistributed under the terms of GNU GPL v3 . + +class Sidebar { + static #selected_node_id = null; + static #resizer_old_width = 0; + static #resizer_start_x = 0; + + static #mousemove_cb = null; + static #mouseup_cb = null; + + static init(first_id){ + var el; + // Initialize the sidebar + + // Bind event to resizer + this.#mousemove_cb = this.#onResizeMouseMove.bind(this); + this.#mouseup_cb = this.#onResizeMouseUp.bind(this); + el = document.getElementById("_SBResizer") + el.addEventListener("mousedown", this.#onResizeMouseDown.bind(this)); + + // create the root node(s). Do not recurse + el = document.getElementById("_SBTree"); + for(var i=0; i=0; i--){ + var current_id = id_chain[i]; + var el = this.#get_node_el(current_id); + if(el == null){ + // doesnt exist. it will get expanded once created + node_ids_to_expand.unshift(current_id); + } else { + // reached node that exists already + if(el.classList.contains("closed")){ + // .. but it is still closed + node_ids_to_expand.unshift(current_id); + } + break; + } + } + + // Create missing elements + for(var i=0; i 0){ + if(el.classList.contains("open")){ + return; // already open + } + + var cdiv; + cdiv = document.createElement("div"); + cdiv.className = "node-children"; + el.after(cdiv); + + for(var i=0; i 0){ + if(el.classList.contains("closed")){ + return; // already closed + } + var cdiv = el.nextElementSibling; + if(cdiv.classList.contains('node-children')){ + cdiv.remove(); + } else { + console.error("OOPS"); + } + el.classList.add("closed") + el.classList.remove("open") + } + } + + static collapse_all(){ + for(var i=0; i 0){ + // has children + div.classList.add("closed"); + + var cdiv; + cdiv = document.createElement("div"); + cdiv.className = "node-children"; + parent_el.appendChild(cdiv); + } else { + // is leaf node + div.classList.add("leaf"); + } + } + + static select_node(id) { + // Changes the selected tree node + var el; + if(this.#selected_node_id != null){ + el = this.#get_node_el(this.#selected_node_id) + if(el != null){ // element might have already been deleted + el.classList.remove("selected"); + } + } + + el = this.#get_node_el(id); + el.classList.add("selected"); + this.#selected_node_id = id; + } + + static #onResizeMouseDown(e) { + var sb_el = document.getElementById("_SBContents"); + this.#resizer_old_width = sb_el.getBoundingClientRect().width; + this.#resizer_start_x = e.clientX; + window.addEventListener('mousemove', this.#mousemove_cb); + window.addEventListener('mouseup', this.#mouseup_cb); + e.preventDefault(); + } + + static #onResizeMouseMove(e) { + var sb_el = document.getElementById("_SBContents"); + var new_width; + new_width = this.#resizer_old_width + e.clientX - this.#resizer_start_x; + sb_el.style.width = new_width + "px"; + } + + static #onResizeMouseUp(e) { + window.removeEventListener('mousemove', this.#mousemove_cb); + window.removeEventListener('mouseup', this.#mouseup_cb); + + // remember sidebar width + var sb_el = document.getElementById("_SBContents"); + localStorage.setItem(page_specific_key("sb_width"), sb_el.style.width); + } + + static show() { + document.getElementById("_Sidebar").style.display = "flex"; + document.getElementById("_Overlay").style.display = "block"; + } + + static hide() { + document.getElementById("_Sidebar").style.display = "none"; + document.getElementById("_Overlay").style.display = "none"; + } + + static scroll_into_view(id){ + var node_el = this.#get_node_el(id); + var tree_el = document.getElementById("_SBTreeContainer"); + + var node_rect = node_el.getBoundingClientRect(); + var tree_rect = tree_el.getBoundingClientRect(); + + if( + (node_rect.top < tree_rect.top) + || (node_rect.bottom > tree_rect.bottom) + || (node_rect.left < tree_rect.left) + || (node_rect.right > tree_rect.right) + ) { + node_el.scrollIntoView({ + block: "nearest", + inline: "start" + }); + } + } +} + +function onClickTreeFold(ev) { + var el = ev.target.parentNode; + var id = parseInt(el.dataset.id); + if(el.classList.contains("leaf")) return; + + if(el.classList.contains("closed")){ + // Open this node + Sidebar.expand_node(id); + + // may need to re-select current + Sidebar.select_node(CurrentID); + }else{ + // Close this node + Sidebar.collapse_node(id); + } +} + +function onClickTreeLink(ev) { + var el = ev.target.parentNode; + var id = parseInt(el.dataset.id); + + close_search(); + Sidebar.hide(); + + if(id == CurrentID) return(false); + + if(!el.classList.contains("leaf")){ + Sidebar.expand_node(id); + } + + RAL.reset_indexes_to_next(id); + + load_page(id).then(() => { + Sidebar.expand_to_id(id); + Sidebar.select_node(id); + refresh_url(); + refresh_title(); + refresh_target_scroll(); + }); + return(false); +} + +function onClickTreeCollapseAll() { + Sidebar.collapse_all() +} diff --git a/rdl/outputs/docs/html/launcher-windows-chrome.bat b/rdl/outputs/docs/html/launcher-windows-chrome.bat new file mode 100644 index 0000000..09bd64c --- /dev/null +++ b/rdl/outputs/docs/html/launcher-windows-chrome.bat @@ -0,0 +1,17 @@ +@echo off&setlocal + +:: set some convenience variables +for %%i in ("%~dp0.") do set "this_dir=%%~fi" +set "docpath=file://%this_dir%\index.html" +set "launcher_data=%this_dir%\.launcher_data" + +:: Launch using Chrome using some special flags: +:: --allow-file-access-from-files +:: This flag works around a security policy that prevents dynamic content to be loaded +:: See this page for more details: +:: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors/CORSRequestNotHttp +:: --user-data-dir +:: If chrome already has a session open, then it will re-use that session and the CORS workaround +:: will not take effect. Forcing chrome to use a temporary alternate user data directory +:: is a hacky way to force chrome to launch a fresh session +start "" chrome --allow-file-access-from-files --user-data-dir=%launcher_data%\chrome %docpath% diff --git a/rdl/outputs/docs/html/launcher-windows-edge.bat b/rdl/outputs/docs/html/launcher-windows-edge.bat new file mode 100644 index 0000000..36cb2a6 --- /dev/null +++ b/rdl/outputs/docs/html/launcher-windows-edge.bat @@ -0,0 +1,19 @@ +@echo off&setlocal + +:: set some convenience variables +for %%i in ("%~dp0.") do set "this_dir=%%~fi" +set "docpath=file://%this_dir%\index.html" +set "launcher_data=%this_dir%\.launcher_data" + +:: Launch using Edge using some special flags: +:: --allow-file-access-from-files +:: This flag works around a security policy that prevents dynamic content to be loaded +:: See this page for more details: +:: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors/CORSRequestNotHttp +:: --user-data-dir +:: If edge already has a session open, then it will re-use that session and the CORS workaround +:: will not take effect. Forcing edge to use a temporary alternate user data directory +:: is a hacky way to force edge to launch a fresh session +:: NOTE: Edge may prompt you with a few "new user" popups the first time, because +:: the data dir is uninitialized. I could not figure out a clean way to disable this +start "" msedge --allow-file-access-from-files --user-data-dir=%launcher_data%\msedge %docpath% diff --git a/rdl/outputs/docs/html/launcher-windows-firefox.bat b/rdl/outputs/docs/html/launcher-windows-firefox.bat new file mode 100644 index 0000000..132f223 --- /dev/null +++ b/rdl/outputs/docs/html/launcher-windows-firefox.bat @@ -0,0 +1,14 @@ +@echo off&setlocal + +:: set some convenience variables +for %%i in ("%~dp0.") do set "this_dir=%%~fi" +set "docpath=file://%this_dir%\index.html" +set "launcher_data=%this_dir%\.launcher_data" + +:: Launch using Firefox using a pre-configured profile +:: This profile sets the user preference: +:: security.fileuri.strict_origin_policy = false +:: This setting works around a security policy that prevents dynamic content to be loaded +:: See this page for more details: +:: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors/CORSRequestNotHttp +start "" firefox -profile %launcher_data%\firefox %docpath% diff --git a/rdl/outputs/docs/html/search/bkt-0.json b/rdl/outputs/docs/html/search/bkt-0.json new file mode 100644 index 0000000..4d3b52a --- /dev/null +++ b/rdl/outputs/docs/html/search/bkt-0.json @@ -0,0 +1 @@ +{"ber":[["ber",[[21,2],[22,2]]]],"shi":[["shift",[[27,11],[14,11]]]],"aut":[["auto",[[17,42],[17,43]]]],"gen":[["generation",[[32,0]]],["generator",[[17,0],[18,2]]]],"cod":[["code",[[38,2],[37,2]]]],"sen":[["sent",[[33,2]]]],"has":[["hash",[[1,2],[2,1],[1,1],[2,3],[2,2],[1,3]]]],"dif":[["differential",[[4,34],[4,35]]]],"dac":[["dac",[[5,10],[5,11]]]],"aft":[["after",[[30,2],[33,2],[31,2],[17,42]]]],"adj":[["adjust",[[28,1],[29,1]]]],"lis":[["list",[[38,2],[36,2],[37,2]]]],"poi":[["pointer",[[38,2],[37,2]]],["pointers",[[38,1],[37,0],[38,0],[37,2],[38,2],[37,1]]]],"low":[["low",[[13,0],[13,1]]],["lower",[[1,1],[1,2],[1,3]]],["lowpass",[[13,27]]]],"ove":[["overflow",[[39,11],[39,10]]]],"app":[["applied",[[28,2],[29,2]]]],"nor":[["normal",[[17,10],[13,10],[3,10],[32,10],[4,18],[17,2],[39,10],[13,2],[3,18],[3,2]]]],"sin":[["since",[[21,2],[22,2],[39,18],[39,26]]]],"tim":[["times",[[33,2]]]],"act":[["active",[[5,11],[7,2],[5,19],[30,2],[31,2]]]],"inc":[["incoming",[[36,2]]]],"alp":[["alpha",[[13,27],[34,1],[35,1],[34,0],[35,0],[34,3],[35,3],[34,2],[35,2]]]],"0x3":[["0x3",[[35,2],[34,2]]],["0x3_ffff",[[35,2],[34,2]]]],"ope":[["operation",[[17,0],[13,10],[3,10],[26,0],[32,10],[39,10],[13,2],[3,18],[3,2]]]],"des":[["desired",[[9,2],[11,2],[12,2],[8,2],[10,2]]]],"out":[["output",[[16,3],[16,2],[15,3],[15,2],[16,1]]]],"off":[["offet",[[28,2],[29,2]]]],"cha":[["channel",[[36,2]]]],"las":[["last",[[21,2],[22,2],[39,18],[39,26]]]],"cal":[["calculated",[[21,2],[22,2]]]],"ena":[["enable",[[4,26],[5,11],[4,35],[4,19],[4,3],[7,3],[32,2],[3,19],[3,3],[7,2],[5,19],[32,3],[4,11],[3,11]]],["enabled",[[4,10],[33,0],[4,2],[5,26],[5,10],[4,34],[5,18]]]],"ini":[["init",[[3,19],[3,3],[3,11]]],["initial",[[18,0]]],["initialization",[[3,1],[3,0]]],["initialize",[[3,18],[3,2],[3,10]]]],"mad":[["made",[[6,2]]]],"pas":[["pass",[[13,0],[13,1]]]],"man":[["manual",[[17,27]]]],"ste":[["steps",[[22,2],[6,2],[25,2],[37,2],[21,2],[38,2],[28,2],[23,2],[7,2],[29,2],[24,2],[30,2],[36,2],[31,2]]]],"sho":[["should",[[33,2]]]],"fff":[["ffff",[[35,2],[39,18],[33,2],[34,2]]]],"rec":[["receive",[[36,0],[36,1],[36,3]]],["received",[[22,2],[39,18],[21,0],[21,3],[21,2],[39,19]]]],"s_a":[["s_axis",[[25,2],[25,3]]],["s_axis_valid",[[5,26],[5,27]]]],"acc":[["accumulator",[[23,1],[24,1],[23,0],[13,10],[24,0],[23,3],[13,3],[24,3],[23,2],[24,2],[13,11]]]],"asy":[["async",[[38,1],[37,0],[37,1],[38,0]]]],"ave":[["average",[[34,1],[35,1]]]],"rep":[["represent",[[35,2],[36,2],[34,2]]],["represents",[[33,2]]]],"0x0":[["0x0",[[35,2],[34,2]]],["0x00",[[39,18],[33,2]]],["0x00_0000",[[39,18],[33,2]]],["0x0_0000",[[35,2],[34,2]]]],"mov":[["moving",[[34,1],[35,1]]]],"cos":[["costas",[[30,2],[31,2]]]],"loc":[["lock",[[39,3]]],["locked",[[39,2]]]],"fre":[["freeze",[[13,2],[13,3]]],["frequency",[[12,1],[9,2],[8,3],[10,0],[11,2],[10,3],[29,1],[12,0],[12,3],[28,2],[8,2],[9,1],[10,2],[11,1],[12,2],[9,0],[28,1],[9,3],[8,1],[11,0],[11,3],[10,1],[29,2]]]],"ad9":[["ad9363",[[5,11],[5,19]]]],"mul":[["multiplier",[[27,2],[14,2]]]],"see":[["seed",[[18,3]]]],"ptt":[["ptt",[[33,2],[4,2],[32,2]]]],"sta":[["starting",[[18,2]]],["state",[[18,0]]],["status",[[28,0],[5,1],[30,0],[4,27],[25,1],[7,1],[22,1],[5,0],[5,3],[25,0],[6,1],[39,1],[7,0],[29,0],[31,0],[5,2],[0,0],[6,0],[21,1]]]],"ton":[["tones",[[33,0]]]],"mor":[["more",[[39,26]]]],"ind":[["indicate",[[19,2],[20,2]]]],"fpg":[["fpga",[[1,1],[1,2],[2,1],[2,2]]]],"enc":[["encoder",[[4,34],[4,35]]]],"buf":[["buffer",[[39,11],[39,10]]]],"cou":[["count",[[39,18],[6,2],[7,3],[39,26],[6,3]]],["counter",[[4,26]]],["counters",[[4,27],[17,18],[17,19]]]],"inv":[["invert",[[4,19]]],["inverted",[[20,2],[4,18]]]],"eac":[["each",[[30,2],[31,2]]]],"000":[["0000",[[35,2],[39,18],[33,2],[34,2]]]],"rat":[["rate",[[9,2],[8,0],[11,2],[12,2],[8,2],[10,2]]],["ratio",[[21,2],[22,2]]]],"plu":[["pluto",[[0,1],[1,2],[2,1],[1,1],[2,2]]]],"fun":[["functions",[[3,0]]]],"sat":[["saturate",[[39,26]]]],"ema":[["ema",[[34,0],[35,0],[34,3],[35,3],[34,2],[35,2]]]],"fil":[["filter",[[13,26],[13,27],[13,0],[13,1]]]],"dat":[["data",[[22,2],[17,3],[8,0],[5,10],[4,18],[24,2],[15,2],[16,1],[6,2],[37,2],[17,2],[28,2],[30,2],[5,18],[25,0],[16,0],[16,3],[7,0],[15,1],[21,2],[23,2],[36,2],[29,2],[4,19],[17,10],[25,2],[16,2],[15,0],[38,2],[7,2],[6,0],[15,3],[31,2]]]],"tra":[["transfers",[[25,2],[25,3]]],["transmission",[[32,2]]],["transmit",[[32,10]]],["transmitter",[[33,1],[32,0],[32,1]]]],"dis":[["disable",[[32,2]]],["disabled",[[4,10],[17,42],[4,2],[5,26],[5,10],[4,34],[5,18]]],["discard",[[26,11],[26,1],[26,10],[26,0],[26,3],[26,2]]]],"ass":[["asserted",[[33,2],[32,2]]]],"rea":[["read",[[22,2],[39,18],[37,0],[24,2],[38,1],[6,2],[37,2],[28,2],[39,26],[30,2],[38,0],[21,2],[23,2],[36,2],[37,1],[25,2],[38,2],[7,2],[29,2],[31,2]]]],"dur":[["duration",[[33,0],[33,1],[33,3]]]],"dem":[["demodulator",[[11,0],[12,0],[26,0],[5,3],[5,2]]]],"dig":[["digital",[[4,11]]]],"iir":[["iir",[[13,27]]]],"occ":[["occur",[[39,26]]]],"0xf":[["0xff",[[39,18],[33,2]]],["0xff_ffff",[[39,18],[33,2]]]],"pat":[["pattern",[[32,10]]],["patterns",[[32,0]]]],"hol":[["hold",[[13,10],[13,11]]]],"fra":[["frame",[[39,2],[39,11],[39,1],[39,26],[39,3]]],["frames",[[39,18],[39,19],[39,27]]]],"par":[["parallel",[[15,0],[16,0]]]],"fee":[["feedback",[[19,2]]]],"loo":[["loop",[[30,2],[31,2]]],["loopback",[[4,10],[4,11],[4,34],[4,35]]]],"axi":[["axis",[[5,26],[5,27],[25,2],[25,3]]]],"rms":[["rms",[[36,2]]]],"err":[["error",[[17,10],[30,1],[31,2],[31,1],[20,0],[20,3],[17,11],[20,2],[30,2]]],["errored",[[21,2],[22,2]]],["errors",[[17,42],[39,27],[39,26],[22,0],[22,3]]]],"msk":[["msk",[[0,1],[1,2],[4,0],[2,1],[7,1],[0,0],[3,1],[6,1],[1,1],[5,1],[3,0],[2,2],[25,1],[4,1]]]],"pos":[["positions",[[19,2],[20,2]]]],"bot":[["both",[[17,10]]]],"exp":[["exponential",[[34,1],[35,1]]]],"per":[["period",[[30,2],[31,2]]]],"zer":[["zero",[[13,10],[13,11]]]],"com":[["completed",[[25,2]]],["computed",[[36,0]]]],"mas":[["mask",[[20,0],[20,3]]]],"val":[["valid",[[5,26],[5,27]]],["value",[[22,2],[39,18],[14,10],[27,10],[33,2],[24,2],[13,2],[35,2],[6,2],[26,11],[13,26],[23,0],[31,1],[23,3],[37,2],[14,3],[28,2],[39,26],[27,3],[30,2],[21,2],[23,2],[34,2],[14,2],[36,2],[27,2],[29,2],[30,1],[25,2],[24,0],[13,3],[24,3],[38,2],[7,2],[18,2],[26,3],[31,2]]]],"ins":[["insert",[[17,11],[17,10]]],["inserted",[[20,2]]]],"nco":[["nco",[[11,1],[26,11],[12,1],[28,1],[29,1],[8,1],[10,1],[9,2],[26,10],[11,2],[28,2],[12,2],[29,2],[8,2],[9,1],[10,2]]]],"cap":[["capture",[[22,2],[6,2],[25,2],[37,2],[21,2],[38,2],[28,2],[23,2],[7,2],[29,2],[24,2],[30,2],[36,2],[31,2]]]],"dec":[["decoder",[[4,34],[4,35]]]],"fol":[["following",[[22,2],[6,2],[25,2],[37,2],[21,2],[38,2],[28,2],[23,2],[7,2],[29,2],[24,2],[30,2],[36,2],[31,2]]]],"wid":[["width",[[16,0],[16,3],[15,1],[16,2],[15,0],[15,3],[15,2],[16,1]]]],"215":[["215",[[27,2],[14,2]]]],"ser":[["serial",[[15,0],[16,0]]]],"any":[["any",[[22,2],[6,2],[25,2],[37,2],[21,2],[38,2],[28,2],[23,2],[7,2],[29,2],[24,2],[30,2],[36,2],[31,2]]]],"for":[["force",[[32,11]]]],"wri":[["write",[[38,1],[22,2],[6,2],[37,0],[38,0],[25,2],[37,2],[21,2],[38,2],[28,2],[23,2],[7,2],[29,2],[24,2],[30,2],[36,2],[31,2],[37,1]]]],"pus":[["push",[[4,3]]]],"aff":[["affect",[[3,0]]]],"mon":[["monitor",[[21,2],[17,0],[22,2],[17,26]]]],"fif":[["fifo",[[38,1],[37,0],[37,1],[38,0]]]],"cen":[["center",[[9,2],[11,2],[12,2],[8,2],[10,2]]]],"sel":[["select",[[17,2],[17,3]]]],"req":[["requests",[[6,2]]],["required",[[22,2],[6,2],[25,2],[37,2],[21,2],[38,2],[28,2],[23,2],[7,2],[29,2],[24,2],[30,2],[36,2],[31,2]]]],"res":[["reserved",[[13,19],[17,35]]]],"tal":[["talk",[[4,3]]]],"inp":[["input",[[5,11],[16,3],[15,1],[16,2],[15,3],[5,19],[15,2]]]],"bit":[["bit",[[4,26],[27,11],[17,10],[31,2],[30,2],[33,2],[22,0],[19,2],[22,3],[6,3],[20,2],[14,11]]],["bitrate",[[8,1]]],["bits",[[22,2],[1,2],[2,1],[21,0],[20,2],[21,3],[1,1],[37,2],[2,3],[21,2],[38,2],[5,0],[32,0],[2,2],[1,3]]]],"cle":[["clear",[[4,26],[4,27],[17,18],[17,19]]]],"whe":[["where",[[9,2],[11,2],[12,2],[8,2],[10,2]]]],"div":[["divisor",[[27,10],[27,0],[14,10],[14,0]]]],"fie":[["field",[[39,26]]]],"pol":[["polynomial",[[19,2],[19,3],[19,0]]]],"syn":[["sync",[[22,2],[33,1],[39,2],[32,11],[17,42],[32,1],[39,27],[32,3],[39,1],[33,3],[32,2],[5,2],[39,26],[5,3],[39,3],[17,43],[17,27]]],["synchronization",[[33,0],[32,10],[33,2],[32,0]]],["synchronize",[[17,26]]],["synchronous",[[3,0]]]],"num":[["number",[[22,2],[25,2],[21,2],[26,10],[33,2],[7,2],[26,2]]]],"mod":[["modem",[[4,0],[3,1],[5,1],[8,0],[25,1],[15,2],[16,1],[6,2],[7,1],[3,0],[5,0],[4,11],[25,0],[6,1],[16,3],[7,0],[15,1],[3,2],[4,1],[4,10],[0,0],[16,2],[15,3],[6,0]]],["modulator",[[9,0],[10,0]]]],"con":[["configuration",[[4,0],[13,1],[0,0],[14,1],[27,1],[3,0]]],["configure",[[26,0],[13,0]]],["configures",[[17,0],[27,0],[14,0]]],["continuously",[[32,10]]],["control",[[4,0],[12,1],[3,1],[8,3],[32,0],[10,3],[18,1],[20,1],[12,3],[9,1],[11,1],[4,1],[17,1],[9,3],[8,1],[19,1],[32,1],[11,3],[10,1]]],["controller",[[23,1],[13,1],[24,1],[14,1],[27,1],[23,0],[13,0],[23,3],[14,0],[24,0],[24,3],[23,2],[27,0],[24,2]]],["controls",[[13,26]]],["converter",[[15,0],[16,0]]]],"prb":[["prbs",[[22,2],[17,0],[17,3],[19,0],[19,3],[17,18],[17,27],[18,1],[21,0],[22,1],[21,3],[20,1],[17,2],[17,11],[17,26],[18,0],[18,3],[21,2],[20,0],[20,3],[22,0],[22,3],[17,1],[21,1],[17,10],[19,1],[17,19],[18,2],[17,43]]]],"thr":[["threshold",[[17,43]]]],"reg":[["register",[[22,2],[27,1],[14,1],[28,0],[30,0],[24,2],[6,2],[37,2],[28,2],[30,2],[29,0],[21,2],[31,0],[23,2],[36,2],[25,2],[38,2],[7,2],[29,2],[31,2]]],["registers",[[0,1],[3,0],[0,0]]]],"clo":[["clocks",[[7,2]]]],"sig":[["signal",[[36,2],[33,2]]]],"sam":[["sample",[[26,11],[26,1],[9,2],[11,2],[12,2],[26,3],[8,2],[10,2]]],["samples",[[26,10],[26,0],[26,2],[36,0]]]],"doe":[["does",[[3,0]]]],"rol":[["rolloff",[[13,26]]]],"upp":[["upper",[[2,3],[2,1],[2,2]]]],"set":[["set",[[9,0],[16,0],[11,0],[12,0],[8,0],[16,2],[15,0],[10,0],[19,2],[20,2],[15,2]]],["sets",[[27,2],[33,0],[34,0],[9,2],[14,10],[35,0],[11,2],[27,10],[12,2],[18,2],[8,2],[14,2],[10,2]]]],"777":[["777",[[27,2],[14,2]]]],"imp":[["implemented",[[5,2]]]],"int":[["integral",[[14,2],[14,3],[14,10],[14,11]]],["interface",[[5,11],[5,19]]]],"pow":[["power",[[36,0],[36,1],[36,2],[36,3]]]],"adc":[["adc",[[5,18],[5,19]]]],"cur":[["current",[[13,2],[13,3]]],["currently",[[5,2]]]],"gai":[["gain",[[27,11],[14,0],[14,3],[27,0],[27,3],[14,11]]]],"pro":[["proportional",[[27,2],[27,3],[27,10],[27,11]]],["provides",[[32,0]]]]} \ No newline at end of file diff --git a/rdl/outputs/docs/html/search/bkt_index.js b/rdl/outputs/docs/html/search/bkt_index.js new file mode 100644 index 0000000..175c354 --- /dev/null +++ b/rdl/outputs/docs/html/search/bkt_index.js @@ -0,0 +1 @@ +var SearchBucketIndex = [267651219]; \ No newline at end of file diff --git a/rdl/outputs/docs/msk_top_regs.docx b/rdl/outputs/docs/msk_top_regs.docx new file mode 100644 index 0000000..ac6b82d Binary files /dev/null and b/rdl/outputs/docs/msk_top_regs.docx differ diff --git a/rdl/outputs/docs/msk_top_regs.md b/rdl/outputs/docs/msk_top_regs.md new file mode 100644 index 0000000..c3a221c --- /dev/null +++ b/rdl/outputs/docs/msk_top_regs.md @@ -0,0 +1,881 @@ + + +## msk_top_regs address map + +- Absolute Address: 0x0 +- Base Offset: 0x0 +- Size: 0x9C + +

MSK Modem Configuration and Status Registers

+ +|Offset| Identifier | Name | +|------|-----------------------|-------------------------------------------------------------| +| 0x00 | Hash_ID_Low | Pluto MSK FPGA Hash ID - Lower 32-bits | +| 0x04 | Hash_ID_High | Pluto MSK FPGA Hash ID - Upper 32-bits | +| 0x08 | MSK_Init | MSK Modem Initialization Control | +| 0x0C | MSK_Control | MSK Modem Control | +| 0x10 | MSK_Status | MSK Modem Status 0 | +| 0x14 | Tx_Bit_Count | MSK Modem Status 1 | +| 0x18 | Tx_Enable_Count | MSK Modem Status 2 | +| 0x1C | Fb_FreqWord | Bitrate NCO Frequency Control Word | +| 0x20 | TX_F1_FreqWord | Tx F1 NCO Frequency Control Word | +| 0x24 | TX_F2_FreqWord | Tx F2 NCO Frequency Control Word | +| 0x28 | RX_F1_FreqWord | Rx F1 NCO Frequency Control Word | +| 0x2C | RX_F2_FreqWord | Rx F2 NCO Frequency Control Word | +| 0x30 | LPF_Config_0 |PI Controller Configuration and Low-pass Filter Configuration| +| 0x34 | LPF_Config_1 | PI Controller Configuration Configuration Register 1 | +| 0x38 | Tx_Data_Width | Modem Tx Input Data Width | +| 0x3C | Rx_Data_Width | Modem Rx Output Data Width | +| 0x40 | PRBS_Control | PRBS Control 0 | +| 0x44 | PRBS_Initial_State | PRBS Control 1 | +| 0x48 | PRBS_Polynomial | PRBS Control 2 | +| 0x4C | PRBS_Error_Mask | PRBS Control 3 | +| 0x50 | PRBS_Bit_Count | PRBS Status 0 | +| 0x54 | PRBS_Error_Count | PRBS Status 1 | +| 0x58 | LPF_Accum_F1 | F1 PI Controller Accumulator | +| 0x5C | LPF_Accum_F2 | F2 PI Controller Accumulator | +| 0x60 | axis_xfer_count | MSK Modem Status 3 | +| 0x64 | Rx_Sample_Discard | Rx Sample Discard | +| 0x68 | LPF_Config_2 | PI Controller Configuration Configuration Register 2 | +| 0x6C | f1_nco_adjust | F1 NCO Frequency Adjust | +| 0x70 | f2_nco_adjust | F2 NCO Frequency Adjust | +| 0x74 | f1_error | F1 Error Value | +| 0x78 | f2_error | F2 Error Value | +| 0x7C | Tx_Sync_Ctrl | Transmitter Sync Control | +| 0x80 | Tx_Sync_Cnt | Transmitter Sync Duration | +| 0x84 | lowpass_ema_alpha1 | Exponential Moving Average Alpha | +| 0x88 | lowpass_ema_alpha2 | Exponential Moving Average Alpha | +| 0x8C | rx_power | Receive Power | +| 0x90 |tx_async_fifo_rd_wr_ptr| Tx async FIFO read and write pointers | +| 0x94 |rx_async_fifo_rd_wr_ptr| Rx async FIFO read and write pointers | +| 0x98 | rx_frame_sync_status | Frame Sync Status | + +### Hash_ID_Low register + +- Absolute Address: 0x0 +- Base Offset: 0x0 +- Size: 0x4 + +|Bits|Identifier|Access| Reset | Name | +|----|----------|------|----------|---------------------| +|31:0|hash_id_lo| r |0xAAAA5555|Hash ID Lower 32-bits| + +#### hash_id_lo field + +

Lower 32-bits of Pluto MSK FPGA Hash ID

+ +### Hash_ID_High register + +- Absolute Address: 0x4 +- Base Offset: 0x4 +- Size: 0x4 + +|Bits|Identifier|Access| Reset | Name | +|----|----------|------|----------|---------------------| +|31:0|hash_id_hi| r |0x5555AAAA|Hash ID Upper 32-bits| + +#### hash_id_hi field + +

Upper 32-bits of Pluto MSK FPGA Hash ID

+ +### MSK_Init register + +- Absolute Address: 0x8 +- Base Offset: 0x8 +- Size: 0x4 + +

Synchronous initialization of MSK Modem functions, does not affect configuration registers.

+ +|Bits|Identifier|Access|Reset| Name | +|----|----------|------|-----|-----------------| +| 0 | txrxinit | rw | 0x1 |Tx/Rx Init Enable| +| 1 | txinit | rw | 0x1 | Tx Init Enable | +| 2 | rxinit | rw | 0x1 | Rx Init Enable | + +#### txrxinit field + +

0 -> Normal modem operation

+

1 -> Initialize Tx and Rx

+ +#### txinit field + +

0 -> Normal Tx operation

+

1 -> Initialize Tx

+ +#### rxinit field + +

0 -> Normal Rx operation

+

1 -> Initialize Rx

+ +### MSK_Control register + +- Absolute Address: 0xC +- Base Offset: 0xC +- Size: 0x4 + +

MSK Modem Configuration and Control

+ +|Bits| Identifier |Access|Reset| Name | +|----|---------------------|------|-----|-----------------------------------------------| +| 0 | ptt | rw | 0x0 | Push-to-Talk Enable | +| 1 | loopback_ena | rw | 0x0 | Modem Digital Tx -> Rx Loopback Enable | +| 2 | rx_invert | rw | 0x0 | Rx Data Invert Enable | +| 3 | clear_counts | rw | 0x0 | Clear Status Counters | +| 4 |diff_encoder_loopback| rw | 0x0 |Differential Encoder -> Decoder Loopback Enable| + +#### ptt field + +

0 -> PTT Disabled +1 -> PTT Enabled

+ +#### loopback_ena field + +

0 -> Modem loopback disabled

+

1 -> Modem loopback enabled

+ +#### rx_invert field + +

0 -> Rx data normal +1 -> Rx data inverted

+ +#### clear_counts field + +

Clear Tx Bit Counter and Tx Enable Counter

+ +#### diff_encoder_loopback field + +

0 -> Differential Encoder -> Decoder loopback disabled

+

1 -> Differential Encoder -> Decoder loopback enabled

+ +### MSK_Status register + +- Absolute Address: 0x10 +- Base Offset: 0x10 +- Size: 0x4 + +

Modem status bits

+ +|Bits| Identifier |Access|Reset| Name | +|----|---------------|------|-----|-------------------------------------------| +| 0 |demod_sync_lock| r | 0x0 | Demodulator Sync Status | +| 1 | tx_enable | r | 0x0 |AD9363 DAC Interface Tx Enable Input Active| +| 2 | rx_enable | r | 0x0 |AD9363 ADC Interface Rx Enable Input Active| +| 3 | tx_axis_valid | r | 0x0 | Tx S_AXIS_VALID | + +#### demod_sync_lock field + +

Demodulator Sync Status - not currently implemented

+ +#### tx_enable field + +

1 -> Data to DAC Enabled

+

0 -> Data to DAC Disabled

+ +#### rx_enable field + +

1 -> Data from ADC Enabled

+

0 -> Data from ADC Disabled

+ +#### tx_axis_valid field + +

1 -> S_AXIS_VALID Enabled

+

0 -> S_AXIS_VALID Disabled

+ +### Tx_Bit_Count register + +- Absolute Address: 0x14 +- Base Offset: 0x14 +- Size: 0x4 + +

Modem status data

+ +|Bits|Identifier|Access|Reset| Name | +|----|----------|------|-----|------------| +|31:0| data | rw | 0x0 |Tx Bit Count| + +#### data field + +

Count of data requests made by modem

+

This register is write-to-capture.

+

To read data the following steps are required:

+

1 - Write any value to this register to capture read data

+

2 - Read the register

+ +### Tx_Enable_Count register + +- Absolute Address: 0x18 +- Base Offset: 0x18 +- Size: 0x4 + +

Modem status data

+ +|Bits|Identifier|Access|Reset| Name | +|----|----------|------|-----|---------------| +|31:0| data | rw | 0x0 |Tx Enable Count| + +#### data field + +

Number of clocks on which Tx Enable is active

+

This register is write-to-capture.

+

To read data the following steps are required:

+

1 - Write any value to this register to capture read data

+

2 - Read the register

+ +### Fb_FreqWord register + +- Absolute Address: 0x1C +- Base Offset: 0x1C +- Size: 0x4 + +

Set Modem Data Rate

+ +|Bits| Identifier|Access|Reset| Name | +|----|-----------|------|-----|----------------------| +|31:0|config_data| rw | 0x0 |Frequency Control Word| + +#### config_data field + +

Sets the center frequency of the NCO as FW = Fn * 2^32/Fs, +where Fn is the desired NCO frequency, and Fs is the NCO sample rate

+ +### TX_F1_FreqWord register + +- Absolute Address: 0x20 +- Base Offset: 0x20 +- Size: 0x4 + +

Set Modulator F1 Frequency

+ +|Bits| Identifier|Access|Reset| Name | +|----|-----------|------|-----|----------------------| +|31:0|config_data| rw | 0x0 |Frequency Control Word| + +#### config_data field + +

Sets the center frequency of the NCO as FW = Fn * 2^32/Fs, +where Fn is the desired NCO frequency, and Fs is the NCO sample rate

+ +### TX_F2_FreqWord register + +- Absolute Address: 0x24 +- Base Offset: 0x24 +- Size: 0x4 + +

Set Modulator F2 Frequency

+ +|Bits| Identifier|Access|Reset| Name | +|----|-----------|------|-----|----------------------| +|31:0|config_data| rw | 0x0 |Frequency Control Word| + +#### config_data field + +

Sets the center frequency of the NCO as FW = Fn * 2^32/Fs, +where Fn is the desired NCO frequency, and Fs is the NCO sample rate

+ +### RX_F1_FreqWord register + +- Absolute Address: 0x28 +- Base Offset: 0x28 +- Size: 0x4 + +

Set Demodulator F1 Frequency

+ +|Bits| Identifier|Access|Reset| Name | +|----|-----------|------|-----|----------------------| +|31:0|config_data| rw | 0x0 |Frequency Control Word| + +#### config_data field + +

Sets the center frequency of the NCO as FW = Fn * 2^32/Fs, +where Fn is the desired NCO frequency, and Fs is the NCO sample rate

+ +### RX_F2_FreqWord register + +- Absolute Address: 0x2C +- Base Offset: 0x2C +- Size: 0x4 + +

Set Demodulator F2 Frequency

+ +|Bits| Identifier|Access|Reset| Name | +|----|-----------|------|-----|----------------------| +|31:0|config_data| rw | 0x0 |Frequency Control Word| + +#### config_data field + +

Sets the center frequency of the NCO as FW = Fn * 2^32/Fs, +where Fn is the desired NCO frequency, and Fs is the NCO sample rate

+ +### LPF_Config_0 register + +- Absolute Address: 0x30 +- Base Offset: 0x30 +- Size: 0x4 + +

Configure PI controller and low-pass filter

+ +|Bits| Identifier |Access|Reset| Name | +|----|-------------|------|-----|--------------------------------------| +| 0 | lpf_freeze | rw | 0x0 |Freeze the accumulator's current value| +| 1 | lpf_zero | rw | 0x0 | Hold the PI Accumulator at zero | +| 7:2|prbs_reserved| rw | 0x0 | Reserved | +|31:8| lpf_alpha | rw | 0x0 | Lowpass IIR filter alpha | + +#### lpf_freeze field + +

0 -> Normal operation

+

1 -> Freeze current value

+ +#### lpf_zero field + +

0 -> Normal operation

+

1 -> Zero and hold accumulator

+ +#### lpf_alpha field + +

Value controls the filter rolloff

+ +### LPF_Config_1 register + +- Absolute Address: 0x34 +- Base Offset: 0x34 +- Size: 0x4 + +

Configures PI Controller I-gain and divisor

+ +| Bits|Identifier|Access|Reset| Name | +|-----|----------|------|-----|-----------------------| +| 23:0| i_gain | rw | 0x0 | Integral Gain Value | +|31:24| i_shift | rw | 0x0 |Integral Gain Bit Shift| + +#### i_gain field + +

Value m of 0-16,777,215 sets the integral multiplier

+ +#### i_shift field + +

Value n of 0-32 sets the integral divisor as 2^-n

+ +### Tx_Data_Width register + +- Absolute Address: 0x38 +- Base Offset: 0x38 +- Size: 0x4 + +

Set the parallel data width of the parallel-to-serial converter

+ +|Bits|Identifier|Access|Reset| Name | +|----|----------|------|-----|-----------------------------| +| 7:0|data_width| rw | 0x8 |Modem input/output data width| + +#### data_width field + +

Set the data width of the modem input/output

+ +### Rx_Data_Width register + +- Absolute Address: 0x3C +- Base Offset: 0x3C +- Size: 0x4 + +

Set the parallel data width of the serial-to-parallel converter

+ +|Bits|Identifier|Access|Reset| Name | +|----|----------|------|-----|-----------------------------| +| 7:0|data_width| rw | 0x8 |Modem input/output data width| + +#### data_width field + +

Set the data width of the modem input/output

+ +### PRBS_Control register + +- Absolute Address: 0x40 +- Base Offset: 0x40 +- Size: 0x4 + +

Configures operation of the PRBS Generator and Monitor

+ +| Bits| Identifier |Access|Reset| Name | +|-----|-------------------|------|-----|------------------------| +| 0 | prbs_sel | rw | 0x0 | PRBS Data Select | +| 1 | prbs_error_insert | w | 0x0 | PRBS Error Insert | +| 2 | prbs_clear | w | 0x0 | PRBS Clear Counters | +| 3 | prbs_manual_sync | w | 0x0 | PRBS Manual Sync | +| 15:4| prbs_reserved | rw | 0x0 | Reserved | +|31:16|prbs_sync_threshold| rw | 0x0 |PRBS Auto Sync Threshold| + +#### prbs_sel field + +

0 -> Select Normal Tx Data +1 -> Select PRBS Tx Data

+ +#### prbs_error_insert field + +

0 -> 1 : Insert bit error in Tx data (both Normal and PRBS)

+

1 -> 0 : Insert bit error in Tx data (both Normal and PRBS)

+ +#### prbs_clear field + +

0 -> 1 : Clear PRBS Counters

+

1 -> 0 : Clear PRBS Counters

+ +#### prbs_manual_sync field + +

0 -> 1 : Synchronize PRBS monitor

+

1 -> 0 : Synchronize PRBS monitor

+ +#### prbs_sync_threshold field + +

0 : Auto Sync Disabled

+

N > 0 : Auto sync after N errors

+ +### PRBS_Initial_State register + +- Absolute Address: 0x44 +- Base Offset: 0x44 +- Size: 0x4 + +

PRBS Initial State

+ +|Bits| Identifier|Access|Reset| Name | +|----|-----------|------|-----|---------| +|31:0|config_data| rw | 0x0 |PRBS Seed| + +#### config_data field + +

Sets the starting value of the PRBS generator

+ +### PRBS_Polynomial register + +- Absolute Address: 0x48 +- Base Offset: 0x48 +- Size: 0x4 + +

PRBS Polynomial

+ +|Bits| Identifier|Access|Reset| Name | +|----|-----------|------|-----|---------------| +|31:0|config_data| rw | 0x0 |PRBS Polynomial| + +#### config_data field + +

Bit positions set to '1' indicate polynomial feedback positions

+ +### PRBS_Error_Mask register + +- Absolute Address: 0x4C +- Base Offset: 0x4C +- Size: 0x4 + +

PRBS Error Mask

+ +|Bits| Identifier|Access|Reset| Name | +|----|-----------|------|-----|---------------| +|31:0|config_data| rw | 0x0 |PRBS Error Mask| + +#### config_data field + +

Bit positions set to '1' indicate bits that are inverted when a bit error is inserted

+ +### PRBS_Bit_Count register + +- Absolute Address: 0x50 +- Base Offset: 0x50 +- Size: 0x4 + +

PRBS Bits Received

+ +|Bits|Identifier|Access|Reset| Name | +|----|----------|------|-----|------------------| +|31:0| data | rw | 0x0 |PRBS Bits Received| + +#### data field + +

Number of bits received by the PRBS monitor since last +BER can be calculated as the ratio of received bits to errored-bits

+

This register is write-to-capture.

+

To read data the following steps are required:

+

1 - Write any value to this register to capture read data

+

2 - Read the register

+ +### PRBS_Error_Count register + +- Absolute Address: 0x54 +- Base Offset: 0x54 +- Size: 0x4 + +

PRBS Bit Errors

+ +|Bits|Identifier|Access|Reset| Name | +|----|----------|------|-----|---------------| +|31:0| data | rw | 0x0 |PRBS Bit Errors| + +#### data field + +

Number of errored-bits received by the PRBS monitor since last sync +BER can be calculated as the ratio of received bits to errored-bits

+

This register is write-to-capture.

+

To read data the following steps are required:

+

1 - Write any value to this register to capture read data

+

2 - Read the register

+ +### LPF_Accum_F1 register + +- Absolute Address: 0x58 +- Base Offset: 0x58 +- Size: 0x4 + +

Value of the F1 PI Controller Accumulator

+ +|Bits|Identifier|Access|Reset| Name | +|----|----------|------|-----|-------------------------------| +|31:0| data | rw | 0x0 |PI Controller Accumulator Value| + +#### data field + +

PI Controller Accumulator Value

+

This register is write-to-capture.

+

To read data the following steps are required:

+

1 - Write any value to this register to capture read data

+

2 - Read the register

+ +### LPF_Accum_F2 register + +- Absolute Address: 0x5C +- Base Offset: 0x5C +- Size: 0x4 + +

Value of the F2 PI Controller Accumulator

+ +|Bits|Identifier|Access|Reset| Name | +|----|----------|------|-----|-------------------------------| +|31:0| data | rw | 0x0 |PI Controller Accumulator Value| + +#### data field + +

PI Controller Accumulator Value

+

This register is write-to-capture.

+

To read data the following steps are required:

+

1 - Write any value to this register to capture read data

+

2 - Read the register

+ +### axis_xfer_count register + +- Absolute Address: 0x60 +- Base Offset: 0x60 +- Size: 0x4 + +

Modem status data

+ +|Bits|Identifier|Access|Reset| Name | +|----|----------|------|-----|----------------| +|31:0| data | rw | 0x0 |S_AXIS Transfers| + +#### data field + +

Number completed S_AXIS transfers

+

This register is write-to-capture.

+

To read data the following steps are required:

+

1 - Write any value to this register to capture read data

+

2 - Read the register

+ +### Rx_Sample_Discard register + +- Absolute Address: 0x64 +- Base Offset: 0x64 +- Size: 0x4 + +

Configure samples discard operation for demodulator

+ +|Bits| Identifier |Access|Reset| Name | +|----|-----------------|------|-----|---------------------------| +| 7:0|rx_sample_discard| rw | 0x0 | Rx Sample Discard Value | +|15:8| rx_nco_discard | rw | 0x0 |Rx NCO Sample Discard Value| + +#### rx_sample_discard field + +

Number of Rx samples to discard

+ +#### rx_nco_discard field + +

Number of NCO samples to discard

+ +### LPF_Config_2 register + +- Absolute Address: 0x68 +- Base Offset: 0x68 +- Size: 0x4 + +

Configures PI Controller I-gain and divisor

+ +| Bits|Identifier|Access|Reset| Name | +|-----|----------|------|-----|---------------------------| +| 23:0| p_gain | rw | 0x0 | Proportional Gain Value | +|31:24| p_shift | rw | 0x0 |Proportional Gain Bit Shift| + +#### p_gain field + +

Value m of 0-16,777,215 sets the proportional multiplier

+ +#### p_shift field + +

Value n of 0-32 sets the proportional divisor as 2^-n

+ +### f1_nco_adjust register + +- Absolute Address: 0x6C +- Base Offset: 0x6C +- Size: 0x4 + +

Status Register

+ +|Bits|Identifier|Access|Reset|Name| +|----|----------|------|-----|----| +|31:0| data | rw | 0x0 | — | + +#### data field + +

Frequency offet applied to the F1 NCO

+

This register is write-to-capture.

+

To read data the following steps are required:

+

1 - Write any value to this register to capture read data

+

2 - Read the register

+ +### f2_nco_adjust register + +- Absolute Address: 0x70 +- Base Offset: 0x70 +- Size: 0x4 + +

Status Register

+ +|Bits|Identifier|Access|Reset|Name| +|----|----------|------|-----|----| +|31:0| data | rw | 0x0 | — | + +#### data field + +

Frequency offet applied to the F2 NCO

+

This register is write-to-capture.

+

To read data the following steps are required:

+

1 - Write any value to this register to capture read data

+

2 - Read the register

+ +### f1_error register + +- Absolute Address: 0x74 +- Base Offset: 0x74 +- Size: 0x4 + +

Status Register

+ +|Bits|Identifier|Access|Reset|Name| +|----|----------|------|-----|----| +|31:0| data | rw | 0x0 | — | + +#### data field + +

Error value of the F1 Costas loop after each active bit period

+

This register is write-to-capture.

+

To read data the following steps are required:

+

1 - Write any value to this register to capture read data

+

2 - Read the register

+ +### f2_error register + +- Absolute Address: 0x78 +- Base Offset: 0x78 +- Size: 0x4 + +

Status Register

+ +|Bits|Identifier|Access|Reset|Name| +|----|----------|------|-----|----| +|31:0| data | rw | 0x0 | — | + +#### data field + +

Error value of the F2 Costas loop after each active bit period

+

This register is write-to-capture.

+

To read data the following steps are required:

+

1 - Write any value to this register to capture read data

+

2 - Read the register

+ +### Tx_Sync_Ctrl register + +- Absolute Address: 0x7C +- Base Offset: 0x7C +- Size: 0x4 + +

Provides control bits for generation of transmitter synchronization patterns

+ +|Bits| Identifier |Access|Reset| Name | +|----|-------------|------|-----|--------------| +| 0 | tx_sync_ena | rw | 0x0 |Tx Sync Enable| +| 1 |tx_sync_force| rw | 0x0 | Tx Sync Force| + +#### tx_sync_ena field + +

0 : Disable sync transmission

+

1 : Enable sync transmission when PTT is asserted

+ +#### tx_sync_force field + +

0 : Normal operation

+

1 : Continuously transmit synchronization pattern

+ +### Tx_Sync_Cnt register + +- Absolute Address: 0x80 +- Base Offset: 0x80 +- Size: 0x4 + +

Sets the duration of the synchronization tones when enabled

+ +|Bits| Identifier|Access|Reset| Name | +|----|-----------|------|-----|----------------| +|23:0|tx_sync_cnt| rw | 0x0 |Tx sync duration| + +#### tx_sync_cnt field + +

Value from 0x00_0000 to 0xFF_FFFF.

+

This value represents the number bit-times the synchronization signal should be sent after PTT is asserted.

+ +### lowpass_ema_alpha1 register + +- Absolute Address: 0x84 +- Base Offset: 0x84 +- Size: 0x4 + +

Sets the alpha for the EMA

+ +|Bits|Identifier|Access|Reset| Name | +|----|----------|------|-----|---------| +|17:0| alpha | rw | 0x0 |EMA alpha| + +#### alpha field + +

Value from 0x0_0000 to 0x3_FFFF represent the EMA alpha

+ +### lowpass_ema_alpha2 register + +- Absolute Address: 0x88 +- Base Offset: 0x88 +- Size: 0x4 + +

Sets the alpha for the EMA

+ +|Bits|Identifier|Access|Reset| Name | +|----|----------|------|-----|---------| +|17:0| alpha | rw | 0x0 |EMA alpha| + +#### alpha field + +

Value from 0x0_0000 to 0x3_FFFF represent the EMA alpha

+ +### rx_power register + +- Absolute Address: 0x8C +- Base Offset: 0x8C +- Size: 0x4 + +

Receive power computed from I/Q samples

+ +|Bits|Identifier|Access|Reset| Name | +|----|----------|------|-----|-------------| +|22:0| data | rw | 0x0 |Receive Power| + +#### data field + +

Value that represent the RMS power of the incoming signal (I-channel)

+

This register is write-to-capture. To read data the following steps are required:

+
    +
  1. Write any value to this register to capture read data +
  2. Read the register +
+ +### tx_async_fifo_rd_wr_ptr register + +- Absolute Address: 0x90 +- Base Offset: 0x90 +- Size: 0x4 + +

Tx async FIFO read and write pointers

+ +|Bits|Identifier|Access|Reset|Name| +|----|----------|------|-----|----| +|31:0| data | rw | 0x0 | — | + +#### data field + +

Read and Write Pointers

+

+Bits 31:16 - write pointer (12-bits) +Bits 15:00 - read pointer (12-bits)

+

This register is write-to-capture. To read data the following steps are required:

+
    +
  1. Write any value to this register to capture read data +
  2. Read the register +
+ +### rx_async_fifo_rd_wr_ptr register + +- Absolute Address: 0x94 +- Base Offset: 0x94 +- Size: 0x4 + +

Rx async FIFO read and write pointers

+ +|Bits|Identifier|Access|Reset|Name| +|----|----------|------|-----|----| +|31:0| data | rw | 0x0 | — | + +#### data field + +

Read and Write Pointers

+

+Bits 31:16 - write pointer (12-bits) +Bits 15:00 - read pointer (12-bits)

+

This register is write-to-capture. To read data the following steps are required:

+
    +
  1. Write any value to this register to capture read data +
  2. Read the register +
+ +### rx_frame_sync_status register + +- Absolute Address: 0x98 +- Base Offset: 0x98 +- Size: 0x4 + +| Bits| Identifier | Access|Reset| Name | +|-----|---------------------|-------|-----|---------------------| +| 0 | frame_sync_locked | r | 0x0 | Frame Sync Lock | +| 1 |frame_buffer_overflow|r, rclr| 0x0 |Frame Buffer Overflow| +| 25:2| frames_received | rw | 0x0 | Frames Received | +|31:26| frame_sync_errors | rw | 0x0 | Frames Sync Errors | + +#### frame_sync_locked field + +

0 - Frame sync not locked +1 - Frame sync locked

+ +#### frame_buffer_overflow field + +

0 - Normal operation +1 - Buffer overflow

+ +#### frames_received field + +

Count of frames received since last read. Value is 0x00_0000 to 0xFF_FFFF

+ +#### frame_sync_errors field + +

Count of frame sync errors since last read. Value is 0 to 63. This field will saturate at 63 if more than 63 occur.

diff --git a/rdl/outputs/docs/msk_top_regs.pdf b/rdl/outputs/docs/msk_top_regs.pdf new file mode 100644 index 0000000..9821309 Binary files /dev/null and b/rdl/outputs/docs/msk_top_regs.pdf differ diff --git a/rdl/outputs/python/msk_top_regs/__init__.py b/rdl/outputs/python/msk_top_regs/__init__.py new file mode 100644 index 0000000..2ae2839 --- /dev/null +++ b/rdl/outputs/python/msk_top_regs/__init__.py @@ -0,0 +1 @@ +pass diff --git a/rdl/outputs/python/msk_top_regs/example.py b/rdl/outputs/python/msk_top_regs/example.py new file mode 100644 index 0000000..80db74d --- /dev/null +++ b/rdl/outputs/python/msk_top_regs/example.py @@ -0,0 +1,13 @@ + +from .lib import AsyncCallbackSet + +from .reg_model.msk_top_regs import msk_top_regs_cls +from .sim.msk_top_regs import msk_top_regs_simulator_cls + +if __name__ == '__main__': + + sim = msk_top_regs_simulator_cls(address=0) + + # create an instance of the class + reg_model = msk_top_regs_cls(callbacks=AsyncCallbackSet(read_callback=sim.read, + write_callback=sim.write)) \ No newline at end of file diff --git a/rdl/outputs/python/msk_top_regs/lib/__init__.py b/rdl/outputs/python/msk_top_regs/lib/__init__.py new file mode 100644 index 0000000..fc1b286 --- /dev/null +++ b/rdl/outputs/python/msk_top_regs/lib/__init__.py @@ -0,0 +1,114 @@ +""" +peakrdl-python is a tool to generate Python Register Access Layer (RAL) from SystemRDL +Copyright (C) 2021 - 2023 + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +This package is intended to distributed as part of automatically generated code by the PeakRDL +Python tool. It provides a set of classes used by the autogenerated code +""" + +from .callbacks import ReadCallback +from .callbacks import ReadBlockCallback +from .callbacks import WriteCallback +from .callbacks import WriteBlockCallback +from .callbacks import NormalCallbackSet, NormalCallbackSetLegacy +from .callbacks import AsyncCallbackSet, AsyncCallbackSetLegacy +from .callbacks import CallbackSet + +from .base import AddressMap +from .base import RegFile +from .base import AddressMapArray +from .base import RegFileArray + +from .base import AsyncAddressMap +from .base import AsyncRegFile +from .base import AsyncAddressMapArray +from .base import AsyncRegFileArray + +from .register_and_field import Reg +from .register_and_field import RegArray +from .register_and_field import RegisterWriteVerifyError + +from .register_and_field import RegReadOnly +from .register_and_field import RegWriteOnly +from .register_and_field import RegReadWrite +from .register_and_field import WritableRegister +from .register_and_field import ReadableRegister + +from .register_and_field import RegReadOnlyArray +from .register_and_field import RegWriteOnlyArray +from .register_and_field import RegReadWriteArray +from .register_and_field import ReadableRegisterArray +from .register_and_field import WriteableRegisterArray + +from .async_register_and_field import AsyncReg +from .async_register_and_field import AsyncRegArray +from .async_register_and_field import RegAsyncReadOnly +from .async_register_and_field import RegAsyncWriteOnly +from .async_register_and_field import RegAsyncReadWrite +from .async_register_and_field import ReadableAsyncRegister +from .async_register_and_field import WritableAsyncRegister +from .async_register_and_field import RegAsyncReadOnlyArray +from .async_register_and_field import RegAsyncWriteOnlyArray +from .async_register_and_field import RegAsyncReadWriteArray +from .async_register_and_field import ReadableAsyncRegisterArray +from .async_register_and_field import WriteableAsyncRegisterArray + +from .base_field import FieldSizeProps +from .base_field import FieldMiscProps +from .register_and_field import FieldReadOnly +from .register_and_field import FieldWriteOnly +from .register_and_field import FieldReadWrite +from .base_field import Field +from .register_and_field import FieldEnumReadOnly +from .register_and_field import FieldEnumWriteOnly +from .register_and_field import FieldEnumReadWrite +from .base_field import FieldEnum +from .field_encoding import SystemRDLEnum, SystemRDLEnumEntry +from .field_encoding import RegisterFieldJSONEncoder + +from .async_register_and_field import FieldAsyncReadOnly +from .async_register_and_field import FieldAsyncWriteOnly +from .async_register_and_field import FieldAsyncReadWrite +from .async_register_and_field import FieldEnumAsyncReadOnly +from .async_register_and_field import FieldEnumAsyncWriteOnly +from .async_register_and_field import FieldEnumAsyncReadWrite + +from .memory import MemoryReadOnly, MemoryReadOnlyLegacy +from .memory import MemoryWriteOnly, MemoryWriteOnlyLegacy +from .memory import MemoryReadWrite, MemoryReadWriteLegacy +from .memory import MemoryReadOnlyArray +from .memory import MemoryWriteOnlyArray +from .memory import MemoryReadWriteArray +from .async_memory import MemoryAsyncReadOnly, MemoryAsyncReadOnlyLegacy +from .async_memory import MemoryAsyncWriteOnly, MemoryAsyncWriteOnlyLegacy +from .async_memory import MemoryAsyncReadWrite, MemoryAsyncReadWriteLegacy +from .async_memory import MemoryAsyncReadOnlyArray +from .async_memory import MemoryAsyncWriteOnlyArray +from .async_memory import MemoryAsyncReadWriteArray +from .memory import ReadableMemory, ReadableMemoryLegacy +from .memory import WritableMemory, WritableMemoryLegacy +from .memory import Memory +from .async_memory import ReadableAsyncMemory, ReadableAsyncMemoryLegacy +from .async_memory import WritableAsyncMemory, WritableAsyncMemoryLegacy +from .async_memory import AsyncMemory +from .memory import MemoryArray +from .async_memory import AsyncMemoryArray + +from .utility_functions import get_array_typecode +from .utility_functions import UnsupportedWidthError +from .base import Node +from .base import Base +from .base import UDPStruct diff --git a/rdl/outputs/python/msk_top_regs/lib/async_memory.py b/rdl/outputs/python/msk_top_regs/lib/async_memory.py new file mode 100644 index 0000000..427a3cb --- /dev/null +++ b/rdl/outputs/python/msk_top_regs/lib/async_memory.py @@ -0,0 +1,626 @@ +""" +peakrdl-python is a tool to generate Python Register Access Layer (RAL) from SystemRDL +Copyright (C) 2021 - 2023 + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +This module is intended to distributed as part of automatically generated code by the +peakrdl-python tool. It provides a set of classes used by the autogenerated code to represent +memories +""" +from array import array as Array +from typing import Union, TYPE_CHECKING +from abc import ABC, abstractmethod +from collections.abc import Iterator +import sys + +from .base import AsyncAddressMap, NodeArray +from .memory import BaseMemory + +from .callbacks import AsyncCallbackSet, AsyncCallbackSetLegacy + +# same bit of code exists in base so flags as duplicate +# pylint: disable=duplicate-code +if sys.version_info >= (3, 10): + # type guarding was introduced in python 3.10 + from typing import TypeGuard +else: + from typing_extensions import TypeGuard +# pylint: enable=duplicate-code + + +if TYPE_CHECKING: + from .async_register_and_field import AsyncReg, AsyncRegArray + from .async_register_and_field import ReadableAsyncRegister, WritableAsyncRegister + from .async_register_and_field import ReadableAsyncRegisterArray, WriteableAsyncRegisterArray +# pylint: disable=duplicate-code + + +class AsyncMemory(BaseMemory, ABC): + """ + base class of non_async memory wrappers + + Note: + It is not expected that this class will be instantiated under normal + circumstances however, it is useful for type checking + """ + __slots__: list[str] = [] + + # pylint: disable=too-many-arguments + def __init__(self, *, + address: int, + width: int, + accesswidth: int, + entries: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap, 'AsyncMemoryArray']): + """ + Initialise the class + + Args: + address: address of the register + width: width of the register in bits + logger_handle: name to be used logging messages associate with thisobject + """ + if not isinstance(parent, (AsyncAddressMap, + MemoryAsyncWriteOnlyArray, MemoryAsyncReadOnlyArray, + MemoryAsyncReadWriteArray)): + raise TypeError(f'parent should be either AddressMap or Memory Array got ' + f'{type(parent)}') + super().__init__(address=address, + logger_handle=logger_handle, + inst_name=inst_name, + width=width, + accesswidth=accesswidth, + entries=entries, + parent=parent) + + @abstractmethod + def get_registers(self, unroll: bool = False) -> \ + Iterator[Union['AsyncReg', 'AsyncRegArray']]: + """ + generator that produces all the readable_registers of this node + + Args: + unroll: Whether to unroll child array or not + """ + + +class _MemoryAsyncReadOnly(AsyncMemory, ABC): + """ + base class of memory wrappers + + Note: + It is not expected that this class will be instantiated under normal + circumstances however, it is useful for type checking + """ + + __slots__: list[str] = [] + + # pylint: disable=too-many-arguments + def __init__(self, *, + address: int, + width: int, + accesswidth: int, + entries: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap, 'AsyncMemoryArray']): + + if not isinstance(parent, (AsyncAddressMap, MemoryAsyncWriteOnlyArray, + MemoryAsyncReadOnlyArray, MemoryAsyncReadWriteArray)): + raise TypeError('parent should be either AddressMap or Memory Array ' + f'got {type(parent)}') + + if not isinstance(parent._callbacks, (AsyncCallbackSet, AsyncCallbackSetLegacy)): + raise TypeError(f'callback set type is wrong, got {type(parent._callbacks)}') + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + entries=entries, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # pylint: enable=too-many-arguments + @property + def _callbacks(self) -> Union[AsyncCallbackSet, AsyncCallbackSetLegacy]: + # pylint: disable=protected-access + if self.parent is None: + raise RuntimeError('Parent must be set') + + if isinstance(self.parent._callbacks, (AsyncCallbackSet, AsyncCallbackSetLegacy)): + return self.parent._callbacks + + raise TypeError(f'unhandled parent callback type: {type(self.parent._callbacks)}') + + async def _read(self, start_entry: int, number_entries: int) -> list[int]: + """ + Read from the memory + + Args: + start_entry: index in the memory to start from, this is not the address + number_entries: number of entries to read + + Returns: data read from memory + + """ + + if not isinstance(start_entry, int): + raise TypeError(f'start_entry should be an int got {type(start_entry)}') + + if not isinstance(number_entries, int): + raise TypeError(f'number_entries should be an int got {type(number_entries)}') + + if start_entry not in range(0, self.entries): + raise ValueError(f'entry must be in range 0 to {self.entries - 1:d} ' + f'but got {start_entry:d}') + + if number_entries not in range(0, self.entries - start_entry + 1): + raise ValueError(f'number_entries must be in range 0 to' + f' {self.entries - start_entry:d} but got {number_entries:d}') + + read_block_callback = self._callbacks.read_block_callback + read_callback = self._callbacks.read_callback + + if read_block_callback is not None: + addr = self.address_lookup(entry=start_entry) + data_read = \ + await read_block_callback(addr=addr, + width=self.width, + accesswidth=self.width, + length=number_entries) + + if isinstance(self._callbacks, AsyncCallbackSet): + if not isinstance(data_read, list): + raise TypeError('The read block callback is expected to return an List') + return data_read + + if isinstance(self._callbacks, AsyncCallbackSetLegacy): + if not isinstance(data_read, Array): + raise TypeError('The read block callback is expected to return an array') + return data_read.tolist() + + raise RuntimeError(f'There is no usable callback block callback:{read_block_callback}') + + if read_callback is not None: + # there is not read_block_callback defined so we must used individual read + data_read = [0 for _ in range(number_entries)] + + for entry in range(number_entries): + entry_address = self.address_lookup(entry=start_entry+entry) + + data_entry = await read_callback(addr=entry_address, + width=self.width, + accesswidth=self.width) + + data_read[entry] = data_entry + + return data_read + + raise RuntimeError(f'There is no usable callback, ' + f'block callback:{read_block_callback}, ' + f'normal callback:{read_callback}') + + async def _read_legacy(self, start_entry: int, number_entries: int) -> Array: + """ + Read from the memory + + Args: + start_entry: index in the memory to start from, this is not the address + number_entries: number of entries to read + + Returns: data read from memory + + """ + + if not isinstance(start_entry, int): + raise TypeError(f'start_entry should be an int got {type(start_entry)}') + + if not isinstance(number_entries, int): + raise TypeError(f'number_entries should be an int got {type(number_entries)}') + + if start_entry not in range(0, self.entries): + raise ValueError(f'entry must be in range 0 to {self.entries - 1:d} ' + f'but got {start_entry:d}') + + if number_entries not in range(0, self.entries - start_entry + 1): + raise ValueError(f'number_entries must be in range 0 to' + f' {self.entries - start_entry:d} but got {number_entries:d}') + + read_block_callback = self._callbacks.read_block_callback + read_callback = self._callbacks.read_callback + + if read_block_callback is not None: + addr = self.address_lookup(entry=start_entry) + data_read = \ + await read_block_callback(addr=addr, + width=self.width, + accesswidth=self.width, + length=number_entries) + + if isinstance(self._callbacks, AsyncCallbackSet): + if not isinstance(data_read, list): + raise TypeError('The read block callback is expected to return an List') + return Array(self.array_typecode, data_read) + + if isinstance(self._callbacks, AsyncCallbackSetLegacy): + if not isinstance(data_read, Array): + raise TypeError('The read block callback is expected to return an array') + return data_read + + raise RuntimeError(f'There is no usable callback block callback:{read_block_callback}') + + if read_callback is not None: + # there is not read_block_callback defined so we must used individual read + data_read_block = Array(self.array_typecode, [0 for _ in range(number_entries)]) + + for entry in range(number_entries): + entry_address = self.address_lookup(entry=start_entry + entry) + data_entry = await read_callback(addr=entry_address, + width=self.width, + accesswidth=self.width) + + data_read_block[entry] = data_entry + + return data_read_block + + raise RuntimeError(f'There is no usable callback, ' + f'block callback:{read_block_callback}, ' + f'normal callback:{read_callback}') + + def get_readable_registers(self, unroll: bool = False) -> \ + Iterator[Union['ReadableAsyncRegister', 'ReadableAsyncRegisterArray']]: + """ + generator that produces all the readable_registers of this node + + Args: + unroll: Whether to unroll child array or not + """ + def is_readable(item: Union['AsyncReg', 'AsyncRegArray']) -> \ + TypeGuard[Union['ReadableAsyncRegister', 'ReadableAsyncRegisterArray']]: + # pylint: disable-next=protected-access + return item._is_readable + + return filter(is_readable, self.get_registers(unroll=unroll)) + + +class MemoryAsyncReadOnly(_MemoryAsyncReadOnly, ABC): + """ + base class of memory wrappers + + Note: + It is not expected that this class will be instantiated under normal + circumstances however, it is useful for type checking + """ + __slots__: list[str] = [] + + async def read(self, start_entry: int, number_entries: int) -> list[int]: + """ + Read from the memory + + Args: + start_entry: index in the memory to start from, this is not the address + number_entries: number of entries to read + + Returns: data read from memory + + """ + return await self._read(start_entry=start_entry, number_entries=number_entries) + + +class MemoryAsyncReadOnlyLegacy(_MemoryAsyncReadOnly, ABC): + """ + base class of memory wrappers + + Note: + It is not expected that this class will be instantiated under normal + circumstances however, it is useful for type checking + """ + __slots__: list[str] = [] + + async def read(self, start_entry: int, number_entries: int) -> Array: + """ + Read from the memory + + Args: + start_entry: index in the memory to start from, this is not the address + number_entries: number of entries to read + + Returns: data read from memory + + """ + return await self._read_legacy(start_entry=start_entry, number_entries=number_entries) + + +class _MemoryAsyncWriteOnly(AsyncMemory, ABC): + """ + base class of memory wrappers + + Note: + It is not expected that this class will be instantiated under normal + circumstances however, it is useful for type checking + """ + + __slots__: list[str] = [] + + # pylint: disable=too-many-arguments + def __init__(self, *, + address: int, + width: int, + accesswidth: int, + entries: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap, 'AsyncMemoryArray']): + + if not isinstance(parent, (AsyncAddressMap, MemoryAsyncWriteOnlyArray, + MemoryAsyncReadOnlyArray, MemoryAsyncReadWriteArray)): + raise TypeError('parent should be either AddressMap or Memory Array ' + f'got {type(parent)}') + if not isinstance(parent._callbacks, (AsyncCallbackSet, AsyncCallbackSetLegacy)): + raise TypeError(f'callback set type is wrong, got {type(parent._callbacks)}') + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + entries=entries, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # pylint: enable=too-many-arguments + @property + def _callbacks(self) -> Union[AsyncCallbackSet, AsyncCallbackSetLegacy]: + # pylint: disable=protected-access + if self.parent is None: + raise RuntimeError('Parent must be set') + + if isinstance(self.parent._callbacks, (AsyncCallbackSet, AsyncCallbackSetLegacy)): + return self.parent._callbacks + + raise TypeError(f'unhandled parent callback type: {type(self.parent._callbacks)}') + + async def _write(self, start_entry: int, data: Union[Array, list[int]]) -> None: + """ + Asynchronously write data to memory + + Args: + start_entry: index in the memory to start from, this is not the address + data: data to write + + Returns: None + + """ + # pylint:disable=too-many-branches + if not isinstance(start_entry, int): + raise TypeError(f'start_entry should be an int got {type(start_entry)}') + + if start_entry not in range(0, self.entries): + raise ValueError(f'entry must be in range 0 to {self.entries - 1:d} ' + f'but got {start_entry:d}') + + if not isinstance(data, (list, Array)): + raise TypeError(f'data should be an array.array got {type(data)}') + + if len(data) not in range(0, self.entries - start_entry + 1): + raise ValueError(f'data length must be in range 0 to {self.entries - start_entry:d} ' + f'but got {len(data):d}') + + if self._callbacks.write_block_callback is not None: + + addr = self.address_lookup(entry=start_entry) + if isinstance(self._callbacks, AsyncCallbackSet): + if isinstance(data, Array): + await self._callbacks.write_block_callback(addr=addr, + width=self.width, + accesswidth=self.width, + data=data.tolist()) + else: + await self._callbacks.write_block_callback(addr=addr, + width=self.width, + accesswidth=self.width, + data=data) + if isinstance(self._callbacks, AsyncCallbackSetLegacy): + if isinstance(data, list): + # need to convert the data to an array before calling + await self._callbacks.write_block_callback( + addr=addr, + width=self.width, + accesswidth=self.width, + data=Array(self.array_typecode, data)) + else: + await self._callbacks.write_block_callback(addr=addr, + width=self.width, + accesswidth=self.width, + data=data) + + elif self._callbacks.write_callback is not None: + # there is not write_block_callback defined so we must used individual write + for entry_index, entry_data in enumerate(data): + entry_address = self.address_lookup(entry=start_entry+entry_index) + await self._callbacks.write_callback(addr=entry_address, + width=self.width, + accesswidth=self.width, + data=entry_data) + + else: + raise RuntimeError('No suitable callback') + + def get_writable_registers(self, unroll: bool = False) -> \ + Iterator[Union['WritableAsyncRegister', 'WriteableAsyncRegisterArray']]: + """ + generator that produces all the readable_registers of this node + + Args: + unroll: Whether to unroll child array or not + """ + def is_writable(item: Union['AsyncReg', 'AsyncRegArray']) -> \ + TypeGuard[Union['WritableAsyncRegister', 'WriteableAsyncRegisterArray']]: + # pylint: disable-next=protected-access + return item._is_writeable + + return filter(is_writable, self.get_registers(unroll=unroll)) + + +class MemoryAsyncWriteOnly(_MemoryAsyncWriteOnly, ABC): + """ + base class of memory wrappers + + Note: + It is not expected that this class will be instantiated under normal + circumstances however, it is useful for type checking + """ + __slots__: list[str] = [] + + async def write(self, start_entry: int, data: list[int]) -> None: + """ + Asynchronously write data to memory + + Args: + start_entry: index in the memory to start from, this is not the address + data: data to write + + Returns: None + + """ + if not isinstance(data, list): + raise TypeError(f'data should be an List got {type(data)}') + return await self._write(start_entry=start_entry, data=data) + + +class MemoryAsyncWriteOnlyLegacy(_MemoryAsyncWriteOnly, ABC): + """ + base class of memory wrappers + + Note: + It is not expected that this class will be instantiated under normal + circumstances however, it is useful for type checking + """ + __slots__: list[str] = [] + + async def write(self, start_entry: int, data: Array) -> None: + """ + Asynchronously write data to memory + + Args: + start_entry: index in the memory to start from, this is not the address + data: data to write + + Returns: None + + """ + if not isinstance(data, Array): + raise TypeError(f'data should be an Array {type(data)}') + return await self._write(start_entry=start_entry, data=data) + + +class MemoryAsyncReadWrite(MemoryAsyncReadOnly, MemoryAsyncWriteOnly, ABC): + """ + base class of memory wrappers + + Note: + It is not expected that this class will be instantiated under normal + circumstances however, it is useful for type checking + """ + + __slots__: list[str] = [] + + +class MemoryAsyncReadWriteLegacy(MemoryAsyncReadOnlyLegacy, MemoryAsyncWriteOnlyLegacy, ABC): + """ + base class of memory wrappers + + Note: + It is not expected that this class will be instantiated under normal + circumstances however, it is useful for type checking + """ + + __slots__: list[str] = [] + + +class MemoryAsyncReadOnlyArray(NodeArray, ABC): + """ + base class for a array of asynchronous read only memories + """ + __slots__: list[str] = [] + + # pylint: disable-next=too-many-arguments + def __init__(self, *, + logger_handle: str, inst_name: str, + parent: AsyncAddressMap, + address: int, + stride: int, + dimensions: tuple[int, ...]): + + if not isinstance(parent, AsyncAddressMap): + raise TypeError(f'parent should be either AsyncAddressMap got {type(parent)}') + + super().__init__(logger_handle=logger_handle, inst_name=inst_name, + parent=parent, address=address, + stride=stride, dimensions=dimensions) + + +class MemoryAsyncWriteOnlyArray(NodeArray, ABC): + """ + base class for a array of asynchronous write only memories + """ + __slots__: list[str] = [] + + # pylint: disable-next=too-many-arguments + def __init__(self, *, + logger_handle: str, inst_name: str, + parent: AsyncAddressMap, + address: int, + stride: int, + dimensions: tuple[int, ...]): + + if not isinstance(parent, AsyncAddressMap): + raise TypeError(f'parent should be either AsyncAddressMap got {type(parent)}') + + super().__init__(logger_handle=logger_handle, inst_name=inst_name, + parent=parent, address=address, + stride=stride, dimensions=dimensions) + + +class MemoryAsyncReadWriteArray(MemoryAsyncReadOnlyArray, MemoryAsyncWriteOnlyArray, ABC): + """ + base class for a array of asynchronous read and write memories + """ + __slots__: list[str] = [] + + # pylint: disable-next=too-many-arguments + def __init__(self, *, + logger_handle: str, inst_name: str, + parent: AsyncAddressMap, + address: int, + stride: int, + dimensions: tuple[int, ...]): + + if not isinstance(parent, AsyncAddressMap): + raise TypeError(f'parent should be either AsyncAddressMap got {type(parent)}') + + super().__init__(logger_handle=logger_handle, inst_name=inst_name, + parent=parent, address=address, + stride=stride, dimensions=dimensions) + + +ReadableAsyncMemory = Union[MemoryAsyncReadOnly, MemoryAsyncReadWrite] +WritableAsyncMemory = Union[MemoryAsyncWriteOnly, MemoryAsyncReadWrite] +ReadableAsyncMemoryLegacy = Union[MemoryAsyncReadOnlyLegacy, MemoryAsyncReadWriteLegacy] +WritableAsyncMemoryLegacy = Union[MemoryAsyncWriteOnlyLegacy, MemoryAsyncReadWriteLegacy] +AsyncMemoryArray = Union[MemoryAsyncReadOnlyArray, MemoryAsyncWriteOnlyArray, + MemoryAsyncReadWriteArray] diff --git a/rdl/outputs/python/msk_top_regs/lib/async_register_and_field.py b/rdl/outputs/python/msk_top_regs/lib/async_register_and_field.py new file mode 100644 index 0000000..cf5bed3 --- /dev/null +++ b/rdl/outputs/python/msk_top_regs/lib/async_register_and_field.py @@ -0,0 +1,1230 @@ +""" +peakrdl-python is a tool to generate Python Register Access Layer (RAL) from SystemRDL +Copyright (C) 2021 - 2023 + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +This module is intended to distributed as part of automatically generated code by the +peakrdl-python tool. It provides a set of classes used by the autogenerated code to represent +asynchronous registers and fields +""" +from enum import Enum +from typing import Union, Optional, TypeVar, cast +from collections.abc import AsyncGenerator, Iterator +from abc import ABC, abstractmethod +from contextlib import asynccontextmanager +from array import array as Array +import sys +from warnings import warn + +from .utility_functions import get_array_typecode +from .base import AsyncAddressMap, AsyncRegFile +from .async_memory import MemoryAsyncReadOnly, MemoryAsyncWriteOnly, MemoryAsyncReadWrite, \ + AsyncMemory, ReadableAsyncMemory, WritableAsyncMemory +from .async_memory import MemoryAsyncReadOnlyLegacy, MemoryAsyncWriteOnlyLegacy, \ + MemoryAsyncReadWriteLegacy +from .async_memory import ReadableAsyncMemoryLegacy, WritableAsyncMemoryLegacy +from .callbacks import AsyncCallbackSet, AsyncCallbackSetLegacy +from .base_register import BaseReg, BaseRegArray, RegisterWriteVerifyError +from .base_field import FieldEnum, FieldSizeProps, FieldMiscProps, \ + _FieldReadOnlyFramework, _FieldWriteOnlyFramework, FieldType + +# pylint: disable=duplicate-code +if sys.version_info >= (3, 11): + from typing import Self +else: + from typing_extensions import Self +# pylint: enable=duplicate-code + +# pylint: disable=duplicate-code +if sys.version_info >= (3, 10): + # type guarding was introduced in python 3.10 + from typing import TypeGuard +else: + from typing_extensions import TypeGuard +# pylint: enable=duplicate-code + +# pylint: disable=redefined-slots-in-subclass,too-many-lines + + +class AsyncReg(BaseReg, ABC): + """ + base class of async register wrappers + + Note: + It is not expected that this class will be instantiated under normal + circumstances however, it is useful for type checking + """ + + __slots__: list[str] = [] + + # pylint: disable=too-many-arguments,duplicate-code + def __init__(self, *, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap, AsyncRegFile, AsyncMemory, 'AsyncRegArray']): + + if not isinstance(parent, (AsyncAddressMap, AsyncRegFile, + MemoryAsyncReadOnly, MemoryAsyncWriteOnly, + MemoryAsyncReadWrite, AsyncRegArray, MemoryAsyncReadOnlyLegacy, + MemoryAsyncWriteOnlyLegacy, + MemoryAsyncReadWriteLegacy)): + raise TypeError(f'bad parent type got: {type(parent)}') + + if not isinstance(parent._callbacks, (AsyncCallbackSet, AsyncCallbackSetLegacy)): + raise TypeError(f'callback set type is wrong, got {type(parent._callbacks)}') + + super().__init__(address=address, width=width, accesswidth=accesswidth, + logger_handle=logger_handle, inst_name=inst_name, parent=parent) + + @property + def _callbacks(self) -> Union[AsyncCallbackSet, AsyncCallbackSetLegacy]: + # pylint: disable=protected-access + if self.parent is None: + raise RuntimeError('Parent must be set') + + if isinstance(self.parent._callbacks, (AsyncCallbackSet, AsyncCallbackSetLegacy)): + return self.parent._callbacks + + raise TypeError(f'unhandled parent callback type: {type(self.parent._callbacks)}') + + @property + @abstractmethod + def fields(self) -> \ + Iterator[Union['FieldAsyncReadOnly', 'FieldAsyncWriteOnly', 'FieldAsyncReadWrite']]: + """ + generator that produces has all the fields within the register + """ + + +class RegAsyncReadOnly(AsyncReg, ABC): + """ + class for an async read only register + + Args: + address: address of the register + width: width of the register in bits + accesswidth: minimum access width of the register in bits + logger_handle: name to be used logging messages associate with this + object + + """ + + __slots__: list[str] = ['__in_context_manager', '__register_state'] + + # pylint: disable=too-many-arguments, duplicate-code + def __init__(self, *, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap, AsyncRegFile, ReadableAsyncMemory, + ReadableAsyncMemoryLegacy]): + + super().__init__(address=address, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent, width=width, accesswidth=accesswidth) + + self.__in_context_manager: bool = False + self.__register_state: int = 0 + # pylint: enable=too-many-arguments, duplicate-code + + @asynccontextmanager + async def single_read(self) -> AsyncGenerator[Self]: + """ + Context manager to allow multiple field accesses to be performed with a single + read of the register + """ + self.__register_state = await self.read() + # pylint: disable=duplicate-code + self.__in_context_manager = True + # this try/finally is needed to make sure that in the event of an exception + # the state flags are not left incorrectly set + try: + yield self + finally: + self.__in_context_manager = False + + async def read(self) -> int: + """Asynchronously read value from the register + + Returns: + The value from register + + """ + # pylint: disable=duplicate-code + if self.__in_context_manager: + return self.__register_state + + read_block_callback = self._callbacks.read_block_callback + read_callback = self._callbacks.read_callback + # pylint: enable=duplicate-code + + if read_callback is not None: + + return await read_callback(addr=self.address, + width=self.width, + accesswidth=self.accesswidth) + + if read_block_callback is not None: + array_read_result = \ + await read_block_callback(addr=self.address, + width=self.width, + accesswidth=self.accesswidth, + length=1) + return array_read_result[0] + + raise RuntimeError('This function does not have a useable callback') + + @property + def readable_fields(self) -> Iterator[Union['FieldAsyncReadOnly', 'FieldAsyncReadWrite']]: + """ + generator that produces has all the readable fields within the register + """ + def is_readable(field: Union['FieldAsyncReadOnly', + 'FieldAsyncWriteOnly', + 'FieldAsyncReadWrite']) -> \ + TypeGuard[Union['FieldAsyncReadOnly', 'FieldAsyncReadWrite']]: + return isinstance(field, (FieldAsyncReadOnly, FieldAsyncReadWrite)) + + return filter(is_readable, self.fields) + + async def read_fields(self) -> dict['str', Union[bool, Enum, int]]: + """ + asynchronously read the register and return a dictionary of the field values + """ + return_dict: dict['str', Union[bool, Enum, int]] = {} + async with self.single_read() as reg: + for field in reg.readable_fields: + return_dict[field.inst_name] = await field.read() + + return return_dict + + @property + def _is_readable(self) -> bool: + return True + + @property + def _is_writeable(self) -> bool: + return False + + +class RegAsyncWriteOnly(AsyncReg, ABC): + """ + class for an asynchronous write only register + """ + + __slots__: list[str] = [] + + # pylint: disable=too-many-arguments, duplicate-code, useless-parent-delegation + def __init__(self, *, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap, AsyncRegFile, + WritableAsyncMemory, WritableAsyncMemoryLegacy]): + + super().__init__(address=address, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent, width=width, accesswidth=accesswidth) + # pylint: enable=too-many-arguments, duplicate-code + + async def write(self, data: int) -> None: + """Asynchronously writes a value to the register + + Args: + data: data to be written + + Raises: + ValueError: if the value provided is outside the range of the + permissible values for the register + TypeError: if the type of data is wrong + """ + + # this method check the types and range checks the data + self._validate_data(data=data) + + # pylint: disable=duplicate-code + self._logger.info('Writing data:%X to %X', data, self.address) + # pylint: enable=duplicate-code + + if self._callbacks.write_callback is not None: + + await self._callbacks.write_callback(addr=self.address, + width=self.width, + accesswidth=self.accesswidth, + data=data) + + elif self._callbacks.write_block_callback is not None: + + if isinstance(self._callbacks, AsyncCallbackSetLegacy): + data_as_array = Array(get_array_typecode(self.width), [data]) + await self._callbacks.write_block_callback(addr=self.address, + width=self.width, + accesswidth=self.accesswidth, + data=data_as_array) + + if isinstance(self._callbacks, AsyncCallbackSet): + await self._callbacks.write_block_callback(addr=self.address, + width=self.width, + accesswidth=self.accesswidth, + data=[data]) + + else: + # pylint: disable-next=duplicate-code + raise RuntimeError('This function does not have a useable callback') + + @property + def writable_fields(self) -> Iterator[Union['FieldAsyncWriteOnly', 'FieldAsyncReadWrite']]: + """ + generator that produces has all the writable fields within the register + """ + def is_writable(field: Union['FieldAsyncReadOnly', + 'FieldAsyncWriteOnly', + 'FieldAsyncReadWrite']) -> \ + TypeGuard[Union['FieldAsyncWriteOnly', 'FieldAsyncReadWrite']]: + return isinstance(field, (FieldAsyncWriteOnly, FieldAsyncReadWrite)) + + return filter(is_writable, self.fields) + + @abstractmethod + async def write_fields(self, **kwargs) -> None: # type: ignore[no-untyped-def] + """ + Do an async write to the register, updating any field included in + the arguments + """ + + @property + def _is_readable(self) -> bool: + return False + + @property + def _is_writeable(self) -> bool: + return True + + +class RegAsyncReadWrite(RegAsyncReadOnly, RegAsyncWriteOnly, ABC): + """ + class for an async read and write only register + + """ + __slots__: list[str] = ['__in_read_write_context_manager', '__in_read_context_manager', + '__register_state'] + + # pylint: disable=too-many-arguments, duplicate-code + def __init__(self, *, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap, AsyncRegFile, MemoryAsyncReadWrite, + MemoryAsyncReadWriteLegacy]): + + super().__init__(address=address, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent, width=width, accesswidth=accesswidth) + + self.__in_read_write_context_manager: bool = False + self.__in_read_context_manager: bool = False + self.__register_state: Optional[int] = None + + # pylint: enable=too-many-arguments, duplicate-code + + @asynccontextmanager + async def single_read_modify_write(self, verify: bool = False, skip_write: bool = False) -> \ + AsyncGenerator[Self]: + """ + Context manager to allow multiple field reads/write to be done with a single set of + field operations + + Args: + verify (bool): very the write with a read afterwards + skip_write (bool): skip the write back at the end + + """ + # pylint: disable=duplicate-code + if self.__in_read_context_manager: + raise RuntimeError('using the `single_read_modify_write` context manager within the ' + 'single_read` is not permitted') + + if skip_write is True: + warn('The `skip_write` argument will be removed in the future, use `single_read`' + ' instead', + DeprecationWarning, stacklevel=2) + # pylint: enable=duplicate-code + + self.__register_state = await self.read() + + # pylint: disable=duplicate-code + self.__in_read_write_context_manager = True + # this try/finally is needed to make sure that in the event of an exception + # the state flags are not left incorrectly set + try: + yield self + finally: + self.__in_read_write_context_manager = False + # pylint: enable=duplicate-code + if not skip_write: + await self.write(self.__register_state, verify) + + # clear the register states at the end of the context manager + self.__register_state = None + + @asynccontextmanager + async def single_read(self) -> \ + AsyncGenerator[Self]: + """ + Context manager to allow multiple field reads with a single register read + """ + # pylint: disable=duplicate-code + if self.__in_read_write_context_manager: + raise RuntimeError('using the `single_read` context manager within the ' + 'single_read_modify_write` is not permitted') + self.__in_read_context_manager = True + # pylint: enable=duplicate-code + try: + async with super().single_read() as reg: + yield reg + finally: + # pylint: disable=duplicate-code + self.__in_read_context_manager = False + + async def write(self, data: int, verify: bool = False) -> None: + """ + Writes a value to the register + + Args: + data: data to be written + verify: set to True to read back the register to verify the read has occurred correctly + + Raises: + ValueError: if the value provided is outside the range of the + permissible values for the register + TypeError: if the type of data is wrong + RegisterWriteVerifyError: the read back data after the write does not match the + expected value + """ + if self.__in_read_context_manager: + # pylint: disable=duplicate-code + raise RuntimeError('writes within the single read context manager are not permitted') + + if self.__in_read_write_context_manager: + # pylint: disable=duplicate-code + if self.__register_state is None: + raise RuntimeError('The internal register state should never be None in the ' + 'context manager') + self.__register_state = data + else: + await super().write(data) + if verify: + read_back = await self.read() + if read_back != data: + raise RegisterWriteVerifyError(f'Readback {read_back:X} ' + f'after writing {data:X}') + + async def read(self) -> int: + """ + Asynchronously read value from the register + """ + if self.__in_read_write_context_manager: + # pylint: disable=duplicate-code + if self.__register_state is None: + raise RuntimeError('The internal register state should never be None in the ' + 'context manager') + return self.__register_state + + # the single read context manager is handled in the base class so does need any + # handling here + + return await super().read() + + async def read_fields(self) -> dict['str', Union[bool, Enum, int]]: + """ + asynchronously read the register and return a dictionary of the field values + """ + return_dict: dict['str', Union[bool, Enum, int]] = {} + async with self.single_read() as reg: + for field in reg.readable_fields: + return_dict[field.inst_name] = await field.read() + + return return_dict + + async def write_fields(self, **kwargs) -> None: # type: ignore[no-untyped-def] + """ + asynchronously read-modify-write to the register, updating any field included in + the arguments + """ + if len(kwargs) == 0: + raise ValueError('no command args') + + async with self.single_read_modify_write() as reg: + for field_name, field_value in kwargs.items(): + if field_name not in reg.systemrdl_python_child_name_map.values(): + raise ValueError(f'{field_name} is not a member of the register') + + field = getattr(reg, field_name) + await field.write(field_value) + + @property + def _is_readable(self) -> bool: + return True + + @property + def _is_writeable(self) -> bool: + return True + + +ReadableAsyncRegister = Union[RegAsyncReadOnly, RegAsyncReadWrite] +WritableAsyncRegister = Union[RegAsyncWriteOnly, RegAsyncReadWrite] + + +# pylint: disable-next=invalid-name +AsyncRegArrayElementType= TypeVar('AsyncRegArrayElementType', bound=AsyncReg) + + +class AsyncRegArray(BaseRegArray, ABC): + """ + base class of register array wrappers + + Note: + It is not expected that this class will be instantiated under normal + circumstances however, it is useful for type checking + """ + # pylint: disable=too-many-arguments,duplicate-code + + __slots__: list[str] = ['__in_context_manager', '__register_cache', + '__register_address_array'] + + def __init__(self, *, + logger_handle: str, inst_name: str, + parent: Union[AsyncAddressMap, AsyncRegFile, AsyncMemory], + width: int, + accesswidth: int, + address: int, + stride: int, + dimensions: tuple[int, ...], + elements: Optional[dict[tuple[int, ...], AsyncRegArrayElementType]] = None): + + self.__in_context_manager: bool = False + self.__register_cache: Optional[Union[Array, list[int]]] = None + self.__register_address_array: Optional[list[int]] = None + + if not isinstance(parent._callbacks, (AsyncCallbackSet, AsyncCallbackSetLegacy)): + raise TypeError(f'callback set type is wrong, got {type(parent._callbacks)}') + + super().__init__(logger_handle=logger_handle, inst_name=inst_name, + parent=parent, address=address, width=width, accesswidth=accesswidth, + stride=stride, dimensions=dimensions, elements=elements) + + @property + def __empty_array_cache(self) -> Array: + return Array(get_array_typecode(self.width), self.__empty_list_cache) + + @property + def __empty_list_cache(self) -> list[int]: + return [0 for _ in range(self.__number_cache_entries)] + + async def __block_read_legacy(self) -> Array: + """ + Read all the contents of the array in the most optimal way, ideally with a block operation + """ + if not isinstance(self._callbacks, AsyncCallbackSetLegacy): + raise RuntimeError('This function should only be used with legacy callbacks') + + read_block_callback = self._callbacks.read_block_callback + read_callback = self._callbacks.read_callback + + if read_block_callback is not None: + + data_read = await read_block_callback(addr=self.address, + width=self.width, + accesswidth=self.accesswidth, + length=self.__number_cache_entries) + + if not isinstance(data_read, Array): + raise TypeError('The read block callback is expected to return an array') + + return data_read + + if read_callback is not None: + # there is not read_block_callback defined so we must used individual read + data_array = self.__empty_array_cache + + if self.__register_address_array is None: + raise RuntimeError('This address array has not be initialised') + + for entry, address in enumerate(self.__register_address_array): + data_entry = await read_callback(addr=address, + width=self.width, + accesswidth=self.accesswidth) + + data_array[entry] = data_entry + + return data_array + + raise RuntimeError('There is no usable callback') + + async def __block_write_legacy(self, data: Array, verify: bool) -> None: + """ + Write all the contents of the array in the most optimal way, ideally with a block operation + """ + if not isinstance(self._callbacks, AsyncCallbackSetLegacy): + raise RuntimeError('This function should only be used with legacy callbacks') + + write_block_callback = self._callbacks.write_block_callback + write_callback = self._callbacks.write_callback + + if write_block_callback is not None: + await write_block_callback(addr=self.address, + width=self.width, + accesswidth=self.width, + data=data) + + elif write_callback is not None: + # there is not write_block_callback defined so we must used individual write + + if self.__register_address_array is None: + raise RuntimeError('This address array has not be initialised') + + for entry_index, entry_data in enumerate(data): + entry_address = self.__register_address_array[entry_index] + await write_callback(addr=entry_address, + width=self.width, + accesswidth=self.accesswidth, + data=entry_data) + + else: + raise RuntimeError('No suitable callback') + + if verify: + read_back_verify_data = self.__block_read_legacy() + if read_back_verify_data != data: + raise RegisterWriteVerifyError('Read back block miss-match') + + async def __block_read(self) -> list[int]: + """ + Read all the contents of the array in the most optimal way, ideally with a block operation + """ + if not isinstance(self._callbacks, AsyncCallbackSet): + raise RuntimeError('This function should only be used with non-legacy callbacks') + + read_block_callback = self._callbacks.read_block_callback + read_callback = self._callbacks.read_callback + + if read_block_callback is not None: + data_read = \ + await read_block_callback(addr=self.address, + width=self.width, + accesswidth=self.accesswidth, + length=self.__number_cache_entries) + + + if not isinstance(data_read, list): + raise TypeError('The read block callback is expected to return an array') + + return data_read + + if read_callback is not None: + # there is not read_block_callback defined so we must used individual read + data_list = self.__empty_list_cache + + if self.__register_address_array is None: + raise RuntimeError('This address array has not be initialised') + + for entry, address in enumerate(self.__register_address_array): + data = await read_callback(addr=address, + width=self.width, + accesswidth=self.accesswidth) + + data_list[entry] = data + + return data_list + + raise RuntimeError('There is no usable callback') + + async def __block_write(self, data: list[int], verify: bool) -> None: + """ + Write all the contents of the array in the most optimal way, ideally with a block operation + """ + if not isinstance(self._callbacks, AsyncCallbackSet): + raise RuntimeError('This function should only be used with non-legacy callbacks') + + write_block_callback = self._callbacks.write_block_callback + write_callback = self._callbacks.write_callback + + if write_block_callback is not None: + await write_block_callback(addr=self.address, + width=self.width, + accesswidth=self.width, + data=data) + elif write_callback is not None: + # there is not write_block_callback defined so we must used individual write + + if self.__register_address_array is None: + raise RuntimeError('This address array has not be initialised') + + for entry_index, entry_data in enumerate(data): + entry_address = self.__register_address_array[entry_index] + await write_callback(addr=entry_address, + width=self.width, + accesswidth=self.accesswidth, + data=entry_data) + + else: + raise RuntimeError('No suitable callback') + + if verify: + read_back_verify_data = self.__block_read() + if read_back_verify_data != data: + raise RegisterWriteVerifyError('Read back block miss-match') + + def __cache_entry(self, addr: int, width: int, accesswidth: int) -> int: + """ + Validate the data provided and determine the cache entry + + Args: + addr: Address to write to + width: Width of the register in bits + accesswidth: Minimum access width of the register in bits + + Returns: + cache entry + + """ + if not isinstance(width, int): + raise TypeError(f'Width should be an int byt got {type(width)}') + if width != self.width: + raise ValueError('Requested Read width does not match the expected value') + if not isinstance(accesswidth, int): + raise TypeError(f'accesswidth should be an int byt got {type(accesswidth)}') + if accesswidth != self.accesswidth: + raise ValueError('Requested Read accesswidth does not match the expected value') + if not isinstance(addr, int): + raise TypeError(f'addr should be an int byt got {type(addr)}') + if not self.address <= addr < (self.address + self.size): + raise ValueError(f'Requested address 0x{addr:X} is out of range 0x{self.address:X} to ' + f'0x{self.address + self.size - (self.width >> 3):X}') + cache_entry = (addr - self.address) // (self.width >> 3) + if self.__register_address_array is None: + raise RuntimeError('The address table should always be populated here') + if self.__register_address_array[cache_entry] != addr: + raise RuntimeError(f'The calculated cache entry for address 0x{addr:X}') + return cache_entry + + async def __cache_read(self, addr: int, width: int, accesswidth: int) -> int: + """ + Used to replace the normal callbacks with those that access the cache + + Args: + addr: Address to write to + width: Width of the register in bits + accesswidth: Minimum access width of the register in bits + + Returns: + value inputted by the used + """ + if self.__register_cache is None: + raise RuntimeError('The cache array should be initialised') + return self.__register_cache[self.__cache_entry(addr=addr, + width=width, + accesswidth=accesswidth)] + + async def __cache_write(self, addr: int, width: int, accesswidth: int, data: int) -> None: + """ + Used to replace the normal callbacks with those that access the cache + + Args: + addr: Address to write to + width: Width of the register in bits + accesswidth: Minimum access width of the register in bits + data: value to be written to the register + + Returns: + None + """ + if not isinstance(data, int): + raise TypeError(f'Data should be an int byt got {type(data)}') + if self.__register_cache is None: + raise RuntimeError('The cache array should be initialised') + self.__register_cache[self.__cache_entry(addr=addr, + width=width, + accesswidth=accesswidth)] = data + + @property + def __cache_callbacks(self) -> AsyncCallbackSet: + return AsyncCallbackSet(read_callback=self.__cache_read, + write_callback=self.__cache_write) + + @property + def __number_cache_entries(self) -> int: + return self.size // (self.width >> 3) + + async def __initialise_cache(self, skip_initial_read: bool) -> Union[Array, list[int]]: + if isinstance(self._callbacks, AsyncCallbackSet): + if skip_initial_read: + return self.__empty_list_cache + return await self.__block_read() + + if isinstance(self._callbacks, AsyncCallbackSetLegacy): + if skip_initial_read: + return self.__empty_array_cache + return await self.__block_read_legacy() + + raise TypeError('Unhandled callback type') + + @asynccontextmanager + async def _cached_access(self, verify: bool = False, skip_write: bool = False, + skip_initial_read: bool = False) -> \ + AsyncGenerator[Self]: + """ + Context manager to allow multiple field reads/write to be done with a single set of + field operations + + Args: + verify (bool): very the write with a read afterwards + skip_write (bool): skip the write back at the end + + """ + self.__register_address_array = \ + [self.address + (i * (self.width >> 3)) for i in range(self.__number_cache_entries)] + self.__register_cache = await self.__initialise_cache(skip_initial_read=skip_initial_read) + self.__in_context_manager = True + # this try/finally is needed to make sure that in the event of an exception + # the state flags are not left incorrectly set + try: + yield self + finally: + self.__in_context_manager = False + if not skip_write: + if isinstance(self._callbacks, AsyncCallbackSet): + if not isinstance(self.__register_cache, list): + raise TypeError('Register cache should be a list in non-legacy mode') + await self.__block_write(self.__register_cache, verify) + if isinstance(self._callbacks, AsyncCallbackSetLegacy): + if not isinstance(self.__register_cache, Array): + raise TypeError('Register cache should be a Array in legacy mode') + await self.__block_write_legacy(self.__register_cache, verify) + + # clear the register states at the end of the context manager + self.__register_address_array = None + self.__register_cache = None + + @property + def _callbacks(self) -> Union[AsyncCallbackSet, AsyncCallbackSetLegacy]: + # pylint: disable=protected-access + if self.__in_context_manager: + return self.__cache_callbacks + + if self.parent is None: + raise RuntimeError('Parent must be set') + + if isinstance(self.parent._callbacks, (AsyncCallbackSet, AsyncCallbackSetLegacy)): + return self.parent._callbacks + + raise TypeError(f'unhandled parent callback type: {type(self.parent._callbacks)}') + + +class RegAsyncReadOnlyArray(AsyncRegArray, ABC): + """ + base class for a array of async read only registers + """ + __slots__: list[str] = [] + + # pylint: disable=too-many-arguments,duplicate-code + def __init__(self, *, + logger_handle: str, inst_name: str, + parent: Union[AsyncRegFile, AsyncAddressMap, ReadableAsyncMemory, + ReadableAsyncMemoryLegacy], + address: int, + width: int, + accesswidth: int, + stride: int, + dimensions: tuple[int, ...], + elements: Optional[dict[tuple[int, ...], RegAsyncReadOnly]] = None): + + if not isinstance(parent, (AsyncRegFile, AsyncAddressMap, + MemoryAsyncReadOnly, MemoryAsyncReadOnlyLegacy, + MemoryAsyncReadWrite, MemoryAsyncReadWriteLegacy)): + raise TypeError('parent should be either AsyncRegFile, AsyncAddressMap, ' + 'MemoryAsyncReadOnly, MemoryAsyncReadWrite ' + f'got {type(parent)}') + + super().__init__(logger_handle=logger_handle, inst_name=inst_name, + parent=parent, address=address, width=width, accesswidth=accesswidth, + stride=stride, dimensions=dimensions, elements=elements) + # pylint: enable=too-many-arguments,duplicate-code + + @asynccontextmanager + async def single_read(self) -> AsyncGenerator[Self]: + """ + Context manager to allow multiple field reads/write to be done with a single set of + field operations + + Args: + + + Returns: + + """ + async with self._cached_access(verify=False, skip_write=True, + skip_initial_read=False) as reg_array: + yield reg_array + + @property + def _is_readable(self) -> bool: + return True + + @property + def _is_writeable(self) -> bool: + return False + + +class RegAsyncWriteOnlyArray(AsyncRegArray, ABC): + """ + base class for a array of async write only registers + """ + __slots__: list[str] = [] + + # pylint: disable=too-many-arguments,duplicate-code + def __init__(self, *, + logger_handle: str, inst_name: str, + parent: Union[AsyncRegFile, AsyncAddressMap, + WritableAsyncMemory, WritableAsyncMemoryLegacy], + address: int, + width: int, + accesswidth: int, + stride: int, + dimensions: tuple[int, ...], + elements: Optional[dict[tuple[int, ...], RegAsyncWriteOnly]] = None): + + if not isinstance(parent, (AsyncRegFile, AsyncAddressMap, + MemoryAsyncWriteOnly, MemoryAsyncReadWrite, + MemoryAsyncWriteOnlyLegacy, MemoryAsyncReadWriteLegacy)): + raise TypeError('parent should be either AsyncRegFile, AsyncAddressMap, ' + 'MemoryAsyncWriteOnly, MemoryAsyncReadWrite ' + f'got {type(parent)}') + + super().__init__(logger_handle=logger_handle, inst_name=inst_name, + parent=parent, address=address, width=width, accesswidth=accesswidth, + stride=stride, dimensions=dimensions, elements=elements) + # pylint: enable=too-many-arguments,duplicate-code + + @asynccontextmanager + async def single_write(self) -> AsyncGenerator[Self]: + """ + Context manager to allow multiple field reads/write to be done with a single set of + field operations + + Args: + + + Returns: + + """ + async with self._cached_access(verify=False, skip_write=False, + skip_initial_read=True) as reg_array: + yield reg_array + + @property + def _is_readable(self) -> bool: + return False + + @property + def _is_writeable(self) -> bool: + return True + + +class RegAsyncReadWriteArray(AsyncRegArray, ABC): + """ + base class for a array of read and write registers + """ + __slots__: list[str] = [] + + # pylint: disable=too-many-arguments,duplicate-code + def __init__(self, *, + logger_handle: str, inst_name: str, + parent: Union[AsyncRegFile, AsyncAddressMap, + MemoryAsyncReadWrite, MemoryAsyncReadWriteLegacy], + address: int, + width: int, + accesswidth: int, + stride: int, + dimensions: tuple[int, ...], + elements: Optional[dict[tuple[int, ...], RegAsyncReadWrite]] = None): + + if not isinstance(parent, (AsyncRegFile, AsyncAddressMap, + MemoryAsyncReadWrite, MemoryAsyncReadWriteLegacy)): + raise TypeError('parent should be either AsyncRegFile, AsyncAddressMap, ' + 'MemoryAsyncReadWrite ' + f'got {type(parent)}') + + super().__init__(logger_handle=logger_handle, inst_name=inst_name, + parent=parent, address=address, width=width, accesswidth=accesswidth, + stride=stride, dimensions=dimensions, elements=elements) + # pylint: enable=too-many-arguments,duplicate-code + + @asynccontextmanager + async def single_read_modify_write(self, verify: bool = False, skip_write: bool = False) -> \ + AsyncGenerator[Self]: + """ + Context manager to allow multiple field reads/write to be done with a single set of + field operations + + Args: + verify (bool): very the write with a read afterwards + skip_write (bool): skip the write back at the end + + Returns: + + """ + if skip_write is True: + warn('The `skip_write` argument will be removed in the future, use `single_read`' + ' instead', + DeprecationWarning, stacklevel=2) + + async with self._cached_access(verify=verify, skip_write=skip_write, + skip_initial_read=False) as reg_array: + yield reg_array + + @property + def _is_readable(self) -> bool: + return True + + @property + def _is_writeable(self) -> bool: + return True + + +ReadableAsyncRegisterArray = Union[RegAsyncReadOnlyArray, RegAsyncReadWriteArray] +WriteableAsyncRegisterArray = Union[RegAsyncWriteOnlyArray, RegAsyncReadWriteArray] + + +class FieldAsyncReadOnly(_FieldReadOnlyFramework[FieldType], ABC): + """ + class for an asynchronous read only register field + + Args: + parent_register: register within which the field resides + size_props: object defining the msb, lsb, high bit, low bit and width + logger_handle: name to be used logging messages associate with this + object + + """ + __slots__: list[str] = [] + + # pylint: disable-next=too-many-arguments + def __init__(self, *, + parent_register: ReadableAsyncRegister, + size_props: FieldSizeProps, + misc_props: FieldMiscProps, + logger_handle: str, + inst_name: str, + field_type:type[FieldType]): + + if not isinstance(parent_register, (RegAsyncReadWrite, RegAsyncReadOnly)): + raise TypeError(f'size_props must be of {type(RegAsyncReadWrite)} or ' + f'{type(RegAsyncReadOnly)} but got {type(parent_register)}') + + # pylint: disable=duplicate-code + super().__init__(logger_handle=logger_handle, + size_props=size_props, + misc_props=misc_props, + parent_register=parent_register, + inst_name=inst_name, + field_type=field_type) + # pylint: enable=duplicate-code + + async def read(self) -> FieldType: # pylint: disable=invalid-overridden-method + """ + Asynchronously reads the register that this field is located in and retries the field + value applying the required masking and shifting + + Returns: + field value + + """ + return self._decode_read_value(await self.parent_register.read()) + + @property + def parent_register(self) -> ReadableAsyncRegister: + """ + parent register the field is placed in + """ + + # this cast is OK because an explict typing check was done in the __init__ + return cast(ReadableAsyncRegister, self.parent) + + +class FieldAsyncWriteOnly(_FieldWriteOnlyFramework[FieldType], ABC): + """ + class for an asynchronous write only register field + + Args: + parent_register: register within which the field resides + size_props: object defining the msb, lsb, high bit, low bit and width + logger_handle: name to be used logging messages associate with this + object + + """ + __slots__: list[str] = [] + + # pylint: disable-next=too-many-arguments + def __init__(self, *, + parent_register: WritableAsyncRegister, + size_props: FieldSizeProps, + misc_props: FieldMiscProps, + logger_handle: str, + inst_name: str, + field_type:type[FieldType]): + + if not isinstance(parent_register, (RegAsyncReadWrite, RegAsyncWriteOnly)): + raise TypeError(f'size_props must be of {type(RegAsyncReadWrite)} or ' + f'{type(RegAsyncWriteOnly)} but got {type(parent_register)}') + + # pylint: disable=duplicate-code + super().__init__(logger_handle=logger_handle, + size_props=size_props, + misc_props=misc_props, + parent_register=parent_register, + inst_name=inst_name, + field_type=field_type) + # pylint: enable=duplicate-code + + async def write(self, value: FieldType) -> None: # pylint: disable=invalid-overridden-method + """ + The behaviour of this method depends on whether the field is located in + a readable register or not: + + If the register is readable, the method will perform an async read-modify-write + on the register updating the field with the value provided + + If the register is not writable all other field values will be asynchronously written + with zero. + + Args: + value: field value to update to + + """ + encoded_value = self._encode_write_value(value) + + if (self.high == (self.register_data_width - 1)) and (self.low == 0): + # special case where the field occupies the whole register, + # there a straight write can be performed + new_reg_value = encoded_value + else: + # do a read, modify write + if isinstance(self.parent_register, RegAsyncReadWrite): + reg_value = await self.parent_register.read() + masked_reg_value = reg_value & self.inverse_bitmask + new_reg_value = masked_reg_value | encoded_value + elif isinstance(self.parent_register, RegAsyncWriteOnly): + new_reg_value = encoded_value + else: + raise TypeError('Unhandled parent type') + + await self.parent_register.write(new_reg_value) + + @property + def parent_register(self) -> WritableAsyncRegister: + """ + parent register the field is placed in + """ + + # this cast is OK because an explict typing check was done in the __init__ + return cast(WritableAsyncRegister, self.parent) + + +class FieldAsyncReadWrite(FieldAsyncReadOnly[FieldType], FieldAsyncWriteOnly[FieldType], ABC): + """ + class for an asynchronous read/write register field + + Args: + parent_register: register within which the field resides + size_props: object defining the msb, lsb, high bit, low bit and width + logger_handle: name to be used logging messages associate with this + object + + """ + __slots__: list[str] = [] + + # pylint: disable-next=too-many-arguments + def __init__(self, *, + parent_register: RegAsyncReadWrite, + size_props: FieldSizeProps, + misc_props: FieldMiscProps, + logger_handle: str, + inst_name: str, + field_type:type[FieldType]): + + if not isinstance(parent_register, RegAsyncReadWrite): + raise TypeError(f'size_props must be of {type(RegAsyncReadWrite)} ' + f'but got {type(parent_register)}') + + # pylint: disable=duplicate-code + super().__init__(logger_handle=logger_handle, + size_props=size_props, + misc_props=misc_props, + parent_register=parent_register, + inst_name=inst_name, + field_type=field_type) + # pylint: enable=duplicate-code + + @property + def parent_register(self) -> RegAsyncReadWrite: + """ + parent register the field is placed in + """ + + # this cast is OK because an explict typing check was done in the __init__ + return cast(RegAsyncReadWrite, self.parent) + + +class FieldEnumAsyncReadWrite(FieldAsyncReadWrite[FieldType], FieldEnum[FieldType], ABC): + """ + class for an async read/write register field with an enumerated value + """ + __slots__: list[str] = [] + + @property + def parent_register(self) -> RegAsyncReadWrite: + """ + parent register the field is placed in + """ + + # this cast is OK because an explict typing check was done in the __init__ + return cast(RegAsyncReadWrite, self.parent) + + +class FieldEnumAsyncReadOnly(FieldAsyncReadOnly[FieldType], FieldEnum[FieldType], ABC): + """ + class for an async read only register field with an enumerated value + """ + __slots__: list[str] = [] + + +class FieldEnumAsyncWriteOnly(FieldAsyncWriteOnly[FieldType], FieldEnum[FieldType], ABC): + """ + class for an async write only register field with an enumerated value + """ + __slots__: list[str] = [] diff --git a/rdl/outputs/python/msk_top_regs/lib/base.py b/rdl/outputs/python/msk_top_regs/lib/base.py new file mode 100644 index 0000000..c99cc7e --- /dev/null +++ b/rdl/outputs/python/msk_top_regs/lib/base.py @@ -0,0 +1,942 @@ +""" +peakrdl-python is a tool to generate Python Register Access Layer (RAL) from SystemRDL +Copyright (C) 2021 - 2023 + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +This module is intended to distributed as part of automatically generated code by the +peakrdl-python tool. It provides a set of base classes used by the autogenerated code +""" +from __future__ import annotations +import logging +import warnings +from typing import Optional, Union, TYPE_CHECKING, TypeVar, Any +from collections.abc import Iterator, Sequence +from abc import ABC, abstractmethod +from itertools import product, chain +from functools import reduce +from operator import mul +import sys +from enum import IntEnum + +from .callbacks import CallbackSet, CallbackSetLegacy +from .callbacks import NormalCallbackSet, AsyncCallbackSet +from .callbacks import NormalCallbackSetLegacy, AsyncCallbackSetLegacy + +if sys.version_info >= (3, 10): + # type guarding was introduced in python 3.10 + from typing import TypeGuard +else: + from typing_extensions import TypeGuard + +if TYPE_CHECKING: + from .memory import Memory, MemoryArray + from .async_memory import AsyncMemory, AsyncMemoryArray + from .register_and_field import Reg, RegArray + from .register_and_field import WritableRegister, ReadableRegister + from .async_register_and_field import AsyncReg, AsyncRegArray + from .async_register_and_field import ReadableAsyncRegister, WritableAsyncRegister + from .register_and_field import ReadableRegisterArray, WriteableRegisterArray + from .async_register_and_field import ReadableAsyncRegisterArray, WriteableAsyncRegisterArray + +UDPStruct = dict[str, 'UDPType'] +UDPType = Union[str, int, bool, IntEnum, UDPStruct] + +class Base(ABC): + """ + base class of for all types + """ + __slots__: list[str] = ['__logger', '__inst_name', '__parent'] + + def __init__(self, *, + logger_handle: str, inst_name: str, parent: Optional[Union['Node', 'NodeArray']]): + + if not isinstance(logger_handle, str): + raise TypeError(f'logger_handle should be str but got {type(logger_handle)}') + + self.__logger = logging.getLogger(logger_handle) + self._logger.debug('creating instance of %s', self.__class__) + + if not isinstance(inst_name, str): + raise TypeError(f'inst_name should be str but got {type(inst_name)}') + self.__inst_name = inst_name + + if parent is not None: + if not isinstance(parent, (Node, NodeArray)): + raise TypeError(f'parent should be Node or Node Array but got {type(parent)}') + self.__parent = parent + + @property + def _logger(self) -> logging.Logger: + return self.__logger + + @property + def inst_name(self) -> str: + """ + systemRDL name of the instance in the parent + """ + return self.__inst_name + + @property + def parent(self) -> Optional[Union['Node', 'NodeArray']]: + """ + parent of the node or field, or None if it has no parent + """ + return self.__parent + + @property + def full_inst_name(self) -> str: + """ + The full hierarchical systemRDL name of the instance + """ + if self.parent is not None: + if isinstance(self.parent, NodeArray): + if self.parent.parent is None: + raise RuntimeError('A node array must have a parent it can not be the ' + 'top level') + return self.parent.parent.full_inst_name + "." + self.inst_name + + return self.parent.full_inst_name + "." + self.inst_name + + return self.inst_name + + @property + def udp(self) -> UDPStruct: + """ + A dictionary of the user defined properties for the node + """ + return {} + + @property + def rdl_name(self) -> Optional[str]: + """ + The systemRDL name property for the item + """ + return None + + @property + def rdl_desc(self) -> Optional[str]: + """ + The systemRDL desc property for the item + """ + return None + + +class Node(Base, ABC): + """ + base class of for all types with an address i.e. not fields + + Note: + It is not expected that this class will be instantiated under normal + circumstances however, it is useful for type checking + """ + + __slots__ = ['__address'] + + def __init__(self, *, + address: int, + logger_handle: str, + inst_name: str, + parent: Optional[Union['Node', 'NodeArray']]): + super().__init__(logger_handle=logger_handle, inst_name=inst_name, parent=parent) + + if not isinstance(address, int): + raise TypeError(f'address should be int but got {type(address)}') + + self.__address = address + + @property + def address(self) -> int: + """ + address of the node + """ + return self.__address + + @property + @abstractmethod + def _callbacks(self) -> Union[CallbackSet, CallbackSetLegacy]: + ... + + @property + @abstractmethod + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + + def get_child_by_system_rdl_name(self, name: Any) -> Any: + """ + returns a child node by its systemRDL name + + Args: + name: name of the node in the systemRDL + + Returns: Node + + """ + if not isinstance(name, str): + raise TypeError(f'name must be a string got {type(name)}') + return getattr(self, self.systemrdl_python_child_name_map[name]) + + @property + @abstractmethod + def size(self) -> int: + """ + Total Number of bytes of address the node occupies + """ + + +# pylint: disable-next=invalid-name +NodeArrayElementType = TypeVar('NodeArrayElementType', bound=Node) + + +class NodeArray(Base, Sequence[NodeArrayElementType]): + """ + base class of for all array types + """ + + # pylint: disable=too-few-public-methods + __slots__: list[str] = ['__elements', '__address', + '__stride', '__dimensions'] + + # pylint: disable-next=too-many-arguments + def __init__(self, *, logger_handle: str, + inst_name: str, + parent: Node, + address: int, + stride: int, + dimensions: tuple[int, ...], + elements: Optional[dict[tuple[int, ...], NodeArrayElementType]] = None): + + super().__init__(logger_handle=logger_handle, inst_name=inst_name, parent=parent) + + if not isinstance(address, int): + raise TypeError(f'address should be a int but got {type(dimensions)}') + self.__address = address + if not isinstance(stride, int): + raise TypeError(f'stride should be a int but got {type(dimensions)}') + self.__stride = stride + + if not isinstance(dimensions, tuple): + raise TypeError(f'dimensions should be a tuple but got {type(dimensions)}') + for dimension in dimensions: + if not isinstance(dimension, int): + raise TypeError(f'dimension should be a int but got {type(dimension)}') + self.__dimensions = dimensions + + # There are two use cases for this class: + # 1. Initial creation - elements is None in which case the data is populated + # 2. Creating a recursive version of itself, this happens when it is sliced by the parent + # in which case a subset of the elements is presented and a new instance + + if elements is not None: + self.__check_init_element(elements) + self.__elements = elements + else: + new_elements: dict[tuple[int, ...], NodeArrayElementType] = {} + for indices in product(*[range(dim) for dim in self.dimensions]): + new_elements[indices] = self._build_element(indices=indices) + + self.__elements = new_elements + + def _build_element(self, indices: tuple[int, ...]) -> NodeArrayElementType: + + return self._element_datatype( + logger_handle=self._build_element_logger_handle(indices=indices), + address=self._address_calculator(indices), + inst_name=self._build_element_inst_name(indices=indices), + parent=self) + + def _build_element_logger_handle(self, indices: tuple[int, ...]) -> str: + """ + Build the logger handle for an element in the array + + Args: + indices: element index + + Returns: + """ + return self._logger.name + '[' + ','.join([str(item) for item in indices]) + ']' + + def _build_element_inst_name(self, indices: tuple[int, ...]) -> str: + """ + Build the logger handle for an element in the array + + Args: + indices: element index + + Returns: + """ + return self.inst_name + '[' + ']['.join([str(item) for item in indices]) + ']' + + def __check_init_element(self, elements: dict[tuple[int, ...], NodeArrayElementType]) -> None: + """ + Used in the __init__ to check that the elements passed in are valid + Args: + elements: proposed element of the array + + Returns: + + """ + if not isinstance(elements, dict): + raise TypeError(f'elements should be a dictionary but got {type(elements)}') + + for index, item in elements.items(): + if not isinstance(index, tuple): + raise TypeError(f'element index should be a tuple but got {type(index)}') + + if len(index) != len(self.dimensions): + raise ValueError(f'size of index does not match index length = {len(index)}') + + for index_pos, index_item in enumerate(index): + if not isinstance(index_item, int): + raise TypeError(f'element index_item should be a int ' + f'but got {type(index_item)}') + + if not 0 <= index_item < self.dimensions[index_pos]: + raise ValueError('index outside of range of dimensions') + + if not isinstance(item, self._element_datatype): + raise TypeError(f'elements should be a {self._element_datatype} ' + f'but got {type(item)}') + + def _address_calculator(self, indices: tuple[int, ...]) -> int: + def cal_addr(dimensions: tuple[int,...], indices: tuple[int, ...], base_address: int, + stride: int) -> int: + """ + Calculates the address of an register within an array + + :param dimensions: list of the array dimensions + :param indices: list of the array indices (length must match the dimensions) + :param base_address: base address of the array + :param stride: address stride of of the array + :return: address of the register + """ + if len(dimensions) == 1: + return (indices[0] * stride) + base_address + + outer_offset = reduce(mul, dimensions[1::], 1) * stride * indices[0] + return outer_offset + cal_addr(dimensions=dimensions[1::], + indices=indices[1::], + stride=self.stride, + base_address=self.address) + + return cal_addr(self.dimensions, base_address=self.address, + stride=self.stride, indices=indices) + + def _sub_instance(self, elements: dict[tuple[int, ...], NodeArrayElementType]) -> \ + NodeArray[NodeArrayElementType]: + if not isinstance(self.parent, Node): + raise RuntimeError('Parent of a Node Array must be Node') + return self.__class__(logger_handle=self._logger.name, + inst_name=self.inst_name, + parent=self.parent, + address=self.address, + stride=self.stride, + dimensions=self.dimensions, + elements=elements) + + def __getitem__(self, item): # type: ignore[no-untyped-def] + if len(self.dimensions) > 1: + return self.__getitem_nd(item) + + if isinstance(item, tuple): + raise IndexError('attempting a multidimensional array access on a single dimension' + ' array') + + if isinstance(item, slice): + + valid_items = [(i,) for i in range(*item.indices(self.dimensions[0]))] + def filter_1d_func(to_filter:tuple[tuple[int, ...], NodeArrayElementType]) -> bool: + index, _ = to_filter + if index in valid_items: + return True + return False + + return self._sub_instance(elements=dict(filter(filter_1d_func, self.items()))) + + if isinstance(item, int): + if (item, ) not in self.__elements: + raise IndexError(f'{item:d} in in the array') + return self.__elements[(item, )] + + raise TypeError(f'Array index must either being an int or a slice, got {type(item)}') + + def __getitem_nd(self, item): # type: ignore[no-untyped-def] + + if isinstance(item, tuple): + + if len(item) != len(self.dimensions): + raise ValueError('When using a multidimensional access, the size must match the' + ' dimensions of the array, array dimensions ' + f'are {len(self.dimensions)}') + + if all(isinstance(i, int) for i in item): + # single item access + if item not in self.__elements: + msg = 'index[' + ','.join([str(i) for i in item]) + '] not in array' + raise IndexError(msg) + return self.__elements[item] + + unpack_index_set = [] + for axis, sub_index in enumerate(item): + if isinstance(sub_index, int): + if not 0 <= sub_index < self.dimensions[axis]: + raise IndexError(f'{sub_index:d} out of range for dimension {axis}') + unpack_index_set.append((sub_index,)) + continue + + if isinstance(sub_index, slice): + unpack_index_set.append(range(*sub_index.indices(self.dimensions[axis]))) + continue + + raise TypeError(f'unhandle index of {type(sub_index)} in position {axis:d}') + + valid_items = tuple(product(*unpack_index_set)) + + def filter_nd_func(to_filter: tuple[tuple[int, ...], NodeArrayElementType]) -> bool: + index, _ = to_filter + if index in valid_items: + return True + return False + + return self._sub_instance(elements=dict(filter(filter_nd_func, self.items()))) + + raise IndexError('attempting a single dimensional array access on a multidimension' + ' array') + + def __len__(self) -> int: + return len(self.__elements) + + def __iter__(self) -> Iterator[NodeArrayElementType]: + yield from self.__elements.values() + + def items(self) -> Iterator[tuple[tuple[int, ...], NodeArrayElementType]]: + """ + iterate through all the items in an array but also return the index of the array + """ + yield from self.__elements.items() + + @property + def dimensions(self) -> Union[tuple[int, ...], tuple[int]]: + """ + Dimensions of the array + """ + return self.__dimensions + + @property + @abstractmethod + def _element_datatype(self) -> type[NodeArrayElementType]: + ... + + @property + def address(self) -> int: + """ + address of the node + """ + return self.__address + + @property + def stride(self) -> int: + """ + address stride of the array + """ + return self.__stride + + @property + def _callbacks(self) -> Union[CallbackSet, CallbackSetLegacy]: + if self.parent is None: + raise RuntimeError('Parent must be set') + # pylint: disable-next=protected-access + return self.parent._callbacks + + @property + def size(self) -> int: + """ + Total Number of bytes of address the array occupies + """ + return reduce(mul, self.dimensions, 1) * self.stride + + +class BaseSection(Node, ABC): + """ + base class of non-async and sync sections (AddressMaps and RegFile) + + Note: + It is not expected that this class will be instantiated under normal + circumstances however, it is useful for type checking + """ + __slots__: list[str] = [] + + @abstractmethod + def get_children(self, unroll: bool = False) -> Iterator[Union[Node, NodeArray]]: + """ + generator that produces all the readable_registers of this node + + Args: + unroll: Whether to unroll child array or not + """ + + +class Section(BaseSection, ABC): + """ + base class of non-async sections (AddressMaps and RegFile) + + Note: + It is not expected that this class will be instantiated under normal + circumstances however, it is useful for type checking + """ + __slots__: list[str] = [] + + def get_writable_registers(self, unroll:bool=False) -> \ + Iterator[Union[WritableRegister, WriteableRegisterArray]]: + """ + generator that produces all the readable_registers of this node + + Args: + unroll: Whether to unroll child array or not + """ + def is_writable(item: Union[Reg, RegArray]) -> \ + TypeGuard[Union[WritableRegister, WriteableRegisterArray]]: + # pylint: disable-next=protected-access + return item._is_writeable + + return filter(is_writable, self.get_registers(unroll=unroll)) + + def get_readable_registers(self, unroll: bool = False) -> \ + Iterator[Union[ReadableRegister, ReadableRegisterArray]]: + """ + generator that produces all the readable_registers of this node + + Args: + unroll: Whether to unroll child array or not + """ + def is_readable(item: Union[Reg, RegArray]) ->\ + TypeGuard[Union[ReadableRegister, ReadableRegisterArray]]: + # pylint: disable-next=protected-access + return item._is_readable + + return filter(is_readable, self.get_registers(unroll=unroll)) + + @abstractmethod + def get_registers(self, unroll: bool = False) -> \ + Iterator[Union[Reg, RegArray]]: + """ + generator that produces all the readable_registers of this node + + Args: + unroll: Whether to unroll child array or not + """ + + +class AddressMap(Section, ABC): + """ + base class of address map wrappers + + Note: + It is not expected that this class will be instantiated under normal + circumstances however, it is useful for type checking + """ + __slots__: list[str] = ['__callbacks'] + + def __init__(self, *, + callbacks: Optional[Union[NormalCallbackSet, NormalCallbackSetLegacy]], + address: int, + logger_handle: str, + inst_name: str, + parent: Optional['AddressMap']): + + # only the top-level address map should have callbacks assigned, everything else should + # use its parent callback + if parent is None: + if not isinstance(callbacks, (NormalCallbackSet, NormalCallbackSetLegacy)): + raise TypeError(f'callback type wrong, got {type(callbacks)}') + if isinstance(callbacks, NormalCallbackSetLegacy): + warnings.warn('Support for the legacy callback using the array types will be ' + 'withdrawn in the future, please consider changing to the list ' + 'versions', category=DeprecationWarning) + self.__callbacks = callbacks + else: + if not callbacks is None: + raise RuntimeError('Callbacks must be None when a parent is set') + if not isinstance(parent._callbacks, (NormalCallbackSet, NormalCallbackSetLegacy)): + raise TypeError(f'callback type wrong, got {type(callbacks)}') + + super().__init__(address=address, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + @abstractmethod + def get_sections(self, unroll: bool = False) -> \ + Iterator[Union['AddressMap', RegFile, AddressMapArray, RegFileArray]]: + """ + generator that produces all the AddressMap and RegFile children of this node + + Args: + unroll: Whether to unroll child array or not + + Returns: + + """ + + @abstractmethod + def get_memories(self, unroll: bool = False) -> \ + Iterator[Union['Memory', 'MemoryArray']]: + """ + generator that produces all the Memory children of this node + + Args: + unroll: Whether to unroll child array or not + + Returns: + + """ + + def get_children(self, unroll: bool = False) -> Iterator[Union[Node, NodeArray]]: + return chain(self.get_registers(unroll=unroll), + self.get_sections(unroll=unroll), + self.get_memories(unroll=unroll)) + + @property + def _callbacks(self) -> Union[NormalCallbackSet, NormalCallbackSetLegacy]: + # pylint: disable=protected-access + if self.parent is None: + return self.__callbacks + + if isinstance(self.parent._callbacks, (NormalCallbackSet, NormalCallbackSetLegacy)): + return self.parent._callbacks + + raise TypeError(f'unhandled parent callback type: {type(self.parent._callbacks)}') + + +class AsyncSection(BaseSection, ABC): + """ + base class of async sections (AddressMaps and RegFile) + + Note: + It is not expected that this class will be instantiated under normal + circumstances however, it is useful for type checking + """ + __slots__: list[str] = [] + + def get_writable_registers(self, unroll: bool = False) -> \ + Iterator[Union[WritableAsyncRegister, WriteableAsyncRegisterArray]]: + """ + generator that produces all the readable_registers of this node + + Args: + unroll: Whether to unroll child array or not + """ + def is_writable(item: Union[AsyncReg, AsyncRegArray]) -> \ + TypeGuard[Union[WritableAsyncRegister, WriteableAsyncRegisterArray]]: + # pylint: disable-next=protected-access + return item._is_writeable + + return filter(is_writable, self.get_registers(unroll=unroll)) + + def get_readable_registers(self, unroll: bool = False) -> \ + Iterator[Union[ReadableAsyncRegister, ReadableAsyncRegisterArray]]: + """ + generator that produces all the readable_registers of this node + + Args: + unroll: Whether to unroll child array or not + """ + def is_readable(item: Union[AsyncReg, AsyncRegArray]) -> \ + TypeGuard[Union[ReadableAsyncRegister, ReadableAsyncRegisterArray]]: + # pylint: disable-next=protected-access + return item._is_readable + + return filter(is_readable, self.get_registers(unroll=unroll)) + + + @abstractmethod + def get_registers(self, unroll: bool = False) -> \ + Iterator[Union[AsyncReg, AsyncRegArray]]: + """ + generator that produces all the readable_registers of this node + + Args: + unroll: Whether to unroll child array or not + """ + + @property + @abstractmethod + def _callbacks(self) -> Union[AsyncCallbackSet, AsyncCallbackSetLegacy]: + ... + + +class AsyncAddressMap(AsyncSection, ABC): + """ + base class of address map wrappers + + Note: + It is not expected that this class will be instantiated under normal + circumstances however, it is useful for type checking + """ + + __slots__: list[str] = ['__callbacks'] + + def __init__(self, *, + callbacks: Optional[Union[AsyncCallbackSet, AsyncCallbackSetLegacy]], + address: int, + logger_handle: str, + inst_name: str, + parent: Optional['AsyncAddressMap']): + + # only the top-level address map should have callbacks assigned, everything else should + # use its parent callback + if parent is None: + if not isinstance(callbacks, (AsyncCallbackSet, AsyncCallbackSetLegacy)): + raise TypeError(f'callback type wrong, got {type(callbacks)}') + if isinstance(callbacks, AsyncCallbackSetLegacy): + warnings.warn('Support for the legacy callback using the array types will be ' + 'withdrawn in the future, please consider changing to the list ' + 'versions', category=DeprecationWarning) + self.__callbacks = callbacks + else: + if not callbacks is None: + raise RuntimeError('Callbacks must be None when a parent is set') + if not isinstance(parent._callbacks, (AsyncCallbackSet, AsyncCallbackSetLegacy)): + raise TypeError(f'callback type wrong, got {type(callbacks)}') + + super().__init__(address=address, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + @abstractmethod + def get_sections(self, unroll: bool = False) -> \ + Iterator[Union['AsyncAddressMap', AsyncRegFile, + AsyncAddressMapArray, AsyncRegFileArray]]: + """ + generator that produces all the AddressMap and RegFile children of this node + + Args: + unroll: Whether to unroll child array or not + + Returns: + + """ + + @abstractmethod + def get_memories(self, unroll: bool = False) -> \ + Iterator[Union['AsyncMemory', 'AsyncMemoryArray']]: + """ + generator that produces all the Memory children of this node + + Args: + unroll: Whether to unroll child array or not + + Returns: + + """ + + @property + def _callbacks(self) -> Union[AsyncCallbackSet, AsyncCallbackSetLegacy]: + # pylint: disable=protected-access + if self.parent is None: + return self.__callbacks + + if isinstance(self.parent._callbacks, (AsyncCallbackSet, AsyncCallbackSetLegacy)): + return self.parent._callbacks + + raise TypeError(f'unhandled parent callback type: {type(self.parent._callbacks)}') + + def get_children(self, unroll: bool = False) -> Iterator[Union[Node, NodeArray]]: + return chain(self.get_registers(unroll=unroll), self.get_sections(unroll=unroll), + self.get_memories(unroll=unroll)) + + +class AddressMapArray(NodeArray, ABC): + """ + base class for a array of address maps + """ + __slots__: list[str] = [] + + # pylint: disable-next=too-many-arguments + def __init__(self, *, logger_handle: str, inst_name: str, + parent: AddressMap, + address: int, + stride: int, + dimensions: tuple[int, ...]): + + super().__init__(logger_handle=logger_handle, inst_name=inst_name, + parent=parent, address=address, stride=stride, dimensions=dimensions) + + +class AsyncAddressMapArray(NodeArray, ABC): + """ + base class for a array of address maps + """ + __slots__: list[str] = [] + + # pylint: disable-next=too-many-arguments + def __init__(self, *, logger_handle: str, inst_name: str, + parent: AsyncAddressMap, + address: int, + stride: int, + dimensions: tuple[int, ...]): + + super().__init__(logger_handle=logger_handle, inst_name=inst_name, + parent=parent, address=address, + stride=stride, dimensions=dimensions) + + +class RegFile(Section, ABC): + """ + base class of register file wrappers + + Note: + It is not expected that this class will be instantiated under normal + circumstances however, it is useful for type checking + """ + + __slots__: list[str] = [] + + def __init__(self, *, + address: int, + logger_handle: str, + inst_name: str, + parent: Union[AddressMap, 'RegFile']): + + if not isinstance(parent._callbacks, (NormalCallbackSet, NormalCallbackSetLegacy)): + raise TypeError(f'parent._callbacks type wrong, got {type(parent._callbacks)}') + + super().__init__(address=address, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + @abstractmethod + def get_sections(self, unroll: bool = False) -> \ + Iterator[Union['RegFile','RegFileArray']]: + """ + generator that produces all the RegFile children of this node + + Args: + unroll: Whether to unroll child array or not + + Returns: + + """ + + @property + def _callbacks(self) -> Union[NormalCallbackSet, NormalCallbackSetLegacy]: + # pylint: disable=protected-access + if self.parent is None: + raise RuntimeError('Parent must be set') + + if isinstance(self.parent._callbacks, (NormalCallbackSet, NormalCallbackSetLegacy)): + return self.parent._callbacks + + raise TypeError(f'unhandled parent callback type: {type(self.parent._callbacks)}') + + def get_children(self, unroll: bool = False) -> Iterator[Union[Node, NodeArray]]: + return chain(self.get_registers(unroll=unroll), self.get_sections(unroll=unroll)) + + +class AsyncRegFile(AsyncSection, ABC): + """ + base class of register file wrappers + + Note: + It is not expected that this class will be instantiated under normal + circumstances however, it is useful for type checking + """ + + __slots__: list[str] = [] + + def __init__(self, *, + address: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap, 'AsyncRegFile']): + super().__init__(address=address, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + if not isinstance(parent._callbacks, (AsyncCallbackSet, AsyncCallbackSetLegacy)): + raise TypeError(f'parent._callbacks type wrong, got {type(parent._callbacks)}') + + @abstractmethod + def get_sections(self, unroll: bool = False) -> \ + Iterator[Union['AsyncRegFile','AsyncRegFileArray']]: + """ + generator that produces all the RegFile children of this node + + Args: + unroll: Whether to unroll child array or not + + Returns: + + """ + + def get_children(self, unroll: bool = False) -> Iterator[Union[Node, NodeArray]]: + return chain(self.get_registers(unroll=unroll), self.get_sections(unroll=unroll)) + + @property + def _callbacks(self) -> Union[AsyncCallbackSet, AsyncCallbackSetLegacy]: + # pylint: disable=protected-access + if self.parent is None: + raise RuntimeError('Parent must be set') + + if isinstance(self.parent._callbacks, (AsyncCallbackSet, AsyncCallbackSetLegacy)): + return self.parent._callbacks + + raise TypeError(f'unhandled parent callback type: {type(self.parent._callbacks)}') + + +class RegFileArray(NodeArray, ABC): + """ + base class for a array of register files + """ + __slots__: list[str] = [] + + # pylint: disable-next=too-many-arguments + def __init__(self, *, + logger_handle: str, inst_name: str, + parent: Union[AddressMap, RegFile], + address: int, + stride: int, + dimensions: tuple[int, ...]): + + super().__init__(logger_handle=logger_handle, inst_name=inst_name, + parent=parent, address=address, + stride=stride, dimensions=dimensions) + + +class AsyncRegFileArray(NodeArray, ABC): + """ + base class for a array of register files + """ + __slots__: list[str] = [] + + # pylint: disable-next=too-many-arguments + def __init__(self, *, + logger_handle: str, inst_name: str, + parent: Union[AsyncAddressMap, AsyncRegFile], + address: int, + stride: int, + dimensions: tuple[int, ...]): + + super().__init__(logger_handle=logger_handle, inst_name=inst_name, + parent=parent, address=address, + stride=stride, dimensions=dimensions) diff --git a/rdl/outputs/python/msk_top_regs/lib/base_field.py b/rdl/outputs/python/msk_top_regs/lib/base_field.py new file mode 100644 index 0000000..415747b --- /dev/null +++ b/rdl/outputs/python/msk_top_regs/lib/base_field.py @@ -0,0 +1,549 @@ +""" +peakrdl-python is a tool to generate Python Register Access Layer (RAL) from SystemRDL +Copyright (C) 2021 - 2023 + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +This module is intended to distributed as part of automatically generated code by the +peakrdl-python tool. It provides the base types for fields that are shared by non-async and async +fields +""" +from enum import IntEnum +from typing import cast, Optional, TypeVar, Generic +from abc import ABC +import warnings + +from .base import Base +from .utility_functions import swap_msb_lsb_ordering +from .base_register import BaseReg +from .field_encoding import SystemRDLEnum + + +class FieldSizeProps: + """ + class to hold the key attributes of a field + """ + __slots__ = ['__msb', '__lsb', '__width', '__high', '__low'] + + # pylint: disable-next=too-many-arguments + def __init__(self, *, width: int, msb: int, lsb: int, high: int, low: int): + self.__width = width + self.__msb = msb + self.__lsb = lsb + self.__high = high + self.__low = low + + if self.width < 1: + raise ValueError('width must be greater than 0') + + if self.high < self.low: + raise ValueError('field high bit position can not be less than the ' + 'low bit position') + + if self.lsb < 0: + raise ValueError('field low bit position cannot be less than zero') + + @property + def lsb(self) -> int: + """ + bit position of the least significant bit (lsb) of the field in the + parent register + + Note: + fields can be defined as msb in bit 0 or as lsb in bit 0 + """ + return self.__lsb + + @property + def msb(self) -> int: + """ + bit position of the most significant bit (msb) of the field in the + parent register + + Note: + fields can be defined as msb in bit 0 or as lsb in bit 0 + """ + return self.__msb + + @property + def width(self) -> int: + """ + The width of the field in bits + """ + return self.__width + + @property + def max_value(self) -> int: + """maximum unsigned integer value that can be stored in the field + + For example: + + * 8-bit field returns 0xFF (255) + * 16-bit field returns 0xFFFF (65535) + * 32-bit field returns 0xFFFF_FFFF (4294967295) + + """ + return (2 ** self.width) - 1 + + @property + def high(self) -> int: + """ + low index of the bit range of the field in the + parent register + + Note: + The first bit in the register is bit 0 + """ + return self.__high + + @property + def low(self) -> int: + """ + low index of the bit range of the field in the + parent register + + Note: + The first bit in the register is bit 0 + """ + return self.__low + + +class FieldMiscProps: + """ + Class to hold additional attributes of a field + """ + + __slots__ = ['__default', '__is_volatile'] + + def __init__(self, default:Optional[int], is_volatile:bool): + if not isinstance(default, int) and default is not None: + raise TypeError(f'default should be int or None, got {type(default)}') + self.__default = default + self.__is_volatile = is_volatile + + @property + def default(self) -> Optional[int]: + """ + The default (reset) value of the field + + None + - if the field is not reset. + - if the register resets to a signal value tht can not be determined + """ + return self.__default + + @property + def is_volatile(self) -> bool: + """ + Volatility of the field. True if the field is hardware-writable. + """ + return self.__is_volatile + + +# The following line should be: +# FieldType = TypeVar('FieldType', bound=int|IntEnum|SystemRDLEnum) +# However, python 3.9 does not support the combination so the binding was removed +# pylint: disable-next=invalid-name +FieldType = TypeVar('FieldType') +class Field(Generic[FieldType], Base, ABC): + """ + base class of register field wrappers + + Note: + It is not expected that this class will be instantiated under normal + circumstances however, it is useful for type checking + """ + + __slots__ = ['__size_props', '__misc_props', + '__bitmask', '__msb0', '__lsb0', '__field_type'] + + # pylint: disable-next=too-many-arguments + def __init__(self, *, + parent_register: BaseReg, size_props: FieldSizeProps, misc_props: FieldMiscProps, + logger_handle: str, inst_name: str, field_type:type[FieldType]): + + super().__init__(logger_handle=logger_handle, + inst_name=inst_name, parent=parent_register) + + if not isinstance(size_props, FieldSizeProps): + raise TypeError(f'size_props must be of {type(FieldSizeProps)} ' + f'but got {type(size_props)}') + self.__size_props = size_props + + if not isinstance(misc_props, FieldMiscProps): + raise TypeError(f'misc_props must be of {type(FieldMiscProps)} ' + f'but got {type(misc_props)}') + self.__misc_props = misc_props + + if not isinstance(parent_register, BaseReg): + raise TypeError(f'parent_register must be of {type(BaseReg)} ' + f'but got {type(parent_register)}') + + if self.width > self.register_data_width: + raise ValueError('width can not be greater than parent width') + + if self.high > self.register_data_width: + raise ValueError(f'field high bit position {self.high:d} must be less than the ' + f'parent register width ({self.register_data_width:d})') + + if self.low > self.register_data_width: + raise ValueError('field lsb must be less than the parent ' + 'register width') + + if self.high - self.low + 1 != self.width: + raise ValueError('field width defined by lsb and msb does not match' + ' specified width') + + if (self.msb == self.high) and (self.lsb == self.low): + self.__lsb0 = True + self.__msb0 = False + elif (self.msb == self.low) and (self.lsb == self.high): + self.__lsb0 = False + self.__msb0 = True + else: + raise ValueError('msb/lsb are inconsistent with low/high') + + self.__bitmask = 0 + for bit_position in range(self.low, self.high+1): + self.__bitmask |= (1 << bit_position) + + if not issubclass(field_type, (int, IntEnum, SystemRDLEnum)): + raise TypeError(f'Unsupported field type: {field_type}') + self.__field_type = field_type + + @property + def lsb(self) -> int: + """ + bit position of the least significant bit (lsb) of the field in the + parent register + + Note: + fields can be defined as msb in bit 0 or as lsb in bit 0 + """ + return self.__size_props.lsb + + @property + def msb(self) -> int: + """ + bit position of the most significant bit (msb) of the field in the + parent register + + Note: + fields can be defined as msb in bit 0 or as lsb in bit 0 + """ + return self.__size_props.msb + + @property + def width(self) -> int: + """ + The width of the field in bits + """ + return self.__size_props.width + + @property + def max_value(self) -> int: + """maximum unsigned integer value that can be stored in the field + + For example: + + * 8-bit field returns 0xFF (255) + * 16-bit field returns 0xFFFF (65535) + * 32-bit field returns 0xFFFF_FFFF (4294967295) + + """ + return (2 ** self.width) - 1 + + @property + def high(self) -> int: + """ + low index of the bit range of the field in the + parent register + + Note: + The first bit in the register is bit 0 + """ + return self.__size_props.high + + @property + def low(self) -> int: + """ + low index of the bit range of the field in the + parent register + + Note: + The first bit in the register is bit 0 + """ + return self.__size_props.low + + @property + def bitmask(self) -> int: + """ + The bit mask needed to extract the field from its register + + For example a register field occupying bits 7 to 4 in a 16-bit register + will have a bit mask of 0x00F0 + """ + return self.__bitmask + + @property + def register_data_width(self) -> int: + """ + The width of the register within which the field resides in bits + """ + return self.__parent_register.width + + @property + def inverse_bitmask(self) -> int: + """ + The bitwise inverse of the bitmask needed to extract the field from its + register + + For example a register field occupying bits 7 to 4 in a 16-bit register + will have a inverse bit mask of 0xFF0F + """ + return self.__parent_register.max_value ^ self.bitmask + + @property + def msb0(self) -> bool: + """ + The field can either be lsb0 or msb0 + + Returns: true if msb0 + + """ + return self.__msb0 + + @property + def lsb0(self) -> bool: + """ + The field can either be lsb0 or msb0 + + Returns: true if lsb0 + + """ + return self.__lsb0 + + @property + def default(self) -> Optional[FieldType]: + """ + The default value of the field + + This returns None: + - if the field is not reset. + - if the register resets to a signal value that can not be determined + """ + if issubclass(self._field_type, (SystemRDLEnum, IntEnum)): + int_default = self.__misc_props.default + + if int_default is not None: + if int_default not in [item.value for item in self._field_type]: + # this is a special case which can occur if the default value of the register + # does not cover the enum + msg = f'reset value {int_default:d} is not within the enumeration for the class' + self._logger.warning(msg) + warnings.warn(msg) + return None + + return_value = self._field_type(int_default) + return return_value # type: ignore[return-value] + + return None + + return self.__misc_props.default # type: ignore[return-value] + + @property + def is_volatile(self) -> bool: + """ + The HW volatility of the field + """ + return self.__misc_props.is_volatile + + @property + def __parent_register(self) -> BaseReg: + """ + parent register the field is placed in + """ + # this cast is OK because an explict typing check was done in the __init__ + return cast(BaseReg, self.parent) + + @property + def _field_type(self) -> type[FieldType]: + return self.__field_type # type: ignore[return-value] + + +class _FieldReadOnlyFramework(Field[FieldType], ABC): + """ + base class for a async or normal read only register field + """ + __slots__ : list[str] = [] + + def decode_read_value(self, value: int) -> FieldType: + """ + extracts the field value from a register value, by applying the bit + mask and shift needed + + Args: + value: value to decode, normally read from a register + + Returns: + field value + + Warning: + This method will be removed from a future version, if you have a compelling use + case for it please add a comment to the #184 ticket + + """ + # end users should not need access to the `decode_read_value` as the decoding is done + # for them, it felt like an anomaly that this was public, see #184 + warnings.warn('decode_read_value will be made private in a future version', + DeprecationWarning, stacklevel=2) + return self._decode_read_value(value=value) + + def _decode_read_value(self, value: int) -> FieldType: + """ + extracts the field value from a register value, by applying the bit + mask and shift needed + + Args: + value: value to decode, normally read from a register + + Returns: + field value + """ + if not isinstance(value, int): + raise TypeError(f'value must be an int but got {type(value)}') + + if value < 0: + raise ValueError('value to be decoded must be greater ' + 'than or equal to 0') + + if value > self.__parent_register.max_value: + raise ValueError(f'value to bede coded must be less than or equal ' + f'to {self.__parent_register.max_value:d}') + + if self.msb0 is False: + return_int_value = (value & self.bitmask) >> self.low + else: + return_int_value = swap_msb_lsb_ordering(value=(value & self.bitmask) >> self.low, + width=self.width) + + if issubclass(self._field_type, (SystemRDLEnum, IntEnum)): + return self._field_type(return_int_value) # type: ignore[return-value] + if issubclass(self._field_type, int): + return return_int_value # type: ignore[return-value] + + raise TypeError(f'unhandled field_type: {self._field_type}') + + + @property + def __parent_register(self) -> BaseReg: + """ + parent register the field is placed in + """ + # this cast is OK because an explict typing check was done in the __init__ + return cast(BaseReg, self.parent) + + +class _FieldWriteOnlyFramework(Field[FieldType], ABC): + """ + class for a write only register field + """ + __slots__ : list[str] = [] + + def _write_value_checks(self, value: int) -> None: + """ + Carries out the value for the encode_write_value and write methods + + Args: + value: proposed value to write + """ + if not isinstance(value, int): + raise TypeError(f'value must be an int but got {type(value)}') + + if value < 0: + raise ValueError('value to be written to register must be greater ' + 'than or equal to 0') + + if value > self.max_value: + raise ValueError(f'value to be written to register must be less ' + f'than or equal to {self.max_value:d}') + + + def encode_write_value(self, value: FieldType) -> int: + """ + Check that a value is legal for the field and then encode it in preparation to be written + to the register + + Args: + value: field value + + Returns: + value which can be applied to the register to update the field + + Warning: + This method will be removed from a future version, if you have a compelling use + case for it please add a comment to the #184 ticket + + """ + # end users should not need access to the `decode_read_value` as the decoding is done + # for them, it felt like an anomaly that this was public, see #184 + warnings.warn('encode_write_value will be made private in a future version', + DeprecationWarning, stacklevel=2) + return self._encode_write_value(value=value) + + def _encode_write_value(self, value: FieldType) -> int: + """ + Check that a value is legal for the field and then encode it in preparation to be written + to the register + + Args: + value: field value + + Returns: + value which can be applied to the register to update the field + + """ + if not isinstance(value, self._field_type): + raise TypeError(f'Field type is not as expected, got {type(value)},' + f' expected {self._field_type}') + + if isinstance(value, (SystemRDLEnum, IntEnum)): + int_value = value.value + elif isinstance(value, int): + int_value = value + else: + raise RuntimeError('Unhandled type configuration') + + self._write_value_checks(value=int_value) + + if self.msb0 is False: + return_value = int_value << self.low + else: + return_value = swap_msb_lsb_ordering(value=int_value, width=self.width) << self.low + + return return_value + + +class FieldEnum(Field[FieldType], ABC): + """ + class for a register field with an enumerated value + """ + __slots__: list[str] = [] + + @property + def enum_cls(self) -> type[FieldType]: + """ + The enumeration class for this field + """ + return self._field_type diff --git a/rdl/outputs/python/msk_top_regs/lib/base_register.py b/rdl/outputs/python/msk_top_regs/lib/base_register.py new file mode 100644 index 0000000..e854a86 --- /dev/null +++ b/rdl/outputs/python/msk_top_regs/lib/base_register.py @@ -0,0 +1,229 @@ +""" +peakrdl-python is a tool to generate Python Register Access Layer (RAL) from SystemRDL +Copyright (C) 2021 - 2023 + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +This module is intended to distributed as part of automatically generated code by the +peakrdl-python tool. It provides a set of classes used by the autogenerated code to represent +registers +""" +from typing import Union, Optional, TypeVar +from abc import ABC, abstractmethod + + +from .base import Node, AddressMap, RegFile, NodeArray +from .utility_functions import legal_register_width +from .base import AsyncAddressMap, AsyncRegFile +from .memory import BaseMemory + + +class RegisterWriteVerifyError(Exception): + """ + Exception that occurs when the read after a write does not match the expected value + """ + + +class BaseReg(Node, ABC): + """ + base class of register wrappers + + Note: + It is not expected that this class will be instantiated under normal + circumstances however, it is useful for type checking + """ + + __slots__: list[str] = ['__width', '__accesswidth'] + + # pylint: disable=too-many-arguments,duplicate-code + def __init__(self, *, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AddressMap, AsyncAddressMap, RegFile, AsyncRegFile, BaseMemory, + 'BaseRegArray']): + + super().__init__(address=address, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + if not isinstance(width, int): + raise TypeError(f'width should be int but got {(type(width))}') + if not legal_register_width(width_in_bits=width): + raise ValueError(f'Unsupported register width {width:d}') + self.__width = width + if not isinstance(accesswidth, int): + raise TypeError(f'accesswidth should be int but got {(type(accesswidth))}') + if not legal_register_width(width_in_bits=accesswidth): + raise ValueError(f'Unsupported access width {accesswidth:d}') + self.__accesswidth = accesswidth + # pylint: enable=too-many-arguments,duplicate-code + + @property + def max_value(self) -> int: + """ + maximum unsigned integer value that can be stored in the register + + For example: + + * 8-bit register returns 0xFF (255) + * 16-bit register returns 0xFFFF (65535) + * 32-bit register returns 0xFFFF_FFFF (4294967295) + + """ + return (2 ** self.width) - 1 + + def _validate_data(self, data: int) -> None: + """ + Check that the data parameter is of valid type and range + """ + if not isinstance(data, int): + raise TypeError(f'data should be an int got {type(data)}') + + if data > self.max_value: + raise ValueError('data out of range') + + if data < 0: + raise ValueError('data out of range') + + @property + def width(self) -> int: + """ + The width of the register in bits, this uses the `regwidth` systemRDL property + """ + return self.__width + + @property + def accesswidth(self) -> int: + """ + The access width of the register in bits, this uses the `accesswidth` systemRDL property + """ + return self.__accesswidth + + @property + def size(self) -> int: + """ + Total Number of bytes of address the node occupies + """ + return self.__width >> 3 + + @property + @abstractmethod + def _is_readable(self) -> bool: + ... + + @property + @abstractmethod + def _is_writeable(self) -> bool: + ... + +# pylint: disable-next=invalid-name +BaseRegArrayElementType= TypeVar('BaseRegArrayElementType', bound=BaseReg) + + +class BaseRegArray(NodeArray[BaseRegArrayElementType], ABC): + """ + base class of register array wrappers (async and non-async) + + Note: + It is not expected that this class will be instantiated under normal + circumstances however, it is useful for type checking + """ + # pylint: disable=too-many-arguments,duplicate-code + + __slots__: list[str] = ['__width', '__accesswidth'] + + def __init__(self, *, + logger_handle: str, inst_name: str, + parent: Union[AddressMap, AsyncAddressMap, RegFile, AsyncRegFile, BaseMemory], + width: int, + accesswidth: int, + address: int, + stride: int, + dimensions: tuple[int, ...], + elements: Optional[dict[tuple[int, ...], BaseRegArrayElementType]] = None): + + if not isinstance(width, int): + raise TypeError(f'width should be int but got {(type(width))}') + if not legal_register_width(width_in_bits=width): + raise ValueError(f'Unsupported register width {width:d}') + self.__width = width + if not isinstance(accesswidth, int): + raise TypeError(f'accesswidth should be int but got {(type(accesswidth))}') + if not legal_register_width(width_in_bits=accesswidth): + raise ValueError(f'Unsupported access width {accesswidth:d}') + self.__accesswidth = accesswidth + + if not issubclass(self._element_datatype, BaseReg): + raise TypeError(f'{self._element_datatype}') + + super().__init__(logger_handle=logger_handle, inst_name=inst_name, + parent=parent, address=address, + stride=stride, dimensions=dimensions, elements=elements) + + @property + def width(self) -> int: + """ + The width of the register in bits, this uses the `regwidth` systemRDL property + """ + return self.__width + + @property + def accesswidth(self) -> int: + """ + The access width of the register in bits, this uses the `accesswidth` systemRDL property + """ + return self.__accesswidth + + def _build_element(self, indices: tuple[int, ...]) -> BaseRegArrayElementType: + + return self._element_datatype( + logger_handle=self._build_element_logger_handle(indices=indices), + address=self._address_calculator(indices), + inst_name=self._build_element_inst_name(indices=indices), + width=self.width, + accesswidth=self.accesswidth, + parent=self) + + def _sub_instance(self, elements: dict[tuple[int, ...], BaseRegArrayElementType]) ->\ + NodeArray[BaseRegArrayElementType]: + if not isinstance(self.parent, (AddressMap, AsyncAddressMap, RegFile, + AsyncRegFile, BaseMemory)): + raise RuntimeError('Parent of a Node Array must be Node') + return self.__class__(logger_handle=self._logger.name, + inst_name=self.inst_name, + parent=self.parent, + address=self.address, + width=self.width, + accesswidth=self.accesswidth, + stride=self.stride, + dimensions=self.dimensions, + elements=elements) + + @property + @abstractmethod + def _element_datatype(self) -> type[BaseRegArrayElementType]: + ... + + @property + @abstractmethod + def _is_readable(self) -> bool: + ... + + @property + @abstractmethod + def _is_writeable(self) -> bool: + ... diff --git a/rdl/outputs/python/msk_top_regs/lib/callbacks.py b/rdl/outputs/python/msk_top_regs/lib/callbacks.py new file mode 100644 index 0000000..8c8b541 --- /dev/null +++ b/rdl/outputs/python/msk_top_regs/lib/callbacks.py @@ -0,0 +1,363 @@ +""" +peakrdl-python is a tool to generate Python Register Access Layer (RAL) from SystemRDL +Copyright (C) 2021 - 2023 + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +This module is intended to distributed as part of automatically generated code by the +peakrdl-python tool. It provides a set of types used by the autogenerated code to callbacks +""" +from array import array as Array + +from typing import Optional, Union +from typing import Protocol + + +class ReadCallback(Protocol): + """ + Callback definition for a single register read operation + """ + # pylint: disable=too-few-public-methods + def __call__(self, addr: int, width: int, accesswidth: int) -> int: + pass + + +class WriteCallback(Protocol): + """ + Callback definition for a single register write operation + """ + # pylint: disable=too-few-public-methods + def __call__(self, addr: int, width: int, accesswidth: int, data: int) -> None: + pass + + +class ReadBlockLegacyCallback(Protocol): + """ + Callback definition for a block read operation + """ + # pylint: disable=too-few-public-methods + def __call__(self, addr: int, width: int, accesswidth: int, length: int) -> Array: + pass + +class ReadBlockCallback(Protocol): + """ + Callback definition for a block read operation + """ + # pylint: disable=too-few-public-methods + def __call__(self, addr: int, width: int, accesswidth: int, length: int) -> list[int]: + pass + + +class WriteBlockCallback(Protocol): + """ + Callback definition for a block write operation + """ + # pylint: disable=too-few-public-methods + def __call__(self, addr: int, width: int, accesswidth: int, data: list[int]) -> None: + pass + + +class WriteBlockLegacyCallback(Protocol): + """ + Callback definition for a block write operation + """ + # pylint: disable=too-few-public-methods + def __call__(self, addr: int, width: int, accesswidth: int, data: Array) -> None: + pass + + +class AsyncReadCallback(Protocol): + """ + Callback definition for a single register async read operation + """ + # pylint: disable=too-few-public-methods,unexpected-special-method-signature + async def __call__(self, addr: int, width: int, accesswidth: int) -> int: + pass + + +class AsyncWriteCallback(Protocol): + """ + Callback definition for a single register async write operation + """ + # pylint: disable=too-few-public-methods,unexpected-special-method-signature + async def __call__(self, addr: int, width: int, accesswidth: int, data: int) -> None: + pass + + +class AsyncReadBlockCallback(Protocol): + """ + Callback definition for an async block read operation + """ + # pylint: disable=too-few-public-methods,unexpected-special-method-signature + async def __call__(self, addr: int, width: int, accesswidth: int, length: int) -> list[int]: + pass + +class AsyncReadBlockLegacyCallback(Protocol): + """ + Callback definition for an async block read operation + """ + # pylint: disable=too-few-public-methods,unexpected-special-method-signature + async def __call__(self, addr: int, width: int, accesswidth: int, length: int) -> Array: + pass + + +class AsyncWriteBlockCallback(Protocol): + """ + Callback definition for an async block write operation + """ + # pylint: disable=too-few-public-methods,unexpected-special-method-signature + async def __call__(self, addr: int, width: int, accesswidth: int, data: list[int]) -> None: + pass + +class AsyncWriteBlockLegacyCallback(Protocol): + """ + Callback definition for an async block write operation + """ + # pylint: disable=too-few-public-methods,unexpected-special-method-signature + async def __call__(self, addr: int, width: int, accesswidth: int, data: Array) -> None: + pass + + +class _NormalCallbackSetBase: + """ + Class to hold a set of callbacks, this reduces the number of callback that need to be passed + around + """ + + __slots__ = ['__write_callback', '__read_callback'] + + def __init__(self, + write_callback: Optional[WriteCallback] = None, + read_callback: Optional[ReadCallback] = None): + + self.__read_callback = read_callback + self.__write_callback = write_callback + + @property + def read_callback(self) -> Optional[ReadCallback]: + """ + single read callback function + + Returns: call back function + + """ + return self.__read_callback + + @property + def write_callback(self) -> Optional[WriteCallback]: + """ + single write callback function + + Returns: call back function + + """ + return self.__write_callback + + +class NormalCallbackSet(_NormalCallbackSetBase): + """ + Class to hold a set of callbacks, this reduces the number of callback that need to be passed + around + """ + + __slots__ = ['__write_block_callback', '__read_block_callback'] + + def __init__(self, + write_callback: Optional[WriteCallback] = None, + read_callback: Optional[ReadCallback] = None, + write_block_callback: Optional[WriteBlockCallback] = None, + read_block_callback: Optional[ReadBlockCallback] = None): + + super().__init__(read_callback=read_callback, write_callback=write_callback) + + self.__read_block_callback = read_block_callback + self.__write_block_callback = write_block_callback + + @property + def read_block_callback(self) -> Optional[ReadBlockCallback]: + """ + block read callback function + + Returns: call back function + + """ + return self.__read_block_callback + + @property + def write_block_callback(self) -> Optional[WriteBlockCallback]: + """ + block read callback function + + Returns: call back function + + """ + return self.__write_block_callback + + +class NormalCallbackSetLegacy(_NormalCallbackSetBase): + """ + Class to hold a set of callbacks, this reduces the number of callback that need to be passed + around + """ + + __slots__ = ['__write_block_callback', '__read_block_callback'] + + def __init__(self, + write_callback: Optional[WriteCallback] = None, + read_callback: Optional[ReadCallback] = None, + write_block_callback: Optional[WriteBlockLegacyCallback] = None, + read_block_callback: Optional[ReadBlockLegacyCallback] = None): + + super().__init__(read_callback=read_callback, write_callback=write_callback) + + self.__read_block_callback = read_block_callback + self.__write_block_callback = write_block_callback + + @property + def read_block_callback(self) -> Optional[ReadBlockLegacyCallback]: + """ + block read callback function + + Returns: call back function + + """ + return self.__read_block_callback + + @property + def write_block_callback(self) -> Optional[WriteBlockLegacyCallback]: + """ + block read callback function + + Returns: call back function + + """ + return self.__write_block_callback + +class _AsyncCallbackSetBase: + """ + Class to hold a set of callbacks, this reduces the number of callback that need to be passed + around + """ + + __slots__ = ['__write_callback', '__read_callback'] + + def __init__(self, + write_callback: Optional[AsyncWriteCallback] = None, + read_callback: Optional[AsyncReadCallback] = None): + + self.__read_callback = read_callback + self.__write_callback = write_callback + + @property + def read_callback(self) -> Optional[AsyncReadCallback]: + """ + single read callback function + + Returns: call back function + + """ + return self.__read_callback + + @property + def write_callback(self) -> Optional[AsyncWriteCallback]: + """ + single write callback function + + Returns: call back function + + """ + return self.__write_callback + + +class AsyncCallbackSet(_AsyncCallbackSetBase): + """ + Class to hold a set of callbacks, this reduces the number of callback that need to be passed + around + """ + + __slots__ = ['__write_block_callback', '__read_block_callback'] + + def __init__(self, + write_callback: Optional[AsyncWriteCallback] = None, + read_callback: Optional[AsyncReadCallback] = None, + write_block_callback: Optional[AsyncWriteBlockCallback] = None, + read_block_callback: Optional[AsyncReadBlockCallback] = None): + + super().__init__(read_callback=read_callback, write_callback=write_callback) + + self.__read_block_callback = read_block_callback + self.__write_block_callback = write_block_callback + + @property + def read_block_callback(self) -> Optional[AsyncReadBlockCallback]: + """ + block read callback function + + Returns: call back function + + """ + return self.__read_block_callback + + @property + def write_block_callback(self) -> Optional[AsyncWriteBlockCallback]: + """ + block read callback function + + Returns: call back function + + """ + return self.__write_block_callback + + +class AsyncCallbackSetLegacy(_AsyncCallbackSetBase): + """ + Class to hold a set of callbacks, this reduces the number of callback that need to be passed + around + """ + + __slots__ = ['__write_block_callback', '__read_block_callback'] + + def __init__(self, + write_callback: Optional[AsyncWriteCallback] = None, + read_callback: Optional[AsyncReadCallback] = None, + write_block_callback: Optional[AsyncWriteBlockLegacyCallback] = None, + read_block_callback: Optional[AsyncReadBlockLegacyCallback] = None): + super().__init__(read_callback=read_callback, write_callback=write_callback) + + self.__read_block_callback = read_block_callback + self.__write_block_callback = write_block_callback + + @property + def read_block_callback(self) -> Optional[AsyncReadBlockLegacyCallback]: + """ + block read callback function + + Returns: call back function + + """ + return self.__read_block_callback + + @property + def write_block_callback(self) -> Optional[AsyncWriteBlockLegacyCallback]: + """ + block read callback function + + Returns: call back function + + """ + return self.__write_block_callback + + +CallbackSet = Union[AsyncCallbackSet, NormalCallbackSet] +CallbackSetLegacy = Union[AsyncCallbackSetLegacy, NormalCallbackSetLegacy] diff --git a/rdl/outputs/python/msk_top_regs/lib/field_encoding.py b/rdl/outputs/python/msk_top_regs/lib/field_encoding.py new file mode 100644 index 0000000..44d4068 --- /dev/null +++ b/rdl/outputs/python/msk_top_regs/lib/field_encoding.py @@ -0,0 +1,80 @@ +""" +peakrdl-python is a tool to generate Python Register Access Layer (RAL) from SystemRDL +Copyright (C) 2021 - 2023 + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +This module is intended to distributed as part of automatically generated code by the +peakrdl-python tool. It provides the base types of field enumerations +""" +from enum import Enum +from typing import Optional +from collections import namedtuple +from json import JSONEncoder + +SystemRDLEnumEntry = namedtuple('SystemRDLEnumEntry', ['int_value', 'name', 'desc']) + +class SystemRDLEnum(Enum): + """ + A Enumeration that can also hold the system RDL properties, notably the `name` and `desc + """ + @property + def _full_value(self) -> SystemRDLEnumEntry: + """ The full field value (needed to some operation) """ + return super().value + + @property + # pylint:disable-next=invalid-overridden-method + def value(self) -> int: + """ The integer value used to encode the field value """ + return super().value.int_value + + @property + def rdl_name(self) -> Optional[str]: + """ + The systemRDL name property for the encoding entry + """ + return super().value.name + + @property + def rdl_desc(self) -> Optional[str]: + """ + The systemRDL name property for the encoding entry + """ + return super().value.desc + + @classmethod + def _missing_(cls, value): # type: ignore[no-untyped-def] + + if isinstance(value, int): + # pylint:disable-next=protected-access,no-member + int_mapping = {item.value: item._full_value for item in cls._member_map_.values()} + if value not in int_mapping: + raise ValueError(f'Enumeration has not integer value of {value}') + return cls(int_mapping[value]) + + return None + + def __str__(self) -> str: + return self.name + +class RegisterFieldJSONEncoder(JSONEncoder): + """ + JSON Encoder that supports SystemRDLEnum + """ + def default(self, o): # type: ignore[no-untyped-def] + if isinstance(o, SystemRDLEnum): + return o.name + # Let the base class default method raise the TypeError + return super().default(o) diff --git a/rdl/outputs/python/msk_top_regs/lib/memory.py b/rdl/outputs/python/msk_top_regs/lib/memory.py new file mode 100644 index 0000000..2ab3a7d --- /dev/null +++ b/rdl/outputs/python/msk_top_regs/lib/memory.py @@ -0,0 +1,752 @@ +""" +peakrdl-python is a tool to generate Python Register Access Layer (RAL) from SystemRDL +Copyright (C) 2021 - 2023 + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +This module is intended to distributed as part of automatically generated code by the +peakrdl-python tool. It provides a set of classes used by the autogenerated code to represent +memories +""" +from array import array as Array +from typing import Union, TYPE_CHECKING +from collections.abc import Iterator +from abc import ABC, abstractmethod +import sys + +from .base import Node, AddressMap, AsyncAddressMap, NodeArray +from .utility_functions import get_array_typecode + +from .callbacks import NormalCallbackSet, NormalCallbackSetLegacy + +# same bit of code exists in base so flags as duplicate +# pylint: disable=duplicate-code +if sys.version_info >= (3, 10): + # type guarding was introduced in python 3.10 + from typing import TypeGuard +else: + from typing_extensions import TypeGuard +# pylint: enable=duplicate-code + + +if TYPE_CHECKING: + from .register_and_field import Reg, RegArray + from .register_and_field import ReadableRegister, WritableRegister + from .register_and_field import ReadableRegisterArray, WriteableRegisterArray + from .async_memory import AsyncMemoryArray + +# pylint: disable=duplicate-code + + +class BaseMemory(Node, ABC): + """ + base class of memory wrappers + + Note: + It is not expected that this class will be instantiated under normal + circumstances however, it is useful for type checking + """ + + __slots__: list[str] = ['__memwidth', '__entries', '__accesswidth'] + + # pylint: disable=too-many-arguments + def __init__(self, *, + address: int, + width: int, + accesswidth: int, + entries: int, + logger_handle: str, + inst_name: str, + parent: Union[AddressMap, AsyncAddressMap, 'MemoryArray', 'AsyncMemoryArray']): + """ + Initialise the class + + Args: + address: address of the register + width: width of the register in bits + logger_handle: name to be used logging messages associate with this object + """ + super().__init__(address=address, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + self.__memwidth = width + self.__entries = entries + self.__accesswidth = accesswidth + # pylint: enable=too-many-arguments + + @property + def width(self) -> int: + """ + The width of the memory in bits, this uses the `memwidth` systemRDL property + + Returns: memory width + + """ + return self.__memwidth + + @property + def width_in_bytes(self) -> int: + """ + The width of the memory bytes, i.e. the width in bits divided by 8 + + Returns: memory width (in bytes) + + """ + def roundup_pow2(x: int) -> int: + return 1 << (x - 1).bit_length() + + return roundup_pow2(self.width) // 8 + + @property + def entries(self) -> int: + """ + The number of entries in the memory, this uses the `mementries` systemRDL property + + Returns: memory entries + + """ + return self.__entries + + @property + def array_typecode(self) -> str: + """ + the python array.array type is initialised with a typecode. This property provides the + recommended typecode to use with this class instance (based on the memwidth) + + Returns: typecode + + """ + return get_array_typecode(self.width) + + @property + def size(self) -> int: + """ + Total Number of bytes of address the node occupies + """ + return self.entries * self.width_in_bytes + + def address_lookup(self, entry: int) -> int: + """ + provides the address for an entry in the memory. + + Examples + + Args: + entry: entry number to look up the address for + + Returns: Address + + """ + if not isinstance(entry, int): + raise TypeError(f'entry must be an int but got {type(entry)}') + + if entry not in range(0, self.entries): + raise ValueError(f'entry must be in range 0 to {self.entries-1:d} but got {entry:d}') + + return self.address + (entry * self.width_in_bytes) + + @property + def accesswidth(self) -> int: + """ + The access width of the register in bits, this uses the `accesswidth` systemRDL property + + Returns: register access width + """ + return self.__accesswidth + + +class Memory(BaseMemory, ABC): + """ + base class of non_async memory wrappers + + Note: + It is not expected that this class will be instantiated under normal + circumstances however, it is useful for type checking + """ + __slots__: list[str] = [] + + # pylint: disable=too-many-arguments + def __init__(self, *, + address: int, + width: int, + accesswidth: int, + entries: int, + logger_handle: str, + inst_name: str, + parent: Union[AddressMap, 'MemoryArray']): + """ + Initialise the class + + Args: + address: address of the register + width: width of the register in bits + logger_handle: name to be used logging messages associate with this object + """ + if not isinstance(parent, (AddressMap, + MemoryWriteOnlyArray, MemoryReadOnlyArray, + MemoryReadWriteArray)): + raise TypeError(f'parent should be either AddressMap or Memory Array got ' + f'{type(parent)}') + super().__init__(address=address, + logger_handle=logger_handle, + inst_name=inst_name, + width=width, + accesswidth=accesswidth, + entries=entries, + parent=parent) + + @abstractmethod + def get_registers(self, unroll: bool = False) -> \ + Iterator[Union['Reg', 'RegArray']]: + """ + generator that produces all the readable_registers of this node + + Args: + unroll: Whether to unroll child array or not + """ + + +class _MemoryReadOnly(Memory, ABC): + """ + base class of memory wrappers + + Note: + It is not expected that this class will be instantiated under normal + circumstances however, it is useful for type checking + """ + + __slots__: list[str] = [] + + # pylint: disable-next=too-many-arguments + def __init__(self, *, + address: int, + width: int, + accesswidth: int, + entries: int, + logger_handle: str, + inst_name: str, + parent: Union[AddressMap, 'MemoryArray']): + + if parent is None: + raise TypeError('parent should be either AddressMap or Memory Array ' + f'got {type(parent)}') + + if not isinstance(parent, (AddressMap, MemoryWriteOnlyArray, + MemoryReadOnlyArray, MemoryReadWriteArray)): + raise TypeError('parent should be either AddressMap or Memory Array ' + f'got {type(parent)}') + + if not isinstance(parent._callbacks, (NormalCallbackSet, NormalCallbackSetLegacy)): + raise TypeError(f'callback set type is wrong, got {type(parent._callbacks)}') + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + entries=entries, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # pylint: enable=too-many-arguments + @property + def _callbacks(self) -> Union[NormalCallbackSet, NormalCallbackSetLegacy]: + # pylint: disable=protected-access + if self.parent is None: + raise RuntimeError('Parent must be set') + + if isinstance(self.parent._callbacks, (NormalCallbackSet, NormalCallbackSetLegacy)): + return self.parent._callbacks + + raise TypeError(f'unhandled parent callback type: {type(self.parent._callbacks)}') + + def _read(self, start_entry: int, number_entries: int) -> list[int]: + """ + Read from the memory + + Args: + start_entry: index in the memory to start from, this is not the address + number_entries: number of entries to read + + Returns: data read from memory + + """ + + if not isinstance(start_entry, int): + raise TypeError(f'start_entry should be an int got {type(start_entry)}') + + if not isinstance(number_entries, int): + raise TypeError(f'number_entries should be an int got {type(number_entries)}') + + if start_entry not in range(0, self.entries): + raise ValueError(f'entry must be in range 0 to {self.entries - 1:d} ' + f'but got {start_entry:d}') + + if number_entries not in range(0, self.entries - start_entry + 1): + raise ValueError(f'number_entries must be in range 0 to' + f' {self.entries - start_entry:d} but got {number_entries:d}') + + read_block_callback = self._callbacks.read_block_callback + read_callback = self._callbacks.read_callback + + if read_block_callback is not None: + addr = self.address_lookup(entry=start_entry) + data_read = \ + read_block_callback(addr=addr, + width=self.width, + accesswidth=self.width, + length=number_entries) + + if isinstance(self._callbacks, NormalCallbackSet): + if not isinstance(data_read, list): + if isinstance(data_read, Array): + raise TypeError( + 'The read block callback is expected to return an list, this ' + 'is likely to happen if you are using legacy callbacks without ' + 'NormalCallbackSetLegacy') + raise TypeError('The read block callback is expected to return an List') + return data_read + + if isinstance(self._callbacks, NormalCallbackSetLegacy): + if not isinstance(data_read, Array): + raise TypeError('The read block callback is expected to return an array') + return data_read.tolist() + + raise RuntimeError(f'There is no usable callback block callback:{read_block_callback}') + + if read_callback is not None: + # there is not read_block_callback defined so we must used individual read + data_read = [0 for _ in range(number_entries)] + + for entry in range(number_entries): + entry_address = self.address_lookup(entry=start_entry+entry) + data_entry = read_callback(addr=entry_address, + width=self.width, + accesswidth=self.width) + + data_read[entry] = data_entry + + return data_read + + raise RuntimeError(f'There is no usable callback, ' + f'block callback:{read_block_callback}, ' + f'normal callback:{read_callback}') + + def _read_legacy(self, start_entry: int, number_entries: int) -> Array: + """ + Read from the memory + + Args: + start_entry: index in the memory to start from, this is not the address + number_entries: number of entries to read + + Returns: data read from memory + + """ + + if not isinstance(start_entry, int): + raise TypeError(f'start_entry should be an int got {type(start_entry)}') + + if not isinstance(number_entries, int): + raise TypeError(f'number_entries should be an int got {type(number_entries)}') + + if start_entry not in range(0, self.entries): + raise ValueError(f'entry must be in range 0 to {self.entries - 1:d} ' + f'but got {start_entry:d}') + + if number_entries not in range(0, self.entries - start_entry + 1): + raise ValueError(f'number_entries must be in range 0 to' + f' {self.entries - start_entry:d} but got {number_entries:d}') + + read_block_callback = self._callbacks.read_block_callback + read_callback = self._callbacks.read_callback + + if read_block_callback is not None: + addr = self.address_lookup(entry=start_entry) + data_read = \ + read_block_callback(addr=addr, + width=self.width, + accesswidth=self.width, + length=number_entries) + + if isinstance(self._callbacks, NormalCallbackSet): + if not isinstance(data_read, list): + if isinstance(data_read, Array): + raise TypeError( + 'The read block callback is expected to return an list, this ' + 'is likely to happen if you are using legacy callbacks without ' + 'NormalCallbackSetLegacy') + raise TypeError('The read block callback is expected to return an List') + return Array(self.array_typecode, data_read) + + if isinstance(self._callbacks, NormalCallbackSetLegacy): + if not isinstance(data_read, Array): + raise TypeError('The read block callback is expected to return an array') + return data_read + + raise RuntimeError(f'There is no usable callback block callback:{read_block_callback}') + + if read_callback is not None: + # there is not read_block_callback defined so we must used individual read + data_read = Array(self.array_typecode, [0 for _ in range(number_entries)]) + + for entry in range(number_entries): + entry_address = self.address_lookup(entry=start_entry+entry) + data_entry = read_callback(addr=entry_address, + width=self.width, + accesswidth=self.width) + + data_read[entry] = data_entry + + return data_read + + raise RuntimeError(f'There is no usable callback, ' + f'block callback:{read_block_callback}, ' + f'normal callback:{read_callback}') + + def get_readable_registers(self, unroll: bool = False) -> \ + Iterator[Union['ReadableRegister', 'ReadableRegisterArray']]: + """ + generator that produces all the readable_registers of this node + + Args: + unroll: Whether to unroll child array or not + """ + def is_readable(item: Union['Reg', 'RegArray']) ->\ + TypeGuard[Union['ReadableRegister', 'ReadableRegisterArray']]: + # pylint: disable-next=protected-access + return item._is_readable + + return filter(is_readable, self.get_registers(unroll=unroll)) + + +class MemoryReadOnly(_MemoryReadOnly, ABC): + """ + base class of memory wrappers + + Note: + It is not expected that this class will be instantiated under normal + circumstances however, it is useful for type checking + """ + + __slots__: list[str] = [] + + def read(self, start_entry: int, number_entries: int) -> list[int]: + """ + Read from the memory + + Args: + start_entry: index in the memory to start from, this is not the address + number_entries: number of entries to read + + Returns: data read from memory + + """ + return self._read(start_entry=start_entry, number_entries=number_entries) + + +class MemoryReadOnlyLegacy(_MemoryReadOnly, ABC): + """ + base class of memory wrappers + + Note: + It is not expected that this class will be instantiated under normal + circumstances however, it is useful for type checking + """ + __slots__: list[str] = [] + + def read(self, start_entry: int, number_entries: int) -> Array: + """ + Read from the memory + + Args: + start_entry: index in the memory to start from, this is not the address + number_entries: number of entries to read + + Returns: data read from memory + + """ + return self._read_legacy(start_entry=start_entry, number_entries=number_entries) + + +class _MemoryWriteOnly(Memory, ABC): + """ + base class of memory wrappers + + Note: + It is not expected that this class will be instantiated under normal + circumstances however, it is useful for type checking + """ + __slots__: list[str] = [] + + # pylint: disable-next=too-many-arguments + def __init__(self, *, + address: int, + width: int, + accesswidth: int, + entries: int, + logger_handle: str, + inst_name: str, + parent: Union[AddressMap, 'MemoryArray']): + + if not isinstance(parent, (AddressMap, MemoryWriteOnlyArray, + MemoryReadOnlyArray, MemoryReadWriteArray)): + raise TypeError('parent should be either AddressMap or Memory Array ' + f'got {type(parent)}') + + if not isinstance(parent._callbacks, (NormalCallbackSet, NormalCallbackSetLegacy)): + raise TypeError(f'callback set type is wrong, got {type(parent._callbacks)}') + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + entries=entries, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # pylint: enable=too-many-arguments + @property + def _callbacks(self) -> Union[NormalCallbackSet, NormalCallbackSetLegacy]: + # pylint: disable=protected-access + if self.parent is None: + raise RuntimeError('Parent must be set') + + if isinstance(self.parent._callbacks, (NormalCallbackSet, NormalCallbackSetLegacy)): + return self.parent._callbacks + + raise TypeError(f'unhandled parent callback type: {type(self.parent._callbacks)}') + + def _write(self, start_entry: int, data: Union[Array, list[int]]) -> None: + """ + Write data to memory + + Args: + start_entry: index in the memory to start from, this is not the address + data: data to write + + Returns: None + + """ + # pylint:disable=too-many-branches + if not isinstance(start_entry, int): + raise TypeError(f'start_entry should be an int got {type(start_entry)}') + + if start_entry not in range(0, self.entries): + raise ValueError(f'entry must be in range 0 to {self.entries - 1:d} ' + f'but got {start_entry:d}') + + if not isinstance(data, (Array, list)): + raise TypeError(f'data should be an List or array.array got {type(data)}') + + if len(data) not in range(0, self.entries - start_entry + 1): + raise ValueError(f'data length must be in range 0 to {self.entries - start_entry:d} ' + f'but got {len(data):d}') + + if self._callbacks.write_block_callback is not None: + addr = self.address_lookup(entry=start_entry) + if isinstance(self._callbacks, NormalCallbackSet): + if isinstance(data, Array): + self._callbacks.write_block_callback(addr=addr, + width=self.width, + accesswidth=self.width, + data=data.tolist()) + else: + self._callbacks.write_block_callback(addr=addr, + width=self.width, + accesswidth=self.width, + data=data) + if isinstance(self._callbacks, NormalCallbackSetLegacy): + if isinstance(data, list): + # need to convert the data to an array before calling + self._callbacks.write_block_callback(addr=addr, + width=self.width, + accesswidth=self.width, + data=Array(self.array_typecode, data)) + else: + self._callbacks.write_block_callback(addr=addr, + width=self.width, + accesswidth=self.width, + data=data) + + elif self._callbacks.write_callback is not None: + # there is not write_block_callback defined so we must used individual write + for entry_index, entry_data in enumerate(data): + entry_address = self.address_lookup(entry=start_entry+entry_index) + self._callbacks.write_callback(addr=entry_address, + width=self.width, + accesswidth=self.width, + data=entry_data) + + else: + raise RuntimeError('No suitable callback') + + def get_writable_registers(self, unroll: bool = False) -> \ + Iterator[Union['WritableRegister', 'WriteableRegisterArray']]: + """ + generator that produces all the readable_registers of this node + + Args: + unroll: Whether to unroll child array or not + """ + def is_writable(item: Union['Reg', 'RegArray']) -> \ + TypeGuard[Union['WritableRegister', 'WriteableRegisterArray']]: + # pylint: disable-next=protected-access + return item._is_writeable + + return filter(is_writable, self.get_registers(unroll=unroll)) + + +class MemoryWriteOnly(_MemoryWriteOnly, ABC): + """ + base class of memory wrappers + + Note: + It is not expected that this class will be instantiated under normal + circumstances however, it is useful for type checking + """ + __slots__: list[str] = [] + + def write(self, start_entry: int, data: list[int]) -> None: + """ + Write data to memory + + Args: + start_entry: index in the memory to start from, this is not the address + data: data to write + + Returns: None + + """ + if not isinstance(data, list): + raise TypeError(f'data should be an List got {type(data)}') + return self._write(start_entry=start_entry, data=data) + + +class MemoryWriteOnlyLegacy(_MemoryWriteOnly, ABC): + """ + base class of memory wrappers + + Note: + It is not expected that this class will be instantiated under normal + circumstances however, it is useful for type checking + """ + __slots__: list[str] = [] + + def write(self, start_entry: int, data: Array) -> None: + """ + Write data to memory + + Args: + start_entry: index in the memory to start from, this is not the address + data: data to write + + Returns: None + + """ + if not isinstance(data, Array): + raise TypeError(f'data should be an Array {type(data)}') + return self._write(start_entry=start_entry, data=data) + + +class MemoryReadWrite(MemoryReadOnly, MemoryWriteOnly, ABC): + """ + base class of memory wrappers + + Note: + It is not expected that this class will be instantiated under normal + circumstances however, it is useful for type checking + """ + + __slots__: list[str] = [] + + +class MemoryReadWriteLegacy(MemoryReadOnlyLegacy, MemoryWriteOnlyLegacy, ABC): + """ + base class of memory wrappers + + Note: + It is not expected that this class will be instantiated under normal + circumstances however, it is useful for type checking + """ + + __slots__: list[str] = [] + + +class MemoryReadOnlyArray(NodeArray, ABC): + """ + base class for a array of read only memories + """ + __slots__: list[str] = [] + + # pylint: disable-next=too-many-arguments + def __init__(self, *, + logger_handle: str, inst_name: str, + parent: AddressMap, + address: int, + stride: int, + dimensions: tuple[int, ...]): + + super().__init__(logger_handle=logger_handle, inst_name=inst_name, + parent=parent, address=address, + stride=stride, dimensions=dimensions) + + +class MemoryWriteOnlyArray(NodeArray, ABC): + """ + base class for a array of write only memories + """ + __slots__: list[str] = [] + + # pylint: disable-next=too-many-arguments + def __init__(self, *, + logger_handle: str, inst_name: str, + parent: AddressMap, + address: int, + stride: int, + dimensions: tuple[int, ...]): + + super().__init__(logger_handle=logger_handle, inst_name=inst_name, + parent=parent, address=address, + stride=stride, dimensions=dimensions) + + +class MemoryReadWriteArray(MemoryReadOnlyArray, MemoryWriteOnlyArray, ABC): + """ + base class for a array of read and write memories + """ + __slots__: list[str] = [] + + # pylint: disable-next=too-many-arguments + def __init__(self, *, + logger_handle: str, inst_name: str, + parent: AddressMap, + address: int, + stride: int, + dimensions: tuple[int, ...]): + + if not isinstance(parent, AddressMap): + raise TypeError(f'parent should be either AddressMap got {type(parent)}') + + super().__init__(logger_handle=logger_handle, inst_name=inst_name, + parent=parent, address=address, + stride=stride, dimensions=dimensions) + + +ReadableMemory = Union[MemoryReadOnly, MemoryReadWrite] +WritableMemory = Union[MemoryWriteOnly, MemoryReadWrite] +ReadableMemoryLegacy = Union[MemoryReadOnlyLegacy, MemoryReadWriteLegacy] +WritableMemoryLegacy = Union[MemoryWriteOnlyLegacy, MemoryReadWriteLegacy] +MemoryArray = Union[MemoryReadOnlyArray, MemoryWriteOnlyArray, MemoryReadWriteArray] diff --git a/rdl/outputs/python/msk_top_regs/lib/register_and_field.py b/rdl/outputs/python/msk_top_regs/lib/register_and_field.py new file mode 100644 index 0000000..62df291 --- /dev/null +++ b/rdl/outputs/python/msk_top_regs/lib/register_and_field.py @@ -0,0 +1,1189 @@ +""" +peakrdl-python is a tool to generate Python Register Access Layer (RAL) from SystemRDL +Copyright (C) 2021 - 2023 + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +This module is intended to distributed as part of automatically generated code by the +peakrdl-python tool. It provides a set of classes used by the autogenerated code to represent +registers and fields +""" +from enum import Enum +from typing import Union, cast, Optional, TypeVar +from collections.abc import Generator, Iterator +from abc import ABC, abstractmethod +from contextlib import contextmanager +from array import array as Array +import sys +from warnings import warn + +from .base import AddressMap, RegFile +from .utility_functions import get_array_typecode +from .memory import MemoryReadOnly, MemoryWriteOnly, MemoryReadWrite, Memory, \ + ReadableMemory, WritableMemory +from .memory import MemoryReadOnlyLegacy, MemoryWriteOnlyLegacy, MemoryReadWriteLegacy +from .memory import ReadableMemoryLegacy, WritableMemoryLegacy +from .callbacks import NormalCallbackSet, NormalCallbackSetLegacy +from .base_register import BaseReg, BaseRegArray, RegisterWriteVerifyError +from .base_field import FieldEnum, FieldSizeProps, FieldMiscProps, \ + _FieldReadOnlyFramework, _FieldWriteOnlyFramework, FieldType + +# pylint: disable=duplicate-code +if sys.version_info >= (3, 11): + from typing import Self +else: + from typing_extensions import Self +# pylint: enable=duplicate-code + +# pylint: disable=duplicate-code +if sys.version_info >= (3, 10): + # type guarding was introduced in python 3.10 + from typing import TypeGuard +else: + from typing_extensions import TypeGuard +# pylint: enable=duplicate-code + +# pylint: disable=redefined-slots-in-subclass,too-many-lines + + +class Reg(BaseReg, ABC): + """ + base class of non-async register wrappers + + Note: + It is not expected that this class will be instantiated under normal + circumstances however, it is useful for type checking + """ + + __slots__: list[str] = [] + + # pylint: disable=too-many-arguments,duplicate-code + def __init__(self, *, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AddressMap, RegFile, Memory, 'RegArray']): + + if not isinstance(parent, (AddressMap, RegFile, + MemoryReadOnly, MemoryWriteOnly, MemoryReadWrite, RegArray, + MemoryReadOnlyLegacy, MemoryWriteOnlyLegacy, + MemoryReadWriteLegacy)): + raise TypeError(f'bad parent type got: {type(parent)}') + + if not isinstance(parent._callbacks, (NormalCallbackSet, NormalCallbackSetLegacy)): + raise TypeError(f'callback set type is wrong, got {type(parent._callbacks)}') + + super().__init__(address=address, width=width, accesswidth=accesswidth, + logger_handle=logger_handle, inst_name=inst_name, parent=parent) + + @property + def _callbacks(self) -> Union[NormalCallbackSet, NormalCallbackSetLegacy]: + # pylint: disable=protected-access + if self.parent is None: + raise RuntimeError('Parent must be set') + + if isinstance(self.parent._callbacks, (NormalCallbackSet, NormalCallbackSetLegacy)): + return self.parent._callbacks + + raise TypeError(f'unhandled parent callback type: {type(self.parent._callbacks)}') + + @property + @abstractmethod + def fields(self) -> Iterator[Union['FieldReadOnly', 'FieldWriteOnly', 'FieldReadWrite']]: + """ + generator that produces has all the fields within the register + """ + + +# pylint: disable-next=invalid-name +RegArrayElementType= TypeVar('RegArrayElementType', bound=BaseReg) + + +class RegArray(BaseRegArray, ABC): + """ + base class of register array wrappers + + Note: + It is not expected that this class will be instantiated under normal + circumstances however, it is useful for type checking + """ + # pylint: disable=too-many-arguments,duplicate-code + + __slots__: list[str] = ['__in_context_manager', '__register_cache', + '__register_address_array'] + + def __init__(self, *, + logger_handle: str, inst_name: str, + parent: Union[AddressMap, RegFile, Memory], + width: int, + accesswidth: int, + address: int, + stride: int, + dimensions: tuple[int, ...], + elements: Optional[dict[tuple[int, ...], RegArrayElementType]] = None): + + self.__in_context_manager: bool = False + self.__register_cache: Optional[Union[Array, list[int]]] = None + self.__register_address_array: Optional[list[int]] = None + + if not isinstance(parent._callbacks, (NormalCallbackSet, NormalCallbackSetLegacy)): + raise TypeError(f'callback set type is wrong, got {type(parent._callbacks)}') + + super().__init__(logger_handle=logger_handle, inst_name=inst_name, + parent=parent, address=address, width=width, accesswidth=accesswidth, + stride=stride, dimensions=dimensions, elements=elements) + + @property + def __empty_array_cache(self) -> Array: + return Array(get_array_typecode(self.width), self.__empty_list_cache) + + @property + def __empty_list_cache(self) -> list[int]: + return [0 for _ in range(self.__number_cache_entries)] + + def __block_read_legacy(self) -> Array: + """ + Read all the contents of the array in the most optimal way, ideally with a block operation + """ + if not isinstance(self._callbacks, NormalCallbackSetLegacy): + raise RuntimeError('This function should only be used with legacy callbacks') + + read_block_callback = self._callbacks.read_block_callback + read_callback = self._callbacks.read_callback + + if read_block_callback is not None: + data_read = read_block_callback(addr=self.address, width=self.width, + accesswidth=self.accesswidth, + length=self.__number_cache_entries) + + if not isinstance(data_read, Array): + raise TypeError('The read block callback is expected to return an array') + + return data_read + + if read_callback is not None: + # there is not read_block_callback defined so we must used individual read + data_array = self.__empty_array_cache + + if self.__register_address_array is None: + raise RuntimeError('This address array has not be initialised') + + for entry, address in enumerate(self.__register_address_array): + data_entry = read_callback(addr=address, + width=self.width, + accesswidth=self.accesswidth) + + data_array[entry] = data_entry + + return data_array + + raise RuntimeError('There is no usable callback') + + def __block_write_legacy(self, data: Array, verify: bool) -> None: + """ + Write all the contents of the array in the most optimal way, ideally with a block operation + """ + if not isinstance(self._callbacks, NormalCallbackSetLegacy): + raise RuntimeError('This function should only be used with legacy callbacks') + + write_block_callback = self._callbacks.write_block_callback + write_callback = self._callbacks.write_callback + + if write_block_callback is not None: + write_block_callback(addr=self.address, + width=self.width, + accesswidth=self.width, + data=data) + + elif write_callback is not None: + # there is not write_block_callback defined so we must used individual write + + if self.__register_address_array is None: + raise RuntimeError('This address array has not be initialised') + + for entry_index, entry_data in enumerate(data): + entry_address = self.__register_address_array[entry_index] + write_callback(addr=entry_address, + width=self.width, + accesswidth=self.accesswidth, + data=entry_data) + + else: + raise RuntimeError('No suitable callback') + + if verify: + read_back_verify_data = self.__block_read_legacy() + if read_back_verify_data != data: + raise RegisterWriteVerifyError('Read back block miss-match') + + def __block_read(self) -> list[int]: + """ + Read all the contents of the array in the most optimal way, ideally with a block operation + """ + if not isinstance(self._callbacks, NormalCallbackSet): + raise RuntimeError('This function should only be used with non-legacy callbacks') + + read_block_callback = self._callbacks.read_block_callback + read_callback = self._callbacks.read_callback + + if read_block_callback is not None: + data_read = \ + read_block_callback(addr=self.address, + width=self.width, + accesswidth=self.accesswidth, + length=self.__number_cache_entries) + + if not isinstance(data_read, list): + if isinstance(data_read, Array): + raise TypeError('The read block callback is expected to return an list, this ' + 'is likely to happen if you are using legacy callbacks without ' + 'NormalCallbackSetLegacy') + raise TypeError('The read block callback is expected to return an list') + return data_read + + if read_callback is not None: + # there is not read_block_callback defined so we must used individual read + data_list = self.__empty_list_cache + + if self.__register_address_array is None: + raise RuntimeError('This address array has not be initialised') + + for entry, address in enumerate(self.__register_address_array): + data_entry = read_callback(addr=address, + width=self.width, + accesswidth=self.accesswidth) + + data_list[entry] = data_entry + + return data_list + + raise RuntimeError('There is no usable callback') + + def __block_write(self, data: list[int], verify: bool) -> None: + """ + Write all the contents of the array in the most optimal way, ideally with a block operation + """ + if not isinstance(self._callbacks, NormalCallbackSet): + raise RuntimeError('This function should only be used with non-legacy callbacks') + + write_block_callback = self._callbacks.write_block_callback + write_callback = self._callbacks.write_callback + + if write_block_callback is not None: + write_block_callback(addr=self.address, + width=self.width, + accesswidth=self.width, + data=data) + + elif write_callback is not None: + # there is not write_block_callback defined so we must used individual write + + if self.__register_address_array is None: + raise RuntimeError('This address array has not be initialised') + + for entry_index, entry_data in enumerate(data): + entry_address = self.__register_address_array[entry_index] + write_callback(addr=entry_address, + width=self.width, + accesswidth=self.accesswidth, + data=entry_data) + + else: + raise RuntimeError('No suitable callback') + + if verify: + read_back_verify_data = self.__block_read() + if read_back_verify_data != data: + raise RegisterWriteVerifyError('Read back block miss-match') + + def __cache_entry(self, addr: int, width: int, accesswidth: int) -> int: + """ + Validate the data provided and determine the cache entry + + Args: + addr: Address to write to + width: Width of the register in bits + accesswidth: Minimum access width of the register in bits + + Returns: + cache entry + + """ + if not isinstance(width, int): + raise TypeError(f'Width should be an int byt got {type(width)}') + if width != self.width: + raise ValueError('Requested Read width does not match the expected value') + if not isinstance(accesswidth, int): + raise TypeError(f'accesswidth should be an int byt got {type(accesswidth)}') + if accesswidth != self.accesswidth: + raise ValueError('Requested Read accesswidth does not match the expected value') + if not isinstance(addr, int): + raise TypeError(f'addr should be an int byt got {type(addr)}') + if not self.address <= addr < (self.address + self.size): + raise ValueError(f'Requested address 0x{addr:X} is out of range 0x{self.address:X} to ' + f'0x{self.address + self.size - (self.width >> 3):X}') + cache_entry = (addr - self.address) // (self.width >> 3) + if self.__register_address_array is None: + raise RuntimeError('The address table should always be populated here') + if self.__register_address_array[cache_entry] != addr: + raise RuntimeError(f'The calculated cache entry for address 0x{addr:X}') + return cache_entry + + def __cache_read(self, addr: int, width: int, accesswidth: int) -> int: + """ + Used to replace the normal callbacks with those that access the cache + + Args: + addr: Address to write to + width: Width of the register in bits + accesswidth: Minimum access width of the register in bits + + Returns: + value inputted by the used + """ + if self.__register_cache is None: + raise RuntimeError('The cache array should be initialised') + return self.__register_cache[self.__cache_entry(addr=addr, + width=width, + accesswidth=accesswidth)] + + def __cache_write(self, addr: int, width: int, accesswidth: int, data: int) -> None: + """ + Used to replace the normal callbacks with those that access the cache + + Args: + addr: Address to write to + width: Width of the register in bits + accesswidth: Minimum access width of the register in bits + data: value to be written to the register + + Returns: + None + """ + if not isinstance(data, int): + raise TypeError(f'Data should be an int byt got {type(data)}') + if self.__register_cache is None: + raise RuntimeError('The cache array should be initialised') + self.__register_cache[self.__cache_entry(addr=addr, + width=width, + accesswidth=accesswidth)] = data + + @property + def __cache_callbacks(self) -> NormalCallbackSet: + return NormalCallbackSet(read_callback=self.__cache_read, + write_callback=self.__cache_write) + + @property + def __number_cache_entries(self) -> int: + return self.size // (self.width >> 3) + + def __initialise_cache(self, skip_initial_read: bool) -> Union[Array, list[int]]: + if isinstance(self._callbacks, NormalCallbackSet): + if skip_initial_read: + return self.__empty_list_cache + return self.__block_read() + + if isinstance(self._callbacks, NormalCallbackSetLegacy): + if skip_initial_read: + return self.__empty_array_cache + return self.__block_read_legacy() + + raise TypeError('Unhandled callback type') + + @contextmanager + def _cached_access(self, verify: bool = False, skip_write: bool = False, + skip_initial_read: bool = False) -> \ + Generator[Self]: + """ + Context manager to allow multiple field reads/write to be done with a single set of + field operations + + Args: + verify (bool): very the write with a read afterwards + skip_write (bool): skip the write back at the end + """ + self.__register_address_array = \ + [self.address + (i * (self.width >> 3)) for i in range(self.__number_cache_entries)] + self.__register_cache = self.__initialise_cache(skip_initial_read=skip_initial_read) + self.__in_context_manager = True + # this try/finally is needed to make sure that in the event of an exception + # the state flags are not left incorrectly set + try: + yield self + finally: + self.__in_context_manager = False + if not skip_write: + if isinstance(self._callbacks, NormalCallbackSet): + if not isinstance(self.__register_cache, list): + raise TypeError('Register cache should be a list in non-legacy mode') + self.__block_write(self.__register_cache, verify) + if isinstance(self._callbacks, NormalCallbackSetLegacy): + if not isinstance(self.__register_cache, Array): + raise TypeError('Register cache should be a Array in legacy mode') + self.__block_write_legacy(self.__register_cache, verify) + + # clear the register states at the end of the context manager + self.__register_address_array = None + self.__register_cache = None + + @property + def _callbacks(self) -> NormalCallbackSet: + + if self.__in_context_manager: + return self.__cache_callbacks + + if self.parent is None: + raise RuntimeError('Parent must be set') + # This cast is OK because the type was checked in the __init__ + # pylint: disable-next=protected-access + return cast(NormalCallbackSet, self.parent._callbacks) + + +class RegReadOnly(Reg, ABC): + """ + class for a read only register + + Args: + address: address of the register + width: width of the register in bits + accesswidth: minimum access width of the register in bits + logger_handle: name to be used logging messages associate with this + object + + """ + + __slots__: list[str] = ['__in_context_manager', '__register_state'] + + # pylint: disable=too-many-arguments, duplicate-code + def __init__(self, *, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AddressMap, RegFile, ReadableMemory, ReadableMemoryLegacy ]): + + super().__init__(address=address, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent, width=width, accesswidth=accesswidth) + + self.__in_context_manager: bool = False + self.__register_state: int = 0 + + # pylint: enable=too-many-arguments, duplicate-code + + @contextmanager + def single_read(self) -> Generator[Self]: + """ + Context manager to allow multiple field accesses to be performed with a single + read of the register + """ + self.__register_state = self.read() + self.__in_context_manager = True + # this try/finally is needed to make sure that in the event of an exception + # the state flags are not left incorrectly set + try: + yield self + finally: + self.__in_context_manager = False + + def read(self) -> int: + """ + Read value from the register + """ + if self.__in_context_manager: + return self.__register_state + + read_block_callback = self._callbacks.read_block_callback + read_callback = self._callbacks.read_callback + + if read_callback is not None: + return read_callback(addr=self.address, + width=self.width, + accesswidth=self.accesswidth) + + if read_block_callback is not None: + return read_block_callback(addr=self.address, + width=self.width, + accesswidth=self.accesswidth, + length=1)[0] + + raise RuntimeError('This function does not have a useable callback') + + @property + def readable_fields(self) -> Iterator[Union['FieldReadOnly', 'FieldReadWrite']]: + """ + generator that produces has all the readable fields within the register + """ + def is_readable(field: Union['FieldReadOnly', 'FieldWriteOnly', 'FieldReadWrite']) -> \ + TypeGuard[Union['FieldReadOnly', 'FieldReadWrite']]: + return isinstance(field, (FieldReadOnly, FieldReadWrite)) + + return filter(is_readable, self.fields) + + def read_fields(self) -> dict['str', Union[bool, Enum, int]]: + """ + read the register and return a dictionary of the field values + """ + return_dict: dict['str', Union[bool, Enum, int]] = {} + with self.single_read() as reg: + for field in reg.readable_fields: + return_dict[field.inst_name] = field.read() + + return return_dict + + @property + def _is_readable(self) -> bool: + # pylint: disable=duplicate-code + return True + + @property + def _is_writeable(self) -> bool: + # pylint: disable=duplicate-code + return False + + +class RegWriteOnly(Reg, ABC): + """ + class for a write only register + """ + + __slots__: list[str] = [] + + # pylint: disable=too-many-arguments, duplicate-code, useless-parent-delegation + def __init__(self, *, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AddressMap, RegFile, WritableMemory, WritableMemoryLegacy]): + + super().__init__(address=address, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent, width=width, accesswidth=accesswidth) + # pylint: enable=too-many-arguments, duplicate-code + + def write(self, data: int) -> None: + """Writes a value to the register + + Args: + data: data to be written + + Raises: + ValueError: if the value provided is outside the range of the + permissible values for the register + TypeError: if the type of data is wrong + """ + # this method check the types and range checks the data + self._validate_data(data=data) + + self._logger.info('Writing data:%X to %X', data, self.address) + + if self._callbacks.write_callback is not None: + self._callbacks.write_callback(addr=self.address, + width=self.width, + accesswidth=self.accesswidth, + data=data) # + + elif self._callbacks.write_block_callback is not None: + if isinstance(self._callbacks, NormalCallbackSetLegacy): + data_as_array = Array(get_array_typecode(self.width), [data]) + self._callbacks.write_block_callback(addr=self.address, + width=self.width, + accesswidth=self.accesswidth, + data=data_as_array) + + if isinstance(self._callbacks, NormalCallbackSet): + self._callbacks.write_block_callback(addr=self.address, + width=self.width, + accesswidth=self.accesswidth, + data=[data]) + + else: + raise RuntimeError('This function does not have a useable callback') + + @property + def writable_fields(self) -> Iterator[Union['FieldWriteOnly', 'FieldReadWrite']]: + """ + generator that produces has all the readable fields within the register + """ + def is_writable(field: Union['FieldReadOnly', 'FieldWriteOnly', 'FieldReadWrite']) -> \ + TypeGuard[Union['FieldWriteOnly', 'FieldReadWrite']]: + return isinstance(field, (FieldWriteOnly, FieldReadWrite)) + + return filter(is_writable, self.fields) + + @abstractmethod + def write_fields(self, **kwargs) -> None: # type: ignore[no-untyped-def] + """ + Do a write to the register, updating any field included in + the arguments + """ + + @property + def _is_readable(self) -> bool: + # pylint: disable=duplicate-code + return False + + @property + def _is_writeable(self) -> bool: + # pylint: disable=duplicate-code + return True + + +class RegReadWrite(RegReadOnly, RegWriteOnly, ABC): + """ + class for a read and write only register + + """ + __slots__: list[str] = ['__in_read_write_context_manager', '__in_read_context_manager', + '__register_state'] + + # pylint: disable=too-many-arguments, duplicate-code + def __init__(self, *, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AddressMap, RegFile, MemoryReadWrite, MemoryReadWriteLegacy]): + + super().__init__(address=address, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent, width=width, accesswidth=accesswidth) + + self.__in_read_write_context_manager: bool = False + self.__in_read_context_manager: bool = False + self.__register_state: Optional[int] = None + + # pylint: enable=too-many-arguments, duplicate-code + + @contextmanager + def single_read_modify_write(self, verify: bool = False, skip_write: bool = False) -> \ + Generator[Self]: + """ + Context manager to allow multiple field reads/write to be done with a single set of + field operations + + Args: + verify (bool): very the write with a read afterwards + skip_write (bool): skip the write back at the end + + """ + if self.__in_read_context_manager: + raise RuntimeError('using the `single_read_modify_write` context manager within the ' + 'single_read` is not permitted') + + if skip_write is True: + warn('The `skip_write` argument will be removed in the future, use `single_read`' + ' instead', + DeprecationWarning, stacklevel=2) + + self.__register_state = self.read() + self.__in_read_write_context_manager = True + try: + yield self + finally: + # need to make sure the state flag is cleared even if an exception occurs within + # the context + self.__in_read_write_context_manager = False + + if not skip_write: + self.write(self.__register_state, verify) + + # clear the register states at the end of the context manager + self.__register_state = None + + @contextmanager + def single_read(self) -> \ + Generator[Self]: + """ + Context manager to allow multiple field reads with a single register read + """ + if self.__in_read_write_context_manager: + raise RuntimeError('using the `single_read` context manager within the ' + 'single_read_modify_write` is not permitted') + self.__in_read_context_manager = True + try: + with super().single_read() as reg: + yield reg + finally: + self.__in_read_context_manager = False + + def write(self, data: int, verify: bool = False) -> None: # pylint: disable=arguments-differ + """ + Writes a value to the register + + Args: + data: data to be written + verify: set to True to read back the register to verify the read has occurred correctly + + Raises: + ValueError: if the value provided is outside the range of the + permissible values for the register + TypeError: if the type of data is wrong + RegisterWriteVerifyError: the read back data after the write does not match the + expected value + """ + if self.__in_read_context_manager: + raise RuntimeError('writes within the single read context manager are not permitted') + + if self.__in_read_write_context_manager: + if self.__register_state is None: + raise RuntimeError('The internal register state should never be None in the ' + 'context manager') + self.__register_state = data + else: + super().write(data) + if verify: + read_back = self.read() + if read_back != data: + raise RegisterWriteVerifyError(f'Readback {read_back:X} ' + f'after writing {data:X}') + + def read(self) -> int: + """ + Read value from the register + """ + if self.__in_read_write_context_manager: + if self.__register_state is None: + raise RuntimeError('The internal register state should never be None in the ' + 'context manager') + return self.__register_state + + # the single read context manager is handled in the base class so does need any + # handling here + + return super().read() + + def write_fields(self, **kwargs) -> None: # type: ignore[no-untyped-def] + """ + Do a read-modify-write to the register, updating any field included in + the arguments + """ + if len(kwargs) == 0: + raise ValueError('no command args') + + with self.single_read_modify_write() as reg: + for field_name, field_value in kwargs.items(): + if field_name not in reg.systemrdl_python_child_name_map.values(): + raise ValueError(f'{field_name} is not a member of the register') + + field = getattr(reg, field_name) + field.write(field_value) + + def read_fields(self) -> dict['str', Union[bool, Enum, int]]: + """ + read the register and return a dictionary of the field values + """ + return_dict: dict['str', Union[bool, Enum, int]] = {} + with self.single_read() as reg: + for field in reg.readable_fields: + return_dict[field.inst_name] = field.read() + + return return_dict + + @property + def _is_readable(self) -> bool: + # pylint: disable=duplicate-code + return True + + @property + def _is_writeable(self) -> bool: + # pylint: disable=duplicate-code + return True + + +ReadableRegister = Union[RegReadOnly, RegReadWrite] +WritableRegister = Union[RegWriteOnly, RegReadWrite] + + +class RegReadOnlyArray(RegArray, ABC): + """ + base class for a array of read only registers + """ + __slots__: list[str] = [] + + # pylint: disable=too-many-arguments,duplicate-code + def __init__(self, *, + logger_handle: str, inst_name: str, + parent: Union[RegFile, AddressMap, ReadableMemory, ReadableMemoryLegacy], + address: int, + width: int, + accesswidth: int, + stride: int, + dimensions: tuple[int, ...], + elements: Optional[dict[tuple[int, ...], RegReadOnly]] = None): + + if not isinstance(parent, (RegFile, AddressMap, MemoryReadOnly, MemoryReadWrite, + MemoryReadOnlyLegacy, MemoryReadWriteLegacy)): + raise TypeError('parent should be either RegFile, AddressMap, ' + 'MemoryReadOnly, MemoryReadWrite ' + f'got {type(parent)}') + + if not isinstance(parent._callbacks, (NormalCallbackSet, NormalCallbackSetLegacy)): + raise TypeError(f'callback set type is wrong, got {type(parent._callbacks)}') + + super().__init__(logger_handle=logger_handle, inst_name=inst_name, + parent=parent, address=address, width=width, accesswidth=accesswidth, + stride=stride, dimensions=dimensions, elements=elements) + # pylint: enable=too-many-arguments,duplicate-code + + @contextmanager + def single_read(self) -> \ + Generator[Self]: + """ + Context manager to allow multiple field reads/write to be done with a single set of + field operations + """ + with self._cached_access(verify=False, skip_write=True, + skip_initial_read=False) as reg_array: + yield reg_array + + @property + def _is_readable(self) -> bool: + # pylint: disable=duplicate-code + return True + + @property + def _is_writeable(self) -> bool: + # pylint: disable=duplicate-code + return False + + +class RegWriteOnlyArray(RegArray, ABC): + """ + base class for a array of write only registers + """ + __slots__: list[str] = [] + + # pylint: disable=too-many-arguments,duplicate-code + def __init__(self, *, + logger_handle: str, inst_name: str, + parent: Union[RegFile, AddressMap, WritableMemory, WritableMemoryLegacy], + address: int, + width: int, + accesswidth: int, + stride: int, + dimensions: tuple[int, ...], + elements: Optional[dict[tuple[int, ...], RegWriteOnly]] = None): + + if not isinstance(parent, (RegFile, AddressMap, MemoryWriteOnly, MemoryReadWrite, + MemoryWriteOnlyLegacy, MemoryReadWriteLegacy)): + raise TypeError('parent should be either RegFile, AddressMap, MemoryWriteOnly, ' + 'MemoryReadWrite ' + f'got {type(parent)}') + + if not isinstance(parent._callbacks, (NormalCallbackSet, NormalCallbackSetLegacy)): + raise TypeError(f'callback set type is wrong, got {type(parent._callbacks)}') + + super().__init__(logger_handle=logger_handle, inst_name=inst_name, + parent=parent, address=address, width=width, accesswidth=accesswidth, + stride=stride, dimensions=dimensions, elements=elements) + # pylint: enable=too-many-arguments,duplicate-code + + @contextmanager + def single_write(self) -> \ + Generator[Self]: + """ + Context manager to allow multiple field reads/write to be done with a single set of + field operations + """ + with self._cached_access(verify=False, skip_write=False, + skip_initial_read=True) as reg_array: + yield reg_array + + @property + def _is_readable(self) -> bool: + # pylint: disable=duplicate-code + return False + + @property + def _is_writeable(self) -> bool: + # pylint: disable=duplicate-code + return True + + +class RegReadWriteArray(RegArray, ABC): + """ + base class for a array of read and write registers + """ + __slots__: list[str] = [] + + # pylint: disable=too-many-arguments,duplicate-code + def __init__(self, *, + logger_handle: str, inst_name: str, + parent: Union[RegFile, AddressMap, MemoryReadWrite, MemoryReadWriteLegacy], + address: int, + width: int, + accesswidth: int, + stride: int, + dimensions: tuple[int, ...], + elements: Optional[dict[tuple[int, ...], RegReadWrite]] = None): + + if not isinstance(parent, (RegFile, AddressMap, MemoryReadWrite, MemoryReadWriteLegacy)): + raise TypeError('parent should be either RegFile, AddressMap, MemoryReadWrite ' + f'got {type(parent)}') + + if not isinstance(parent._callbacks, (NormalCallbackSet, NormalCallbackSetLegacy)): + raise TypeError(f'callback set type is wrong, got {type(parent._callbacks)}') + + super().__init__(logger_handle=logger_handle, inst_name=inst_name, + parent=parent, address=address, width=width, accesswidth=accesswidth, + stride=stride, dimensions=dimensions, elements=elements) + + # pylint: enable=too-many-arguments,duplicate-code + + @contextmanager + def single_read_modify_write(self, verify: bool = False, skip_write: bool = False) -> \ + Generator[Self]: + """ + Context manager to allow multiple field reads/write to be done with a single set of + field operations + + Args: + verify (bool): very the write with a read afterwards + skip_write (bool): skip the write back at the end + """ + with self._cached_access(verify=verify, skip_write=skip_write, + skip_initial_read=False) as reg_array: + yield reg_array + + @property + def _is_readable(self) -> bool: + # pylint: disable=duplicate-code + return True + + @property + def _is_writeable(self) -> bool: + # pylint: disable=duplicate-code + return True + + +ReadableRegisterArray = Union[RegReadOnlyArray, RegReadWriteArray] +WriteableRegisterArray = Union[RegWriteOnlyArray, RegReadWriteArray] + + +class FieldReadOnly(_FieldReadOnlyFramework[FieldType], ABC): + """ + class for a read only register field + + Args: + parent_register: register within which the field resides + size_props: object defining the msb, lsb, high bit, low bit and width + logger_handle: name to be used logging messages associate with this + object + + """ + __slots__: list[str] = [] + + # pylint: disable-next=too-many-arguments + def __init__(self, *, + parent_register: ReadableRegister, + size_props: FieldSizeProps, + misc_props: FieldMiscProps, + logger_handle: str, + inst_name: str, + field_type:type[FieldType]): + + if not isinstance(parent_register, (RegReadWrite, RegReadOnly)): + raise TypeError(f'size_props must be of {type(RegReadWrite)} or {type(RegReadOnly)} ' + f'but got {type(parent_register)}') + + # pylint: disable=duplicate-code + super().__init__(logger_handle=logger_handle, + size_props=size_props, + misc_props=misc_props, + parent_register=parent_register, + inst_name=inst_name, + field_type=field_type) + # pylint: enable=duplicate-code + + def read(self) -> FieldType: + """ + Reads the register that this field is located in and retries the field + value applying the required masking and shifting + + Returns: + field value + + """ + return self._decode_read_value(self.parent_register.read()) + + @property + def parent_register(self) -> ReadableRegister: + """ + parent register the field is placed in + """ + + # this cast is OK because an explict typing check was done in the __init__ + return cast(ReadableRegister, self.parent) + + +class FieldWriteOnly(_FieldWriteOnlyFramework[FieldType], ABC): + """ + class for a write only register field + + Args: + parent_register: register within which the field resides + size_props: object defining the msb, lsb, high bit, low bit and width + logger_handle: name to be used logging messages associate with this + object + + """ + __slots__: list[str] = [] + + # pylint: disable-next=too-many-arguments + def __init__(self, *, + parent_register: WritableRegister, + size_props: FieldSizeProps, + misc_props: FieldMiscProps, + logger_handle: str, + inst_name: str, + field_type:type[FieldType]): + + if not isinstance(parent_register, (RegReadWrite, RegWriteOnly)): + raise TypeError(f'size_props must be of {type(RegReadWrite)} or {type(RegWriteOnly)} ' + f'but got {type(parent_register)}') + + # pylint: disable=duplicate-code + super().__init__(logger_handle=logger_handle, + size_props=size_props, + misc_props=misc_props, + parent_register=parent_register, + inst_name=inst_name, + field_type=field_type) + # pylint: enable=duplicate-code + + def write(self, value: FieldType) -> None: + """ + The behaviour of this method depends on whether the field is located in + a readable register or not: + + If the register is readable, the method will perform a read-modify-write + on the register updating the field with the value provided + + If the register is not writable all other field values will be written + with zero. + + Args: + value: field value to update to + + """ + encoded_value = self._encode_write_value(value) + + if (self.high == (self.register_data_width - 1)) and (self.low == 0): + # special case where the field occupies the whole register, + # there a straight write can be performed + new_reg_value = encoded_value + else: + # do a read, modify write + if isinstance(self.parent_register, RegReadWrite): + reg_value = self.parent_register.read() + masked_reg_value = reg_value & self.inverse_bitmask + new_reg_value = masked_reg_value | encoded_value + elif isinstance(self.parent_register, RegWriteOnly): + new_reg_value = encoded_value + else: + raise TypeError('Unhandled parent type') + + self.parent_register.write(new_reg_value) + + @property + def parent_register(self) -> WritableRegister: + """ + parent register the field is placed in + """ + + # this cast is OK because an explict typing check was done in the __init__ + return cast(WritableRegister, self.parent) + + +class FieldReadWrite(FieldReadOnly[FieldType], FieldWriteOnly[FieldType], ABC): + """ + class for a read/write register field + + Args: + parent_register: register within which the field resides + size_props: object defining the msb, lsb, high bit, low bit and width + logger_handle: name to be used logging messages associate with this + object + + """ + __slots__: list[str] = [] + + # pylint: disable-next=too-many-arguments + def __init__(self, *, + parent_register: RegReadWrite, + size_props: FieldSizeProps, + misc_props: FieldMiscProps, + logger_handle: str, + inst_name: str, + field_type:type[FieldType]): + + if not isinstance(parent_register, RegReadWrite): + raise TypeError(f'parent_register must be of {type(RegReadWrite)} ' + f'but got {type(parent_register)}') + + super().__init__(logger_handle=logger_handle, + size_props=size_props, + misc_props=misc_props, + parent_register=parent_register, + inst_name=inst_name, + field_type=field_type) + + @property + def parent_register(self) -> RegReadWrite: + """ + parent register the field is placed in + """ + + # this cast is OK because an explict typing check was done in the __init__ + return cast(RegReadWrite, self.parent) + + +class FieldEnumReadWrite(FieldReadWrite[FieldType], FieldEnum[FieldType], ABC): + """ + class for a read/write register field with an enumerated value + """ + __slots__: list[str] = [] + + @property + def parent_register(self) -> RegReadWrite: + """ + parent register the field is placed in + """ + + # this cast is OK because an explict typing check was done in the __init__ + return cast(RegReadWrite, self.parent) + + +class FieldEnumReadOnly(FieldReadOnly[FieldType], FieldEnum[FieldType], ABC): + """ + class for a read only register field with an enumerated value + """ + __slots__: list[str] = [] + + +class FieldEnumWriteOnly(FieldWriteOnly[FieldType], FieldEnum[FieldType], ABC): + """ + class for a write only register field with an enumerated value + """ + __slots__: list[str] = [] diff --git a/rdl/outputs/python/msk_top_regs/lib/utility_functions.py b/rdl/outputs/python/msk_top_regs/lib/utility_functions.py new file mode 100644 index 0000000..6c9113d --- /dev/null +++ b/rdl/outputs/python/msk_top_regs/lib/utility_functions.py @@ -0,0 +1,83 @@ +""" +peakrdl-python is a tool to generate Python Register Access Layer (RAL) from SystemRDL +Copyright (C) 2021 - 2023 + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +This module is intended to distributed as part of automatically generated code by the +peakrdl-python tool. It provides a set of base classes used by the autogenerated code +""" + + +def swap_msb_lsb_ordering(width: int, value: int) -> int: + """ + swaps the msb/lsb on a integer + + Returns: + swapped value + """ + value_to_return = 0 + for bit_positions in zip(range(0, width), range(width-1, -1, -1)): + bit_value = (value >> bit_positions[0]) & 0x1 + value_to_return |= bit_value << bit_positions[1] + + return value_to_return + + +class UnsupportedWidthError(Exception): + """ + Exception for width that can not be supported in the legacy array based API + """ + + +def get_array_typecode(width: int) -> str: + """ + python array typecode + + Args: + width: in bits + + Returns: + string to pass into the array generator + + """ + if width == 32: + return 'L' + + if width == 64: + return 'Q' + + if width == 16: + return 'I' + + if width == 8: + return 'B' + + raise UnsupportedWidthError(f'unhandled width {width:d}, consider using the new new list ' + f'based API and callbacks rather than the legacy Array versions') + + +def is_power_two(value: int) -> bool: + """ + efficient algorithm for checking if something is a power of two + """ + return (value != 0) and ((value & (value - 1)) == 0) + + +def legal_register_width(width_in_bits: int) -> bool: + """ + check if a register width is legal, see the system RDL specification 10.1 e) and f) + must be a power of 2 and greater than 8 + """ + return (width_in_bits >= 8) and is_power_two(width_in_bits) diff --git a/rdl/outputs/python/msk_top_regs/reg_model/__init__.py b/rdl/outputs/python/msk_top_regs/reg_model/__init__.py new file mode 100644 index 0000000..2ae2839 --- /dev/null +++ b/rdl/outputs/python/msk_top_regs/reg_model/__init__.py @@ -0,0 +1 @@ +pass diff --git a/rdl/outputs/python/msk_top_regs/reg_model/msk_top_regs.py b/rdl/outputs/python/msk_top_regs/reg_model/msk_top_regs.py new file mode 100644 index 0000000..e2fa941 --- /dev/null +++ b/rdl/outputs/python/msk_top_regs/reg_model/msk_top_regs.py @@ -0,0 +1,10168 @@ + + + +""" +Python Wrapper for the msk_top_regs register model + +This code was generated from the PeakRDL-python package version 1.4.0 + +""" + + +from enum import unique +from typing import Iterator +from typing import Optional +from typing import Union +from typing import Type +from typing import overload +from typing import Literal +from typing import Any +from typing import NoReturn +from typing import AsyncGenerator + +import warnings + + + +from contextlib import asynccontextmanager + +from ..lib import Node, Base +from ..lib import UDPStruct + +from ..lib import AddressMapArray, RegFileArray +from ..lib import AsyncMemory, AsyncMemoryArray +from ..lib import AsyncAddressMap +from ..lib import AsyncRegFile +from ..lib import AsyncAddressMapArray +from ..lib import AsyncRegFileArray +from ..lib import MemoryAsyncReadOnly, MemoryAsyncWriteOnly, MemoryAsyncReadWrite +from ..lib import MemoryAsyncReadOnlyArray, MemoryAsyncWriteOnlyArray, MemoryAsyncReadWriteArray +from ..lib import AsyncReg, AsyncRegArray +from ..lib import RegAsyncReadOnly, RegAsyncWriteOnly, RegAsyncReadWrite +from ..lib import RegAsyncReadOnlyArray, RegAsyncWriteOnlyArray, RegAsyncReadWriteArray +from ..lib import FieldAsyncReadOnly, FieldAsyncWriteOnly, FieldAsyncReadWrite, Field + +from ..lib import ReadableAsyncRegister, WritableAsyncRegister +from ..lib import ReadableAsyncMemory, WritableAsyncMemory +from ..lib import ReadableAsyncRegisterArray, WriteableAsyncRegisterArray +from ..lib import FieldSizeProps, FieldMiscProps + + +from ..lib import SystemRDLEnum, SystemRDLEnumEntry + + + +from ..lib import AsyncCallbackSet, AsyncCallbackSetLegacy + + + + + + + + + + + + + + + + + + + +# regfile, register and field definitions + + + +class msk_top_regs_frame_sync_status_frame_sync_errors_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Frames Sync Errors | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Count of frame sync errors since last read. Value is 0 to 63. | + | | This field will saturate at 63 if more than 63 occur.

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Frames Sync Errors" + @property + def rdl_desc(self) -> str: + return "Count of frame sync errors since last read. Value is 0 to 63. This field will saturate at 63 if more than 63 occur." + + + + + + + +class msk_top_regs_frame_sync_status_frames_received_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Frames Received | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Count of frames received since last read. Value is 0x00_0000 to | + | | 0xFF_FFFF

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Frames Received" + @property + def rdl_desc(self) -> str: + return "Count of frames received since last read. Value is 0x00_0000 to 0xFF_FFFF" + + + + + + + +class msk_top_regs_frame_sync_status_frame_buffer_overflow_cls(FieldAsyncReadOnly): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Frame Buffer Overflow | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

0 - Normal operation 1 - Buffer overflow

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Frame Buffer Overflow" + @property + def rdl_desc(self) -> str: + return "0 - Normal operation\n1 - Buffer overflow" + + + + + + + +class msk_top_regs_frame_sync_status_frame_sync_locked_cls(FieldAsyncReadOnly): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Frame Sync Lock | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

0 - Frame sync not locked 1 - Frame sync locked

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Frame Sync Lock" + @property + def rdl_desc(self) -> str: + return "0 - Frame sync not locked\n1 - Frame sync locked" + + + + + + +class msk_top_regs_frame_sync_status_cls(RegAsyncReadWrite): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Frame Sync Status | + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__frame_sync_locked', '__frame_buffer_overflow', '__frames_received', '__frame_sync_errors'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,MemoryAsyncReadWrite]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__frame_sync_locked:msk_top_regs_frame_sync_status_frame_sync_locked_cls = msk_top_regs_frame_sync_status_frame_sync_locked_cls( + parent_register=self, + size_props=FieldSizeProps( + width=1, + lsb=0, + msb=0, + low=0, + high=0), + misc_props=FieldMiscProps( + default=0, + is_volatile=True), + logger_handle=logger_handle+'.frame_sync_locked', + inst_name='frame_sync_locked', + field_type=int) + self.__frame_buffer_overflow:msk_top_regs_frame_sync_status_frame_buffer_overflow_cls = msk_top_regs_frame_sync_status_frame_buffer_overflow_cls( + parent_register=self, + size_props=FieldSizeProps( + width=1, + lsb=1, + msb=1, + low=1, + high=1), + misc_props=FieldMiscProps( + default=0, + is_volatile=True), + logger_handle=logger_handle+'.frame_buffer_overflow', + inst_name='frame_buffer_overflow', + field_type=int) + self.__frames_received:msk_top_regs_frame_sync_status_frames_received_cls = msk_top_regs_frame_sync_status_frames_received_cls( + parent_register=self, + size_props=FieldSizeProps( + width=24, + lsb=2, + msb=25, + low=2, + high=25), + misc_props=FieldMiscProps( + default=0, + is_volatile=True), + logger_handle=logger_handle+'.frames_received', + inst_name='frames_received', + field_type=int) + self.__frame_sync_errors:msk_top_regs_frame_sync_status_frame_sync_errors_cls = msk_top_regs_frame_sync_status_frame_sync_errors_cls( + parent_register=self, + size_props=FieldSizeProps( + width=6, + lsb=26, + msb=31, + low=26, + high=31), + misc_props=FieldMiscProps( + default=0, + is_volatile=True), + logger_handle=logger_handle+'.frame_sync_errors', + inst_name='frame_sync_errors', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.frame_sync_locked + yield self.frame_buffer_overflow + yield self.frames_received + yield self.frame_sync_errors + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def frame_sync_locked(self) -> msk_top_regs_frame_sync_status_frame_sync_locked_cls: + """ + Property to access frame_sync_locked field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Frame Sync Lock | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

0 - Frame sync not locked 1 - Frame sync locked

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__frame_sync_locked + @property + def frame_buffer_overflow(self) -> msk_top_regs_frame_sync_status_frame_buffer_overflow_cls: + """ + Property to access frame_buffer_overflow field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Frame Buffer Overflow | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

0 - Normal operation 1 - Buffer overflow

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__frame_buffer_overflow + @property + def frames_received(self) -> msk_top_regs_frame_sync_status_frames_received_cls: + """ + Property to access frames_received field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Frames Received | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Count of frames received since last read. Value is 0x00_0000 to | + | | 0xFF_FFFF

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__frames_received + @property + def frame_sync_errors(self) -> msk_top_regs_frame_sync_status_frame_sync_errors_cls: + """ + Property to access frame_sync_errors field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Frames Sync Errors | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Count of frame sync errors since last read. Value is 0 to 63. | + | | This field will saturate at 63 if more than 63 occur.

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__frame_sync_errors + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'frame_sync_locked':'frame_sync_locked','frame_buffer_overflow':'frame_buffer_overflow','frames_received':'frames_received','frame_sync_errors':'frame_sync_errors', + } + + + + + + + + # nodes:4 + + @overload + def get_child_by_system_rdl_name(self, name: Literal["frame_sync_locked"]) -> msk_top_regs_frame_sync_status_frame_sync_locked_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["frame_buffer_overflow"]) -> msk_top_regs_frame_sync_status_frame_buffer_overflow_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["frames_received"]) -> msk_top_regs_frame_sync_status_frames_received_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["frame_sync_errors"]) -> msk_top_regs_frame_sync_status_frame_sync_errors_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: str) -> Union[msk_top_regs_frame_sync_status_frame_sync_locked_cls, msk_top_regs_frame_sync_status_frame_buffer_overflow_cls, msk_top_regs_frame_sync_status_frames_received_cls, msk_top_regs_frame_sync_status_frame_sync_errors_cls, ]: ... + + def get_child_by_system_rdl_name(self, name: Any) -> Any: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + @property + def rdl_name(self) -> str: + return "Frame Sync Status" + + + + + + + +class msk_top_regs_status_reg_data_desc_a6882ec4_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Description | .. raw:: html | + | | | + | |

Read and Write Pointers

Bits 31:16 - write | + | | pointer (12-bits) Bits 15:00 - read pointer (12-bits)

| + | |

This register is write-to-capture. To read data the following | + | | steps are required:

  1. Write any value to this | + | | register to capture read data
  2. Read the register | + | |
| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_desc(self) -> str: + return "Read and Write Pointers\n\n[code]\nBits 31:16 - write pointer (12-bits)\nBits 15:00 - read pointer (12-bits)\n[/code]\n\nThis register is write-to-capture. To read data the following steps are required:\n[list=1]\n[*] Write any value to this register to capture read data\n[*] Read the register\n[/list]" + + + + + + +class msk_top_regs_status_reg_data_8a67e1fe_desc_8a90eed1_name_8a90eed1_cls(RegAsyncReadWrite): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Rx async FIFO read and write pointers | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Rx async FIFO read and write pointers

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__data'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,MemoryAsyncReadWrite]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__data:msk_top_regs_status_reg_data_desc_a6882ec4_cls = msk_top_regs_status_reg_data_desc_a6882ec4_cls( + parent_register=self, + size_props=FieldSizeProps( + width=32, + lsb=0, + msb=31, + low=0, + high=31), + misc_props=FieldMiscProps( + default=0, + is_volatile=True), + logger_handle=logger_handle+'.data', + inst_name='data', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.data + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def data(self) -> msk_top_regs_status_reg_data_desc_a6882ec4_cls: + """ + Property to access data field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Description | .. raw:: html | + | | | + | |

Read and Write Pointers

Bits 31:16 - write | + | | pointer (12-bits) Bits 15:00 - read pointer (12-bits)

| + | |

This register is write-to-capture. To read data the following | + | | steps are required:

  1. Write any value to this | + | | register to capture read data
  2. Read the register | + | |
| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__data + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'data':'data', + } + + + + + + + + + def get_child_by_system_rdl_name(self, name: Any) -> msk_top_regs_status_reg_data_desc_a6882ec4_cls: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + + @property + def rdl_name(self) -> str: + return "Rx async FIFO read and write pointers" + @property + def rdl_desc(self) -> str: + return "Rx async FIFO read and write pointers" + + + + + + + +class msk_top_regs_status_reg_data_desc_a6882ec4_0x0x1101989e_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Description | .. raw:: html | + | | | + | |

Read and Write Pointers

Bits 31:16 - write | + | | pointer (12-bits) Bits 15:00 - read pointer (12-bits)

| + | |

This register is write-to-capture. To read data the following | + | | steps are required:

  1. Write any value to this | + | | register to capture read data
  2. Read the register | + | |
| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_desc(self) -> str: + return "Read and Write Pointers\n\n[code]\nBits 31:16 - write pointer (12-bits)\nBits 15:00 - read pointer (12-bits)\n[/code]\n\nThis register is write-to-capture. To read data the following steps are required:\n[list=1]\n[*] Write any value to this register to capture read data\n[*] Read the register\n[/list]" + + + + + + +class msk_top_regs_status_reg_data_8a67e1fe_desc_aa4ec676_name_aa4ec676_cls(RegAsyncReadWrite): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Tx async FIFO read and write pointers | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Tx async FIFO read and write pointers

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__data'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,MemoryAsyncReadWrite]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__data:msk_top_regs_status_reg_data_desc_a6882ec4_0x0x1101989e_cls = msk_top_regs_status_reg_data_desc_a6882ec4_0x0x1101989e_cls( + parent_register=self, + size_props=FieldSizeProps( + width=32, + lsb=0, + msb=31, + low=0, + high=31), + misc_props=FieldMiscProps( + default=0, + is_volatile=True), + logger_handle=logger_handle+'.data', + inst_name='data', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.data + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def data(self) -> msk_top_regs_status_reg_data_desc_a6882ec4_0x0x1101989e_cls: + """ + Property to access data field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Description | .. raw:: html | + | | | + | |

Read and Write Pointers

Bits 31:16 - write | + | | pointer (12-bits) Bits 15:00 - read pointer (12-bits)

| + | |

This register is write-to-capture. To read data the following | + | | steps are required:

  1. Write any value to this | + | | register to capture read data
  2. Read the register | + | |
| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__data + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'data':'data', + } + + + + + + + + + def get_child_by_system_rdl_name(self, name: Any) -> msk_top_regs_status_reg_data_desc_a6882ec4_0x0x1101989e_cls: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + + @property + def rdl_name(self) -> str: + return "Tx async FIFO read and write pointers" + @property + def rdl_desc(self) -> str: + return "Tx async FIFO read and write pointers" + + + + + + + +class msk_top_regs_rx_power_data_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Receive Power | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Value that represent the RMS power of the incoming signal | + | | (I-channel)

This register is write-to-capture. To read data | + | | the following steps are required:

  1. Write any | + | | value to this register to capture read data
  2. Read the | + | | register
| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Receive Power" + @property + def rdl_desc(self) -> str: + return "Value that represent the RMS power of the incoming signal (I-channel)\n\nThis register is write-to-capture. To read data the following steps are required:\n[list=1]\n[*] Write any value to this register to capture read data\n[*] Read the register\n[/list]" + + + + + + +class msk_top_regs_rx_power_cls(RegAsyncReadWrite): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Receive Power | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Receive power computed from I/Q samples

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__data'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,MemoryAsyncReadWrite]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__data:msk_top_regs_rx_power_data_cls = msk_top_regs_rx_power_data_cls( + parent_register=self, + size_props=FieldSizeProps( + width=23, + lsb=0, + msb=22, + low=0, + high=22), + misc_props=FieldMiscProps( + default=0, + is_volatile=True), + logger_handle=logger_handle+'.data', + inst_name='data', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.data + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def data(self) -> msk_top_regs_rx_power_data_cls: + """ + Property to access data field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Receive Power | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Value that represent the RMS power of the incoming signal | + | | (I-channel)

This register is write-to-capture. To read data | + | | the following steps are required:

  1. Write any | + | | value to this register to capture read data
  2. Read the | + | | register
| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__data + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'data':'data', + } + + + + + + + + + def get_child_by_system_rdl_name(self, name: Any) -> msk_top_regs_rx_power_data_cls: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + + @property + def rdl_name(self) -> str: + return "Receive Power" + @property + def rdl_desc(self) -> str: + return "Receive power computed from I/Q samples" + + + + + + + +class msk_top_regs_lowpass_ema_alpha_alpha_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | EMA alpha | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Value from 0x0_0000 to 0x3_FFFF represent the EMA alpha

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "EMA alpha" + @property + def rdl_desc(self) -> str: + return "Value from 0x0_0000 to 0x3_FFFF represent the EMA alpha" + + + + + + +class msk_top_regs_lowpass_ema_alpha_cls(RegAsyncReadWrite): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Exponential Moving Average Alpha | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Sets the alpha for the EMA

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__alpha'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,MemoryAsyncReadWrite]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__alpha:msk_top_regs_lowpass_ema_alpha_alpha_cls = msk_top_regs_lowpass_ema_alpha_alpha_cls( + parent_register=self, + size_props=FieldSizeProps( + width=18, + lsb=0, + msb=17, + low=0, + high=17), + misc_props=FieldMiscProps( + default=0, + is_volatile=False), + logger_handle=logger_handle+'.alpha', + inst_name='alpha', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.alpha + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def alpha(self) -> msk_top_regs_lowpass_ema_alpha_alpha_cls: + """ + Property to access alpha field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | EMA alpha | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Value from 0x0_0000 to 0x3_FFFF represent the EMA alpha

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__alpha + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'alpha':'alpha', + } + + + + + + + + + def get_child_by_system_rdl_name(self, name: Any) -> msk_top_regs_lowpass_ema_alpha_alpha_cls: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + + @property + def rdl_name(self) -> str: + return "Exponential Moving Average Alpha" + @property + def rdl_desc(self) -> str: + return "Sets the alpha for the EMA" + + + + + + + +class msk_top_regs_lowpass_ema_alpha_alpha_0x0x110198d4_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | EMA alpha | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Value from 0x0_0000 to 0x3_FFFF represent the EMA alpha

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "EMA alpha" + @property + def rdl_desc(self) -> str: + return "Value from 0x0_0000 to 0x3_FFFF represent the EMA alpha" + + + + + + +class msk_top_regs_lowpass_ema_alpha_0x0x1101991f_cls(RegAsyncReadWrite): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Exponential Moving Average Alpha | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Sets the alpha for the EMA

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__alpha'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,MemoryAsyncReadWrite]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__alpha:msk_top_regs_lowpass_ema_alpha_alpha_0x0x110198d4_cls = msk_top_regs_lowpass_ema_alpha_alpha_0x0x110198d4_cls( + parent_register=self, + size_props=FieldSizeProps( + width=18, + lsb=0, + msb=17, + low=0, + high=17), + misc_props=FieldMiscProps( + default=0, + is_volatile=False), + logger_handle=logger_handle+'.alpha', + inst_name='alpha', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.alpha + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def alpha(self) -> msk_top_regs_lowpass_ema_alpha_alpha_0x0x110198d4_cls: + """ + Property to access alpha field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | EMA alpha | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Value from 0x0_0000 to 0x3_FFFF represent the EMA alpha

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__alpha + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'alpha':'alpha', + } + + + + + + + + + def get_child_by_system_rdl_name(self, name: Any) -> msk_top_regs_lowpass_ema_alpha_alpha_0x0x110198d4_cls: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + + @property + def rdl_name(self) -> str: + return "Exponential Moving Average Alpha" + @property + def rdl_desc(self) -> str: + return "Sets the alpha for the EMA" + + + + + + + +class msk_top_regs_tx_sync_cnt_tx_sync_cnt_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Tx sync duration | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Value from 0x00_0000 to 0xFF_FFFF.

This value | + | | represents the number bit-times the synchronization signal should | + | | be sent after PTT is asserted.

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Tx sync duration" + @property + def rdl_desc(self) -> str: + return "Value from 0x00_0000 to 0xFF_FFFF. \n\nThis value represents the number bit-times the synchronization signal should be sent after PTT is asserted." + + + + + + +class msk_top_regs_tx_sync_cnt_cls(RegAsyncReadWrite): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Transmitter Sync Duration | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Sets the duration of the synchronization tones when enabled

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__tx_sync_cnt'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,MemoryAsyncReadWrite]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__tx_sync_cnt:msk_top_regs_tx_sync_cnt_tx_sync_cnt_cls = msk_top_regs_tx_sync_cnt_tx_sync_cnt_cls( + parent_register=self, + size_props=FieldSizeProps( + width=24, + lsb=0, + msb=23, + low=0, + high=23), + misc_props=FieldMiscProps( + default=0, + is_volatile=False), + logger_handle=logger_handle+'.tx_sync_cnt', + inst_name='tx_sync_cnt', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.tx_sync_cnt + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def tx_sync_cnt(self) -> msk_top_regs_tx_sync_cnt_tx_sync_cnt_cls: + """ + Property to access tx_sync_cnt field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Tx sync duration | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Value from 0x00_0000 to 0xFF_FFFF.

This value | + | | represents the number bit-times the synchronization signal should | + | | be sent after PTT is asserted.

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__tx_sync_cnt + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'tx_sync_cnt':'tx_sync_cnt', + } + + + + + + + + + def get_child_by_system_rdl_name(self, name: Any) -> msk_top_regs_tx_sync_cnt_tx_sync_cnt_cls: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + + @property + def rdl_name(self) -> str: + return "Transmitter Sync Duration" + @property + def rdl_desc(self) -> str: + return "Sets the duration of the synchronization tones when enabled" + + + + + + + +class msk_top_regs_tx_sync_ctrl_tx_sync_force_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Tx Sync Force | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

0 : Normal operation

1 : Continuously transmit | + | | synchronization pattern

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Tx Sync Force" + @property + def rdl_desc(self) -> str: + return "0 : Normal operation\n\n1 : Continuously transmit synchronization pattern" + + + + + + + +class msk_top_regs_tx_sync_ctrl_tx_sync_ena_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Tx Sync Enable | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

0 : Disable sync transmission

1 : Enable sync | + | | transmission when PTT is asserted

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Tx Sync Enable" + @property + def rdl_desc(self) -> str: + return "0 : Disable sync transmission\n\n1 : Enable sync transmission when PTT is asserted" + + + + + + +class msk_top_regs_tx_sync_ctrl_cls(RegAsyncReadWrite): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Transmitter Sync Control | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Provides control bits for generation of transmitter | + | | synchronization patterns

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__tx_sync_ena', '__tx_sync_force'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,MemoryAsyncReadWrite]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__tx_sync_ena:msk_top_regs_tx_sync_ctrl_tx_sync_ena_cls = msk_top_regs_tx_sync_ctrl_tx_sync_ena_cls( + parent_register=self, + size_props=FieldSizeProps( + width=1, + lsb=0, + msb=0, + low=0, + high=0), + misc_props=FieldMiscProps( + default=0, + is_volatile=False), + logger_handle=logger_handle+'.tx_sync_ena', + inst_name='tx_sync_ena', + field_type=int) + self.__tx_sync_force:msk_top_regs_tx_sync_ctrl_tx_sync_force_cls = msk_top_regs_tx_sync_ctrl_tx_sync_force_cls( + parent_register=self, + size_props=FieldSizeProps( + width=1, + lsb=1, + msb=1, + low=1, + high=1), + misc_props=FieldMiscProps( + default=0, + is_volatile=False), + logger_handle=logger_handle+'.tx_sync_force', + inst_name='tx_sync_force', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.tx_sync_ena + yield self.tx_sync_force + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def tx_sync_ena(self) -> msk_top_regs_tx_sync_ctrl_tx_sync_ena_cls: + """ + Property to access tx_sync_ena field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Tx Sync Enable | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

0 : Disable sync transmission

1 : Enable sync | + | | transmission when PTT is asserted

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__tx_sync_ena + @property + def tx_sync_force(self) -> msk_top_regs_tx_sync_ctrl_tx_sync_force_cls: + """ + Property to access tx_sync_force field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Tx Sync Force | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

0 : Normal operation

1 : Continuously transmit | + | | synchronization pattern

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__tx_sync_force + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'tx_sync_ena':'tx_sync_ena','tx_sync_force':'tx_sync_force', + } + + + + + + + + # nodes:2 + + @overload + def get_child_by_system_rdl_name(self, name: Literal["tx_sync_ena"]) -> msk_top_regs_tx_sync_ctrl_tx_sync_ena_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["tx_sync_force"]) -> msk_top_regs_tx_sync_ctrl_tx_sync_force_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: str) -> Union[msk_top_regs_tx_sync_ctrl_tx_sync_ena_cls, msk_top_regs_tx_sync_ctrl_tx_sync_force_cls, ]: ... + + def get_child_by_system_rdl_name(self, name: Any) -> Any: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + @property + def rdl_name(self) -> str: + return "Transmitter Sync Control" + @property + def rdl_desc(self) -> str: + return "Provides control bits for generation of transmitter synchronization patterns" + + + + + + + +class msk_top_regs_status_reg_data_desc_c8bf066a_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Description | .. raw:: html | + | | | + | |

Error value of the F2 Costas loop after each active bit | + | | period

This register is write-to-capture.

To read | + | | data the following steps are required:

1 - Write any value | + | | to this register to capture read data

2 - Read the | + | | register

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_desc(self) -> str: + return "Error value of the F2 Costas loop after each active bit period\n\nThis register is write-to-capture.\n\nTo read data the following steps are required:\n\n1 - Write any value to this register to capture read data\n\n2 - Read the register" + + + + + + +class msk_top_regs_status_reg_data_642692cf_name_3de9a0d3_cls(RegAsyncReadWrite): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | F2 Error Value | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Status Register

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__data'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,MemoryAsyncReadWrite]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__data:msk_top_regs_status_reg_data_desc_c8bf066a_cls = msk_top_regs_status_reg_data_desc_c8bf066a_cls( + parent_register=self, + size_props=FieldSizeProps( + width=32, + lsb=0, + msb=31, + low=0, + high=31), + misc_props=FieldMiscProps( + default=0, + is_volatile=True), + logger_handle=logger_handle+'.data', + inst_name='data', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.data + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def data(self) -> msk_top_regs_status_reg_data_desc_c8bf066a_cls: + """ + Property to access data field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Description | .. raw:: html | + | | | + | |

Error value of the F2 Costas loop after each active bit | + | | period

This register is write-to-capture.

To read | + | | data the following steps are required:

1 - Write any value | + | | to this register to capture read data

2 - Read the | + | | register

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__data + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'data':'data', + } + + + + + + + + + def get_child_by_system_rdl_name(self, name: Any) -> msk_top_regs_status_reg_data_desc_c8bf066a_cls: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + + @property + def rdl_name(self) -> str: + return "F2 Error Value" + @property + def rdl_desc(self) -> str: + return "Status Register" + + + + + + + +class msk_top_regs_status_reg_data_desc_83db1b72_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Description | .. raw:: html | + | | | + | |

Error value of the F1 Costas loop after each active bit | + | | period

This register is write-to-capture.

To read | + | | data the following steps are required:

1 - Write any value | + | | to this register to capture read data

2 - Read the | + | | register

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_desc(self) -> str: + return "Error value of the F1 Costas loop after each active bit period\n\nThis register is write-to-capture.\n\nTo read data the following steps are required:\n\n1 - Write any value to this register to capture read data\n\n2 - Read the register" + + + + + + +class msk_top_regs_status_reg_data_10a2e5b5_name_3b640507_cls(RegAsyncReadWrite): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | F1 Error Value | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Status Register

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__data'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,MemoryAsyncReadWrite]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__data:msk_top_regs_status_reg_data_desc_83db1b72_cls = msk_top_regs_status_reg_data_desc_83db1b72_cls( + parent_register=self, + size_props=FieldSizeProps( + width=32, + lsb=0, + msb=31, + low=0, + high=31), + misc_props=FieldMiscProps( + default=0, + is_volatile=True), + logger_handle=logger_handle+'.data', + inst_name='data', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.data + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def data(self) -> msk_top_regs_status_reg_data_desc_83db1b72_cls: + """ + Property to access data field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Description | .. raw:: html | + | | | + | |

Error value of the F1 Costas loop after each active bit | + | | period

This register is write-to-capture.

To read | + | | data the following steps are required:

1 - Write any value | + | | to this register to capture read data

2 - Read the | + | | register

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__data + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'data':'data', + } + + + + + + + + + def get_child_by_system_rdl_name(self, name: Any) -> msk_top_regs_status_reg_data_desc_83db1b72_cls: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + + @property + def rdl_name(self) -> str: + return "F1 Error Value" + @property + def rdl_desc(self) -> str: + return "Status Register" + + + + + + + +class msk_top_regs_status_reg_data_desc_13897f4c_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Description | .. raw:: html | + | | | + | |

Frequency offet applied to the F2 NCO

This register is | + | | write-to-capture.

To read data the following steps are | + | | required:

1 - Write any value to this register to capture | + | | read data

2 - Read the register

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_desc(self) -> str: + return "Frequency offet applied to the F2 NCO\n\nThis register is write-to-capture.\n\nTo read data the following steps are required:\n\n1 - Write any value to this register to capture read data\n\n2 - Read the register" + + + + + + +class msk_top_regs_status_reg_data_05243a4e_name_2c154788_cls(RegAsyncReadWrite): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | F2 NCO Frequency Adjust | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Status Register

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__data'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,MemoryAsyncReadWrite]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__data:msk_top_regs_status_reg_data_desc_13897f4c_cls = msk_top_regs_status_reg_data_desc_13897f4c_cls( + parent_register=self, + size_props=FieldSizeProps( + width=32, + lsb=0, + msb=31, + low=0, + high=31), + misc_props=FieldMiscProps( + default=0, + is_volatile=True), + logger_handle=logger_handle+'.data', + inst_name='data', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.data + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def data(self) -> msk_top_regs_status_reg_data_desc_13897f4c_cls: + """ + Property to access data field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Description | .. raw:: html | + | | | + | |

Frequency offet applied to the F2 NCO

This register is | + | | write-to-capture.

To read data the following steps are | + | | required:

1 - Write any value to this register to capture | + | | read data

2 - Read the register

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__data + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'data':'data', + } + + + + + + + + + def get_child_by_system_rdl_name(self, name: Any) -> msk_top_regs_status_reg_data_desc_13897f4c_cls: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + + @property + def rdl_name(self) -> str: + return "F2 NCO Frequency Adjust" + @property + def rdl_desc(self) -> str: + return "Status Register" + + + + + + + +class msk_top_regs_status_reg_data_desc_0ed96915_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Description | .. raw:: html | + | | | + | |

Frequency offet applied to the F1 NCO

This register is | + | | write-to-capture.

To read data the following steps are | + | | required:

1 - Write any value to this register to capture | + | | read data

2 - Read the register

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_desc(self) -> str: + return "Frequency offet applied to the F1 NCO\n\nThis register is write-to-capture.\n\nTo read data the following steps are required:\n\n1 - Write any value to this register to capture read data\n\n2 - Read the register" + + + + + + +class msk_top_regs_status_reg_data_f53978c8_name_d8ad3b25_cls(RegAsyncReadWrite): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | F1 NCO Frequency Adjust | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Status Register

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__data'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,MemoryAsyncReadWrite]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__data:msk_top_regs_status_reg_data_desc_0ed96915_cls = msk_top_regs_status_reg_data_desc_0ed96915_cls( + parent_register=self, + size_props=FieldSizeProps( + width=32, + lsb=0, + msb=31, + low=0, + high=31), + misc_props=FieldMiscProps( + default=0, + is_volatile=True), + logger_handle=logger_handle+'.data', + inst_name='data', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.data + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def data(self) -> msk_top_regs_status_reg_data_desc_0ed96915_cls: + """ + Property to access data field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Description | .. raw:: html | + | | | + | |

Frequency offet applied to the F1 NCO

This register is | + | | write-to-capture.

To read data the following steps are | + | | required:

1 - Write any value to this register to capture | + | | read data

2 - Read the register

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__data + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'data':'data', + } + + + + + + + + + def get_child_by_system_rdl_name(self, name: Any) -> msk_top_regs_status_reg_data_desc_0ed96915_cls: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + + @property + def rdl_name(self) -> str: + return "F1 NCO Frequency Adjust" + @property + def rdl_desc(self) -> str: + return "Status Register" + + + + + + + +class msk_top_regs_lpf_config_2_p_shift_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Proportional Gain Bit Shift | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Value n of 0-32 sets the proportional divisor as 2^-n

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Proportional Gain Bit Shift" + @property + def rdl_desc(self) -> str: + return "Value n of 0-32 sets the proportional divisor as 2^-n" + + + + + + + +class msk_top_regs_lpf_config_2_p_gain_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Proportional Gain Value | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Value m of 0-16,777,215 sets the proportional multiplier

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Proportional Gain Value" + @property + def rdl_desc(self) -> str: + return "Value m of 0-16,777,215 sets the proportional multiplier" + + + + + + +class msk_top_regs_lpf_config_2_cls(RegAsyncReadWrite): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PI Controller Configuration Configuration Register 2 | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Configures PI Controller I-gain and divisor

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__p_gain', '__p_shift'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,MemoryAsyncReadWrite]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__p_gain:msk_top_regs_lpf_config_2_p_gain_cls = msk_top_regs_lpf_config_2_p_gain_cls( + parent_register=self, + size_props=FieldSizeProps( + width=24, + lsb=0, + msb=23, + low=0, + high=23), + misc_props=FieldMiscProps( + default=0, + is_volatile=False), + logger_handle=logger_handle+'.p_gain', + inst_name='p_gain', + field_type=int) + self.__p_shift:msk_top_regs_lpf_config_2_p_shift_cls = msk_top_regs_lpf_config_2_p_shift_cls( + parent_register=self, + size_props=FieldSizeProps( + width=8, + lsb=24, + msb=31, + low=24, + high=31), + misc_props=FieldMiscProps( + default=0, + is_volatile=False), + logger_handle=logger_handle+'.p_shift', + inst_name='p_shift', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.p_gain + yield self.p_shift + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def p_gain(self) -> msk_top_regs_lpf_config_2_p_gain_cls: + """ + Property to access p_gain field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Proportional Gain Value | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Value m of 0-16,777,215 sets the proportional multiplier

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__p_gain + @property + def p_shift(self) -> msk_top_regs_lpf_config_2_p_shift_cls: + """ + Property to access p_shift field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Proportional Gain Bit Shift | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Value n of 0-32 sets the proportional divisor as 2^-n

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__p_shift + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'p_gain':'p_gain','p_shift':'p_shift', + } + + + + + + + + # nodes:2 + + @overload + def get_child_by_system_rdl_name(self, name: Literal["p_gain"]) -> msk_top_regs_lpf_config_2_p_gain_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["p_shift"]) -> msk_top_regs_lpf_config_2_p_shift_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: str) -> Union[msk_top_regs_lpf_config_2_p_gain_cls, msk_top_regs_lpf_config_2_p_shift_cls, ]: ... + + def get_child_by_system_rdl_name(self, name: Any) -> Any: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + @property + def rdl_name(self) -> str: + return "PI Controller Configuration Configuration Register 2" + @property + def rdl_desc(self) -> str: + return "Configures PI Controller I-gain and divisor" + + + + + + + +class msk_top_regs_rx_sample_discard_rx_nco_discard_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Rx NCO Sample Discard Value | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Number of NCO samples to discard

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Rx NCO Sample Discard Value" + @property + def rdl_desc(self) -> str: + return "Number of NCO samples to discard" + + + + + + + +class msk_top_regs_rx_sample_discard_rx_sample_discard_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Rx Sample Discard Value | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Number of Rx samples to discard

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Rx Sample Discard Value" + @property + def rdl_desc(self) -> str: + return "Number of Rx samples to discard" + + + + + + +class msk_top_regs_rx_sample_discard_cls(RegAsyncReadWrite): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Rx Sample Discard | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Configure samples discard operation for demodulator

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__rx_sample_discard', '__rx_nco_discard'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,MemoryAsyncReadWrite]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__rx_sample_discard:msk_top_regs_rx_sample_discard_rx_sample_discard_cls = msk_top_regs_rx_sample_discard_rx_sample_discard_cls( + parent_register=self, + size_props=FieldSizeProps( + width=8, + lsb=0, + msb=7, + low=0, + high=7), + misc_props=FieldMiscProps( + default=0, + is_volatile=False), + logger_handle=logger_handle+'.rx_sample_discard', + inst_name='rx_sample_discard', + field_type=int) + self.__rx_nco_discard:msk_top_regs_rx_sample_discard_rx_nco_discard_cls = msk_top_regs_rx_sample_discard_rx_nco_discard_cls( + parent_register=self, + size_props=FieldSizeProps( + width=8, + lsb=8, + msb=15, + low=8, + high=15), + misc_props=FieldMiscProps( + default=0, + is_volatile=False), + logger_handle=logger_handle+'.rx_nco_discard', + inst_name='rx_nco_discard', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.rx_sample_discard + yield self.rx_nco_discard + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def rx_sample_discard(self) -> msk_top_regs_rx_sample_discard_rx_sample_discard_cls: + """ + Property to access rx_sample_discard field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Rx Sample Discard Value | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Number of Rx samples to discard

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__rx_sample_discard + @property + def rx_nco_discard(self) -> msk_top_regs_rx_sample_discard_rx_nco_discard_cls: + """ + Property to access rx_nco_discard field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Rx NCO Sample Discard Value | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Number of NCO samples to discard

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__rx_nco_discard + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'rx_sample_discard':'rx_sample_discard','rx_nco_discard':'rx_nco_discard', + } + + + + + + + + # nodes:2 + + @overload + def get_child_by_system_rdl_name(self, name: Literal["rx_sample_discard"]) -> msk_top_regs_rx_sample_discard_rx_sample_discard_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["rx_nco_discard"]) -> msk_top_regs_rx_sample_discard_rx_nco_discard_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: str) -> Union[msk_top_regs_rx_sample_discard_rx_sample_discard_cls, msk_top_regs_rx_sample_discard_rx_nco_discard_cls, ]: ... + + def get_child_by_system_rdl_name(self, name: Any) -> Any: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + @property + def rdl_name(self) -> str: + return "Rx Sample Discard" + @property + def rdl_desc(self) -> str: + return "Configure samples discard operation for demodulator" + + + + + + + +class msk_top_regs_msk_stat_3_data_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | S_AXIS Transfers | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Number completed S_AXIS transfers

This register is | + | | write-to-capture.

To read data the following steps are | + | | required:

1 - Write any value to this register to capture | + | | read data

2 - Read the register

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "S_AXIS Transfers" + @property + def rdl_desc(self) -> str: + return "Number completed S_AXIS transfers\n\nThis register is write-to-capture.\n\nTo read data the following steps are required:\n\n1 - Write any value to this register to capture read data\n\n2 - Read the register" + + + + + + +class msk_top_regs_msk_stat_3_cls(RegAsyncReadWrite): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | MSK Modem Status 3 | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Modem status data

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__data'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,MemoryAsyncReadWrite]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__data:msk_top_regs_msk_stat_3_data_cls = msk_top_regs_msk_stat_3_data_cls( + parent_register=self, + size_props=FieldSizeProps( + width=32, + lsb=0, + msb=31, + low=0, + high=31), + misc_props=FieldMiscProps( + default=0, + is_volatile=True), + logger_handle=logger_handle+'.data', + inst_name='data', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.data + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def data(self) -> msk_top_regs_msk_stat_3_data_cls: + """ + Property to access data field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | S_AXIS Transfers | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Number completed S_AXIS transfers

This register is | + | | write-to-capture.

To read data the following steps are | + | | required:

1 - Write any value to this register to capture | + | | read data

2 - Read the register

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__data + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'data':'data', + } + + + + + + + + + def get_child_by_system_rdl_name(self, name: Any) -> msk_top_regs_msk_stat_3_data_cls: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + + @property + def rdl_name(self) -> str: + return "MSK Modem Status 3" + @property + def rdl_desc(self) -> str: + return "Modem status data" + + + + + + + +class msk_top_regs_stat_32_lpf_acc_data_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PI Controller Accumulator Value | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

PI Controller Accumulator Value

This register is write- | + | | to-capture.

To read data the following steps are | + | | required:

1 - Write any value to this register to capture | + | | read data

2 - Read the register

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "PI Controller Accumulator Value" + @property + def rdl_desc(self) -> str: + return "PI Controller Accumulator Value\n\nThis register is write-to-capture.\n\nTo read data the following steps are required:\n\n1 - Write any value to this register to capture read data\n\n2 - Read the register" + + + + + + +class msk_top_regs_stat_32_lpf_acc_desc_dea6bd99_name_758fd0ce_cls(RegAsyncReadWrite): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | F2 PI Controller Accumulator | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Value of the F2 PI Controller Accumulator

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__data'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,MemoryAsyncReadWrite]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__data:msk_top_regs_stat_32_lpf_acc_data_cls = msk_top_regs_stat_32_lpf_acc_data_cls( + parent_register=self, + size_props=FieldSizeProps( + width=32, + lsb=0, + msb=31, + low=0, + high=31), + misc_props=FieldMiscProps( + default=0, + is_volatile=True), + logger_handle=logger_handle+'.data', + inst_name='data', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.data + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def data(self) -> msk_top_regs_stat_32_lpf_acc_data_cls: + """ + Property to access data field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PI Controller Accumulator Value | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

PI Controller Accumulator Value

This register is write- | + | | to-capture.

To read data the following steps are | + | | required:

1 - Write any value to this register to capture | + | | read data

2 - Read the register

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__data + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'data':'data', + } + + + + + + + + + def get_child_by_system_rdl_name(self, name: Any) -> msk_top_regs_stat_32_lpf_acc_data_cls: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + + @property + def rdl_name(self) -> str: + return "F2 PI Controller Accumulator" + @property + def rdl_desc(self) -> str: + return "Value of the F2 PI Controller Accumulator" + + + + + + + +class msk_top_regs_stat_32_lpf_acc_data_0x0x10797426_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PI Controller Accumulator Value | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

PI Controller Accumulator Value

This register is write- | + | | to-capture.

To read data the following steps are | + | | required:

1 - Write any value to this register to capture | + | | read data

2 - Read the register

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "PI Controller Accumulator Value" + @property + def rdl_desc(self) -> str: + return "PI Controller Accumulator Value\n\nThis register is write-to-capture.\n\nTo read data the following steps are required:\n\n1 - Write any value to this register to capture read data\n\n2 - Read the register" + + + + + + +class msk_top_regs_stat_32_lpf_acc_desc_8cebc7dc_name_f20c6670_cls(RegAsyncReadWrite): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | F1 PI Controller Accumulator | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Value of the F1 PI Controller Accumulator

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__data'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,MemoryAsyncReadWrite]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__data:msk_top_regs_stat_32_lpf_acc_data_0x0x10797426_cls = msk_top_regs_stat_32_lpf_acc_data_0x0x10797426_cls( + parent_register=self, + size_props=FieldSizeProps( + width=32, + lsb=0, + msb=31, + low=0, + high=31), + misc_props=FieldMiscProps( + default=0, + is_volatile=True), + logger_handle=logger_handle+'.data', + inst_name='data', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.data + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def data(self) -> msk_top_regs_stat_32_lpf_acc_data_0x0x10797426_cls: + """ + Property to access data field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PI Controller Accumulator Value | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

PI Controller Accumulator Value

This register is write- | + | | to-capture.

To read data the following steps are | + | | required:

1 - Write any value to this register to capture | + | | read data

2 - Read the register

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__data + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'data':'data', + } + + + + + + + + + def get_child_by_system_rdl_name(self, name: Any) -> msk_top_regs_stat_32_lpf_acc_data_0x0x10797426_cls: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + + @property + def rdl_name(self) -> str: + return "F1 PI Controller Accumulator" + @property + def rdl_desc(self) -> str: + return "Value of the F1 PI Controller Accumulator" + + + + + + + +class msk_top_regs_stat_32_errs_data_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PRBS Bit Errors | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Number of errored-bits received by the PRBS monitor since last | + | | sync BER can be calculated as the ratio of received bits to | + | | errored-bits

This register is write-to-capture.

To | + | | read data the following steps are required:

1 - Write any | + | | value to this register to capture read data

2 - Read the | + | | register

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "PRBS Bit Errors" + @property + def rdl_desc(self) -> str: + return "Number of errored-bits received by the PRBS monitor since last sync\nBER can be calculated as the ratio of received bits to errored-bits\n\nThis register is write-to-capture.\n\nTo read data the following steps are required:\n\n1 - Write any value to this register to capture read data\n\n2 - Read the register" + + + + + + +class msk_top_regs_stat_32_errs_cls(RegAsyncReadWrite): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PRBS Status 1 | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

PRBS Bit Errors

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__data'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,MemoryAsyncReadWrite]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__data:msk_top_regs_stat_32_errs_data_cls = msk_top_regs_stat_32_errs_data_cls( + parent_register=self, + size_props=FieldSizeProps( + width=32, + lsb=0, + msb=31, + low=0, + high=31), + misc_props=FieldMiscProps( + default=0, + is_volatile=True), + logger_handle=logger_handle+'.data', + inst_name='data', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.data + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def data(self) -> msk_top_regs_stat_32_errs_data_cls: + """ + Property to access data field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PRBS Bit Errors | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Number of errored-bits received by the PRBS monitor since last | + | | sync BER can be calculated as the ratio of received bits to | + | | errored-bits

This register is write-to-capture.

To | + | | read data the following steps are required:

1 - Write any | + | | value to this register to capture read data

2 - Read the | + | | register

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__data + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'data':'data', + } + + + + + + + + + def get_child_by_system_rdl_name(self, name: Any) -> msk_top_regs_stat_32_errs_data_cls: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + + @property + def rdl_name(self) -> str: + return "PRBS Status 1" + @property + def rdl_desc(self) -> str: + return "PRBS Bit Errors" + + + + + + + +class msk_top_regs_stat_32_bits_data_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PRBS Bits Received | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Number of bits received by the PRBS monitor since last BER can | + | | be calculated as the ratio of received bits to errored-bits

| + | |

This register is write-to-capture.

To read data the | + | | following steps are required:

1 - Write any value to this | + | | register to capture read data

2 - Read the register

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "PRBS Bits Received" + @property + def rdl_desc(self) -> str: + return "Number of bits received by the PRBS monitor since last\nBER can be calculated as the ratio of received bits to errored-bits\n\nThis register is write-to-capture.\n\nTo read data the following steps are required:\n\n1 - Write any value to this register to capture read data\n\n2 - Read the register" + + + + + + +class msk_top_regs_stat_32_bits_cls(RegAsyncReadWrite): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PRBS Status 0 | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

PRBS Bits Received

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__data'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,MemoryAsyncReadWrite]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__data:msk_top_regs_stat_32_bits_data_cls = msk_top_regs_stat_32_bits_data_cls( + parent_register=self, + size_props=FieldSizeProps( + width=32, + lsb=0, + msb=31, + low=0, + high=31), + misc_props=FieldMiscProps( + default=0, + is_volatile=True), + logger_handle=logger_handle+'.data', + inst_name='data', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.data + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def data(self) -> msk_top_regs_stat_32_bits_data_cls: + """ + Property to access data field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PRBS Bits Received | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Number of bits received by the PRBS monitor since last BER can | + | | be calculated as the ratio of received bits to errored-bits

| + | |

This register is write-to-capture.

To read data the | + | | following steps are required:

1 - Write any value to this | + | | register to capture read data

2 - Read the register

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__data + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'data':'data', + } + + + + + + + + + def get_child_by_system_rdl_name(self, name: Any) -> msk_top_regs_stat_32_bits_data_cls: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + + @property + def rdl_name(self) -> str: + return "PRBS Status 0" + @property + def rdl_desc(self) -> str: + return "PRBS Bits Received" + + + + + + + +class msk_top_regs_config_prbs_errmask_config_data_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PRBS Error Mask | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Bit positions set to '1' indicate bits that are inverted when a | + | | bit error is inserted

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "PRBS Error Mask" + @property + def rdl_desc(self) -> str: + return "Bit positions set to \u00271\u0027 indicate bits that are inverted when a bit error is inserted" + + + + + + +class msk_top_regs_config_prbs_errmask_cls(RegAsyncReadWrite): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PRBS Control 3 | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

PRBS Error Mask

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__config_data'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,MemoryAsyncReadWrite]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__config_data:msk_top_regs_config_prbs_errmask_config_data_cls = msk_top_regs_config_prbs_errmask_config_data_cls( + parent_register=self, + size_props=FieldSizeProps( + width=32, + lsb=0, + msb=31, + low=0, + high=31), + misc_props=FieldMiscProps( + default=0, + is_volatile=False), + logger_handle=logger_handle+'.config_data', + inst_name='config_data', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.config_data + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def config_data(self) -> msk_top_regs_config_prbs_errmask_config_data_cls: + """ + Property to access config_data field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PRBS Error Mask | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Bit positions set to '1' indicate bits that are inverted when a | + | | bit error is inserted

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__config_data + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'config_data':'config_data', + } + + + + + + + + + def get_child_by_system_rdl_name(self, name: Any) -> msk_top_regs_config_prbs_errmask_config_data_cls: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + + @property + def rdl_name(self) -> str: + return "PRBS Control 3" + @property + def rdl_desc(self) -> str: + return "PRBS Error Mask" + + + + + + + +class msk_top_regs_config_prbs_poly_config_data_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PRBS Polynomial | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Bit positions set to '1' indicate polynomial feedback | + | | positions

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "PRBS Polynomial" + @property + def rdl_desc(self) -> str: + return "Bit positions set to \u00271\u0027 indicate polynomial feedback positions" + + + + + + +class msk_top_regs_config_prbs_poly_cls(RegAsyncReadWrite): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PRBS Control 2 | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

PRBS Polynomial

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__config_data'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,MemoryAsyncReadWrite]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__config_data:msk_top_regs_config_prbs_poly_config_data_cls = msk_top_regs_config_prbs_poly_config_data_cls( + parent_register=self, + size_props=FieldSizeProps( + width=32, + lsb=0, + msb=31, + low=0, + high=31), + misc_props=FieldMiscProps( + default=0, + is_volatile=False), + logger_handle=logger_handle+'.config_data', + inst_name='config_data', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.config_data + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def config_data(self) -> msk_top_regs_config_prbs_poly_config_data_cls: + """ + Property to access config_data field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PRBS Polynomial | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Bit positions set to '1' indicate polynomial feedback | + | | positions

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__config_data + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'config_data':'config_data', + } + + + + + + + + + def get_child_by_system_rdl_name(self, name: Any) -> msk_top_regs_config_prbs_poly_config_data_cls: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + + @property + def rdl_name(self) -> str: + return "PRBS Control 2" + @property + def rdl_desc(self) -> str: + return "PRBS Polynomial" + + + + + + + +class msk_top_regs_config_prbs_seed_config_data_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PRBS Seed | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Sets the starting value of the PRBS generator

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "PRBS Seed" + @property + def rdl_desc(self) -> str: + return "Sets the starting value of the PRBS generator" + + + + + + +class msk_top_regs_config_prbs_seed_cls(RegAsyncReadWrite): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PRBS Control 1 | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

PRBS Initial State

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__config_data'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,MemoryAsyncReadWrite]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__config_data:msk_top_regs_config_prbs_seed_config_data_cls = msk_top_regs_config_prbs_seed_config_data_cls( + parent_register=self, + size_props=FieldSizeProps( + width=32, + lsb=0, + msb=31, + low=0, + high=31), + misc_props=FieldMiscProps( + default=0, + is_volatile=False), + logger_handle=logger_handle+'.config_data', + inst_name='config_data', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.config_data + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def config_data(self) -> msk_top_regs_config_prbs_seed_config_data_cls: + """ + Property to access config_data field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PRBS Seed | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Sets the starting value of the PRBS generator

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__config_data + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'config_data':'config_data', + } + + + + + + + + + def get_child_by_system_rdl_name(self, name: Any) -> msk_top_regs_config_prbs_seed_config_data_cls: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + + @property + def rdl_name(self) -> str: + return "PRBS Control 1" + @property + def rdl_desc(self) -> str: + return "PRBS Initial State" + + + + + + + +class msk_top_regs_prbs_ctrl_prbs_sync_threshold_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PRBS Auto Sync Threshold | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

0 : Auto Sync Disabled

N > 0 : Auto sync after N | + | | errors

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "PRBS Auto Sync Threshold" + @property + def rdl_desc(self) -> str: + return "0 : Auto Sync Disabled\n\nN \u003e 0 : Auto sync after N errors" + + + + + + + +class msk_top_regs_prbs_ctrl_prbs_reserved_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Reserved | + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Reserved" + + + + + + + +class msk_top_regs_prbs_ctrl_prbs_manual_sync_cls(FieldAsyncWriteOnly): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PRBS Manual Sync | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

0 -> 1 : Synchronize PRBS monitor

1 -> 0 : | + | | Synchronize PRBS monitor

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "PRBS Manual Sync" + @property + def rdl_desc(self) -> str: + return "0 -\u003e 1 : Synchronize PRBS monitor\n\n1 -\u003e 0 : Synchronize PRBS monitor" + + + + + + + +class msk_top_regs_prbs_ctrl_prbs_clear_cls(FieldAsyncWriteOnly): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PRBS Clear Counters | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

0 -> 1 : Clear PRBS Counters

1 -> 0 : Clear PRBS | + | | Counters

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "PRBS Clear Counters" + @property + def rdl_desc(self) -> str: + return "0 -\u003e 1 : Clear PRBS Counters\n\n1 -\u003e 0 : Clear PRBS Counters" + + + + + + + +class msk_top_regs_prbs_ctrl_prbs_error_insert_cls(FieldAsyncWriteOnly): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PRBS Error Insert | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

0 -> 1 : Insert bit error in Tx data (both Normal and | + | | PRBS)

1 -> 0 : Insert bit error in Tx data (both Normal | + | | and PRBS)

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "PRBS Error Insert" + @property + def rdl_desc(self) -> str: + return "0 -\u003e 1 : Insert bit error in Tx data (both Normal and PRBS)\n\n1 -\u003e 0 : Insert bit error in Tx data (both Normal and PRBS)" + + + + + + + +class msk_top_regs_prbs_ctrl_prbs_sel_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PRBS Data Select | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

0 -> Select Normal Tx Data 1 -> Select PRBS Tx Data

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "PRBS Data Select" + @property + def rdl_desc(self) -> str: + return "0 -\u003e Select Normal Tx Data\n1 -\u003e Select PRBS Tx Data" + + + + + + +class msk_top_regs_prbs_ctrl_cls(RegAsyncReadWrite): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PRBS Control 0 | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Configures operation of the PRBS Generator and Monitor

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__prbs_sel', '__prbs_error_insert', '__prbs_clear', '__prbs_manual_sync', '__prbs_reserved', '__prbs_sync_threshold'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,MemoryAsyncReadWrite]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__prbs_sel:msk_top_regs_prbs_ctrl_prbs_sel_cls = msk_top_regs_prbs_ctrl_prbs_sel_cls( + parent_register=self, + size_props=FieldSizeProps( + width=1, + lsb=0, + msb=0, + low=0, + high=0), + misc_props=FieldMiscProps( + default=0, + is_volatile=False), + logger_handle=logger_handle+'.prbs_sel', + inst_name='prbs_sel', + field_type=int) + self.__prbs_error_insert:msk_top_regs_prbs_ctrl_prbs_error_insert_cls = msk_top_regs_prbs_ctrl_prbs_error_insert_cls( + parent_register=self, + size_props=FieldSizeProps( + width=1, + lsb=1, + msb=1, + low=1, + high=1), + misc_props=FieldMiscProps( + default=0, + is_volatile=False), + logger_handle=logger_handle+'.prbs_error_insert', + inst_name='prbs_error_insert', + field_type=int) + self.__prbs_clear:msk_top_regs_prbs_ctrl_prbs_clear_cls = msk_top_regs_prbs_ctrl_prbs_clear_cls( + parent_register=self, + size_props=FieldSizeProps( + width=1, + lsb=2, + msb=2, + low=2, + high=2), + misc_props=FieldMiscProps( + default=0, + is_volatile=False), + logger_handle=logger_handle+'.prbs_clear', + inst_name='prbs_clear', + field_type=int) + self.__prbs_manual_sync:msk_top_regs_prbs_ctrl_prbs_manual_sync_cls = msk_top_regs_prbs_ctrl_prbs_manual_sync_cls( + parent_register=self, + size_props=FieldSizeProps( + width=1, + lsb=3, + msb=3, + low=3, + high=3), + misc_props=FieldMiscProps( + default=0, + is_volatile=False), + logger_handle=logger_handle+'.prbs_manual_sync', + inst_name='prbs_manual_sync', + field_type=int) + self.__prbs_reserved:msk_top_regs_prbs_ctrl_prbs_reserved_cls = msk_top_regs_prbs_ctrl_prbs_reserved_cls( + parent_register=self, + size_props=FieldSizeProps( + width=12, + lsb=4, + msb=15, + low=4, + high=15), + misc_props=FieldMiscProps( + default=0, + is_volatile=False), + logger_handle=logger_handle+'.prbs_reserved', + inst_name='prbs_reserved', + field_type=int) + self.__prbs_sync_threshold:msk_top_regs_prbs_ctrl_prbs_sync_threshold_cls = msk_top_regs_prbs_ctrl_prbs_sync_threshold_cls( + parent_register=self, + size_props=FieldSizeProps( + width=16, + lsb=16, + msb=31, + low=16, + high=31), + misc_props=FieldMiscProps( + default=0, + is_volatile=False), + logger_handle=logger_handle+'.prbs_sync_threshold', + inst_name='prbs_sync_threshold', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.prbs_sel + yield self.prbs_error_insert + yield self.prbs_clear + yield self.prbs_manual_sync + yield self.prbs_reserved + yield self.prbs_sync_threshold + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def prbs_sel(self) -> msk_top_regs_prbs_ctrl_prbs_sel_cls: + """ + Property to access prbs_sel field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PRBS Data Select | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

0 -> Select Normal Tx Data 1 -> Select PRBS Tx Data

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__prbs_sel + @property + def prbs_error_insert(self) -> msk_top_regs_prbs_ctrl_prbs_error_insert_cls: + """ + Property to access prbs_error_insert field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PRBS Error Insert | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

0 -> 1 : Insert bit error in Tx data (both Normal and | + | | PRBS)

1 -> 0 : Insert bit error in Tx data (both Normal | + | | and PRBS)

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__prbs_error_insert + @property + def prbs_clear(self) -> msk_top_regs_prbs_ctrl_prbs_clear_cls: + """ + Property to access prbs_clear field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PRBS Clear Counters | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

0 -> 1 : Clear PRBS Counters

1 -> 0 : Clear PRBS | + | | Counters

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__prbs_clear + @property + def prbs_manual_sync(self) -> msk_top_regs_prbs_ctrl_prbs_manual_sync_cls: + """ + Property to access prbs_manual_sync field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PRBS Manual Sync | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

0 -> 1 : Synchronize PRBS monitor

1 -> 0 : | + | | Synchronize PRBS monitor

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__prbs_manual_sync + @property + def prbs_reserved(self) -> msk_top_regs_prbs_ctrl_prbs_reserved_cls: + """ + Property to access prbs_reserved field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Reserved | + +--------------+-------------------------------------------------------------------------+ + """ + return self.__prbs_reserved + @property + def prbs_sync_threshold(self) -> msk_top_regs_prbs_ctrl_prbs_sync_threshold_cls: + """ + Property to access prbs_sync_threshold field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PRBS Auto Sync Threshold | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

0 : Auto Sync Disabled

N > 0 : Auto sync after N | + | | errors

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__prbs_sync_threshold + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'prbs_sel':'prbs_sel','prbs_error_insert':'prbs_error_insert','prbs_clear':'prbs_clear','prbs_manual_sync':'prbs_manual_sync','prbs_reserved':'prbs_reserved','prbs_sync_threshold':'prbs_sync_threshold', + } + + + + + + + + # nodes:6 + + @overload + def get_child_by_system_rdl_name(self, name: Literal["prbs_sel"]) -> msk_top_regs_prbs_ctrl_prbs_sel_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["prbs_error_insert"]) -> msk_top_regs_prbs_ctrl_prbs_error_insert_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["prbs_clear"]) -> msk_top_regs_prbs_ctrl_prbs_clear_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["prbs_manual_sync"]) -> msk_top_regs_prbs_ctrl_prbs_manual_sync_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["prbs_reserved"]) -> msk_top_regs_prbs_ctrl_prbs_reserved_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["prbs_sync_threshold"]) -> msk_top_regs_prbs_ctrl_prbs_sync_threshold_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: str) -> Union[msk_top_regs_prbs_ctrl_prbs_sel_cls, msk_top_regs_prbs_ctrl_prbs_error_insert_cls, msk_top_regs_prbs_ctrl_prbs_clear_cls, msk_top_regs_prbs_ctrl_prbs_manual_sync_cls, msk_top_regs_prbs_ctrl_prbs_reserved_cls, msk_top_regs_prbs_ctrl_prbs_sync_threshold_cls, ]: ... + + def get_child_by_system_rdl_name(self, name: Any) -> Any: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + @property + def rdl_name(self) -> str: + return "PRBS Control 0" + @property + def rdl_desc(self) -> str: + return "Configures operation of the PRBS Generator and Monitor" + + + + + + + +class msk_top_regs_data_width_data_width_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Modem input/output data width | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Set the data width of the modem input/output

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Modem input/output data width" + @property + def rdl_desc(self) -> str: + return "Set the data width of the modem input/output" + + + + + + +class msk_top_regs_data_width_desc_6097df38_name_4609588b_cls(RegAsyncReadWrite): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Modem Rx Output Data Width | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Set the parallel data width of the serial-to-parallel | + | | converter

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__data_width'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,MemoryAsyncReadWrite]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__data_width:msk_top_regs_data_width_data_width_cls = msk_top_regs_data_width_data_width_cls( + parent_register=self, + size_props=FieldSizeProps( + width=8, + lsb=0, + msb=7, + low=0, + high=7), + misc_props=FieldMiscProps( + default=8, + is_volatile=False), + logger_handle=logger_handle+'.data_width', + inst_name='data_width', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.data_width + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def data_width(self) -> msk_top_regs_data_width_data_width_cls: + """ + Property to access data_width field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Modem input/output data width | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Set the data width of the modem input/output

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__data_width + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'data_width':'data_width', + } + + + + + + + + + def get_child_by_system_rdl_name(self, name: Any) -> msk_top_regs_data_width_data_width_cls: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + + @property + def rdl_name(self) -> str: + return "Modem Rx Output Data Width" + @property + def rdl_desc(self) -> str: + return "Set the parallel data width of the serial-to-parallel converter" + + + + + + + +class msk_top_regs_data_width_data_width_0x0x1079ec62_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Modem input/output data width | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Set the data width of the modem input/output

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Modem input/output data width" + @property + def rdl_desc(self) -> str: + return "Set the data width of the modem input/output" + + + + + + +class msk_top_regs_data_width_desc_58c848dd_name_2fbd8eba_cls(RegAsyncReadWrite): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Modem Tx Input Data Width | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Set the parallel data width of the parallel-to-serial | + | | converter

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__data_width'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,MemoryAsyncReadWrite]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__data_width:msk_top_regs_data_width_data_width_0x0x1079ec62_cls = msk_top_regs_data_width_data_width_0x0x1079ec62_cls( + parent_register=self, + size_props=FieldSizeProps( + width=8, + lsb=0, + msb=7, + low=0, + high=7), + misc_props=FieldMiscProps( + default=8, + is_volatile=False), + logger_handle=logger_handle+'.data_width', + inst_name='data_width', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.data_width + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def data_width(self) -> msk_top_regs_data_width_data_width_0x0x1079ec62_cls: + """ + Property to access data_width field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Modem input/output data width | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Set the data width of the modem input/output

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__data_width + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'data_width':'data_width', + } + + + + + + + + + def get_child_by_system_rdl_name(self, name: Any) -> msk_top_regs_data_width_data_width_0x0x1079ec62_cls: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + + @property + def rdl_name(self) -> str: + return "Modem Tx Input Data Width" + @property + def rdl_desc(self) -> str: + return "Set the parallel data width of the parallel-to-serial converter" + + + + + + + +class msk_top_regs_lpf_config_1_i_shift_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Integral Gain Bit Shift | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Value n of 0-32 sets the integral divisor as 2^-n

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Integral Gain Bit Shift" + @property + def rdl_desc(self) -> str: + return "Value n of 0-32 sets the integral divisor as 2^-n" + + + + + + + +class msk_top_regs_lpf_config_1_i_gain_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Integral Gain Value | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Value m of 0-16,777,215 sets the integral multiplier

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Integral Gain Value" + @property + def rdl_desc(self) -> str: + return "Value m of 0-16,777,215 sets the integral multiplier" + + + + + + +class msk_top_regs_lpf_config_1_cls(RegAsyncReadWrite): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PI Controller Configuration Configuration Register 1 | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Configures PI Controller I-gain and divisor

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__i_gain', '__i_shift'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,MemoryAsyncReadWrite]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__i_gain:msk_top_regs_lpf_config_1_i_gain_cls = msk_top_regs_lpf_config_1_i_gain_cls( + parent_register=self, + size_props=FieldSizeProps( + width=24, + lsb=0, + msb=23, + low=0, + high=23), + misc_props=FieldMiscProps( + default=0, + is_volatile=False), + logger_handle=logger_handle+'.i_gain', + inst_name='i_gain', + field_type=int) + self.__i_shift:msk_top_regs_lpf_config_1_i_shift_cls = msk_top_regs_lpf_config_1_i_shift_cls( + parent_register=self, + size_props=FieldSizeProps( + width=8, + lsb=24, + msb=31, + low=24, + high=31), + misc_props=FieldMiscProps( + default=0, + is_volatile=False), + logger_handle=logger_handle+'.i_shift', + inst_name='i_shift', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.i_gain + yield self.i_shift + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def i_gain(self) -> msk_top_regs_lpf_config_1_i_gain_cls: + """ + Property to access i_gain field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Integral Gain Value | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Value m of 0-16,777,215 sets the integral multiplier

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__i_gain + @property + def i_shift(self) -> msk_top_regs_lpf_config_1_i_shift_cls: + """ + Property to access i_shift field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Integral Gain Bit Shift | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Value n of 0-32 sets the integral divisor as 2^-n

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__i_shift + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'i_gain':'i_gain','i_shift':'i_shift', + } + + + + + + + + # nodes:2 + + @overload + def get_child_by_system_rdl_name(self, name: Literal["i_gain"]) -> msk_top_regs_lpf_config_1_i_gain_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["i_shift"]) -> msk_top_regs_lpf_config_1_i_shift_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: str) -> Union[msk_top_regs_lpf_config_1_i_gain_cls, msk_top_regs_lpf_config_1_i_shift_cls, ]: ... + + def get_child_by_system_rdl_name(self, name: Any) -> Any: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + @property + def rdl_name(self) -> str: + return "PI Controller Configuration Configuration Register 1" + @property + def rdl_desc(self) -> str: + return "Configures PI Controller I-gain and divisor" + + + + + + + +class msk_top_regs_lpf_config_0_lpf_alpha_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Lowpass IIR filter alpha | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Value controls the filter rolloff

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Lowpass IIR filter alpha" + @property + def rdl_desc(self) -> str: + return "Value controls the filter rolloff" + + + + + + + +class msk_top_regs_lpf_config_0_prbs_reserved_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Reserved | + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Reserved" + + + + + + + +class msk_top_regs_lpf_config_0_lpf_zero_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Hold the PI Accumulator at zero | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

0 -> Normal operation

1 -> Zero and hold | + | | accumulator

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Hold the PI Accumulator at zero" + @property + def rdl_desc(self) -> str: + return "0 -\u003e Normal operation\n\n1 -\u003e Zero and hold accumulator" + + + + + + + +class msk_top_regs_lpf_config_0_lpf_freeze_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Freeze the accumulator's current value | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

0 -> Normal operation

1 -> Freeze current | + | | value

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Freeze the accumulator\u0027s current value" + @property + def rdl_desc(self) -> str: + return "0 -\u003e Normal operation\n\n1 -\u003e Freeze current value" + + + + + + +class msk_top_regs_lpf_config_0_cls(RegAsyncReadWrite): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PI Controller Configuration and Low-pass Filter Configuration | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Configure PI controller and low-pass filter

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__lpf_freeze', '__lpf_zero', '__prbs_reserved', '__lpf_alpha'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,MemoryAsyncReadWrite]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__lpf_freeze:msk_top_regs_lpf_config_0_lpf_freeze_cls = msk_top_regs_lpf_config_0_lpf_freeze_cls( + parent_register=self, + size_props=FieldSizeProps( + width=1, + lsb=0, + msb=0, + low=0, + high=0), + misc_props=FieldMiscProps( + default=0, + is_volatile=False), + logger_handle=logger_handle+'.lpf_freeze', + inst_name='lpf_freeze', + field_type=int) + self.__lpf_zero:msk_top_regs_lpf_config_0_lpf_zero_cls = msk_top_regs_lpf_config_0_lpf_zero_cls( + parent_register=self, + size_props=FieldSizeProps( + width=1, + lsb=1, + msb=1, + low=1, + high=1), + misc_props=FieldMiscProps( + default=0, + is_volatile=False), + logger_handle=logger_handle+'.lpf_zero', + inst_name='lpf_zero', + field_type=int) + self.__prbs_reserved:msk_top_regs_lpf_config_0_prbs_reserved_cls = msk_top_regs_lpf_config_0_prbs_reserved_cls( + parent_register=self, + size_props=FieldSizeProps( + width=6, + lsb=2, + msb=7, + low=2, + high=7), + misc_props=FieldMiscProps( + default=0, + is_volatile=False), + logger_handle=logger_handle+'.prbs_reserved', + inst_name='prbs_reserved', + field_type=int) + self.__lpf_alpha:msk_top_regs_lpf_config_0_lpf_alpha_cls = msk_top_regs_lpf_config_0_lpf_alpha_cls( + parent_register=self, + size_props=FieldSizeProps( + width=24, + lsb=8, + msb=31, + low=8, + high=31), + misc_props=FieldMiscProps( + default=0, + is_volatile=False), + logger_handle=logger_handle+'.lpf_alpha', + inst_name='lpf_alpha', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.lpf_freeze + yield self.lpf_zero + yield self.prbs_reserved + yield self.lpf_alpha + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def lpf_freeze(self) -> msk_top_regs_lpf_config_0_lpf_freeze_cls: + """ + Property to access lpf_freeze field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Freeze the accumulator's current value | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

0 -> Normal operation

1 -> Freeze current | + | | value

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__lpf_freeze + @property + def lpf_zero(self) -> msk_top_regs_lpf_config_0_lpf_zero_cls: + """ + Property to access lpf_zero field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Hold the PI Accumulator at zero | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

0 -> Normal operation

1 -> Zero and hold | + | | accumulator

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__lpf_zero + @property + def prbs_reserved(self) -> msk_top_regs_lpf_config_0_prbs_reserved_cls: + """ + Property to access prbs_reserved field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Reserved | + +--------------+-------------------------------------------------------------------------+ + """ + return self.__prbs_reserved + @property + def lpf_alpha(self) -> msk_top_regs_lpf_config_0_lpf_alpha_cls: + """ + Property to access lpf_alpha field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Lowpass IIR filter alpha | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Value controls the filter rolloff

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__lpf_alpha + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'lpf_freeze':'lpf_freeze','lpf_zero':'lpf_zero','prbs_reserved':'prbs_reserved','lpf_alpha':'lpf_alpha', + } + + + + + + + + # nodes:4 + + @overload + def get_child_by_system_rdl_name(self, name: Literal["lpf_freeze"]) -> msk_top_regs_lpf_config_0_lpf_freeze_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["lpf_zero"]) -> msk_top_regs_lpf_config_0_lpf_zero_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["prbs_reserved"]) -> msk_top_regs_lpf_config_0_prbs_reserved_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["lpf_alpha"]) -> msk_top_regs_lpf_config_0_lpf_alpha_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: str) -> Union[msk_top_regs_lpf_config_0_lpf_freeze_cls, msk_top_regs_lpf_config_0_lpf_zero_cls, msk_top_regs_lpf_config_0_prbs_reserved_cls, msk_top_regs_lpf_config_0_lpf_alpha_cls, ]: ... + + def get_child_by_system_rdl_name(self, name: Any) -> Any: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + @property + def rdl_name(self) -> str: + return "PI Controller Configuration and Low-pass Filter Configuration" + @property + def rdl_desc(self) -> str: + return "Configure PI controller and low-pass filter" + + + + + + + +class msk_top_regs_config_nco_fw_config_data_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Frequency Control Word | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Sets the center frequency of the NCO as FW = Fn * 2^32/Fs, | + | | where Fn is the desired NCO frequency, and Fs is the NCO sample | + | | rate

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Frequency Control Word" + @property + def rdl_desc(self) -> str: + return "Sets the center frequency of the NCO as FW = Fn * 2^32/Fs, \nwhere Fn is the desired NCO frequency, and Fs is the NCO sample rate" + + + + + + +class msk_top_regs_config_nco_fw_desc_43c0828f_name_bdc60ecf_cls(RegAsyncReadWrite): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Rx F2 NCO Frequency Control Word | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Set Demodulator F2 Frequency

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__config_data'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,MemoryAsyncReadWrite]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__config_data:msk_top_regs_config_nco_fw_config_data_cls = msk_top_regs_config_nco_fw_config_data_cls( + parent_register=self, + size_props=FieldSizeProps( + width=32, + lsb=0, + msb=31, + low=0, + high=31), + misc_props=FieldMiscProps( + default=0, + is_volatile=False), + logger_handle=logger_handle+'.config_data', + inst_name='config_data', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.config_data + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def config_data(self) -> msk_top_regs_config_nco_fw_config_data_cls: + """ + Property to access config_data field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Frequency Control Word | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Sets the center frequency of the NCO as FW = Fn * 2^32/Fs, | + | | where Fn is the desired NCO frequency, and Fs is the NCO sample | + | | rate

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__config_data + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'config_data':'config_data', + } + + + + + + + + + def get_child_by_system_rdl_name(self, name: Any) -> msk_top_regs_config_nco_fw_config_data_cls: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + + @property + def rdl_name(self) -> str: + return "Rx F2 NCO Frequency Control Word" + @property + def rdl_desc(self) -> str: + return "Set Demodulator F2 Frequency" + + + + + + + +class msk_top_regs_config_nco_fw_config_data_0x0x1079c844_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Frequency Control Word | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Sets the center frequency of the NCO as FW = Fn * 2^32/Fs, | + | | where Fn is the desired NCO frequency, and Fs is the NCO sample | + | | rate

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Frequency Control Word" + @property + def rdl_desc(self) -> str: + return "Sets the center frequency of the NCO as FW = Fn * 2^32/Fs, \nwhere Fn is the desired NCO frequency, and Fs is the NCO sample rate" + + + + + + +class msk_top_regs_config_nco_fw_desc_16fb48c8_name_8d01a20d_cls(RegAsyncReadWrite): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Rx F1 NCO Frequency Control Word | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Set Demodulator F1 Frequency

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__config_data'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,MemoryAsyncReadWrite]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__config_data:msk_top_regs_config_nco_fw_config_data_0x0x1079c844_cls = msk_top_regs_config_nco_fw_config_data_0x0x1079c844_cls( + parent_register=self, + size_props=FieldSizeProps( + width=32, + lsb=0, + msb=31, + low=0, + high=31), + misc_props=FieldMiscProps( + default=0, + is_volatile=False), + logger_handle=logger_handle+'.config_data', + inst_name='config_data', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.config_data + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def config_data(self) -> msk_top_regs_config_nco_fw_config_data_0x0x1079c844_cls: + """ + Property to access config_data field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Frequency Control Word | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Sets the center frequency of the NCO as FW = Fn * 2^32/Fs, | + | | where Fn is the desired NCO frequency, and Fs is the NCO sample | + | | rate

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__config_data + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'config_data':'config_data', + } + + + + + + + + + def get_child_by_system_rdl_name(self, name: Any) -> msk_top_regs_config_nco_fw_config_data_0x0x1079c844_cls: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + + @property + def rdl_name(self) -> str: + return "Rx F1 NCO Frequency Control Word" + @property + def rdl_desc(self) -> str: + return "Set Demodulator F1 Frequency" + + + + + + + +class msk_top_regs_config_nco_fw_config_data_0x0x1079621e_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Frequency Control Word | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Sets the center frequency of the NCO as FW = Fn * 2^32/Fs, | + | | where Fn is the desired NCO frequency, and Fs is the NCO sample | + | | rate

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Frequency Control Word" + @property + def rdl_desc(self) -> str: + return "Sets the center frequency of the NCO as FW = Fn * 2^32/Fs, \nwhere Fn is the desired NCO frequency, and Fs is the NCO sample rate" + + + + + + +class msk_top_regs_config_nco_fw_desc_42134a4f_name_d97dbd51_cls(RegAsyncReadWrite): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Tx F2 NCO Frequency Control Word | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Set Modulator F2 Frequency

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__config_data'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,MemoryAsyncReadWrite]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__config_data:msk_top_regs_config_nco_fw_config_data_0x0x1079621e_cls = msk_top_regs_config_nco_fw_config_data_0x0x1079621e_cls( + parent_register=self, + size_props=FieldSizeProps( + width=32, + lsb=0, + msb=31, + low=0, + high=31), + misc_props=FieldMiscProps( + default=0, + is_volatile=False), + logger_handle=logger_handle+'.config_data', + inst_name='config_data', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.config_data + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def config_data(self) -> msk_top_regs_config_nco_fw_config_data_0x0x1079621e_cls: + """ + Property to access config_data field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Frequency Control Word | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Sets the center frequency of the NCO as FW = Fn * 2^32/Fs, | + | | where Fn is the desired NCO frequency, and Fs is the NCO sample | + | | rate

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__config_data + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'config_data':'config_data', + } + + + + + + + + + def get_child_by_system_rdl_name(self, name: Any) -> msk_top_regs_config_nco_fw_config_data_0x0x1079621e_cls: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + + @property + def rdl_name(self) -> str: + return "Tx F2 NCO Frequency Control Word" + @property + def rdl_desc(self) -> str: + return "Set Modulator F2 Frequency" + + + + + + + +class msk_top_regs_config_nco_fw_config_data_0x0x1079636b_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Frequency Control Word | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Sets the center frequency of the NCO as FW = Fn * 2^32/Fs, | + | | where Fn is the desired NCO frequency, and Fs is the NCO sample | + | | rate

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Frequency Control Word" + @property + def rdl_desc(self) -> str: + return "Sets the center frequency of the NCO as FW = Fn * 2^32/Fs, \nwhere Fn is the desired NCO frequency, and Fs is the NCO sample rate" + + + + + + +class msk_top_regs_config_nco_fw_desc_94d7aaf5_name_84dd0c1c_cls(RegAsyncReadWrite): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Tx F1 NCO Frequency Control Word | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Set Modulator F1 Frequency

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__config_data'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,MemoryAsyncReadWrite]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__config_data:msk_top_regs_config_nco_fw_config_data_0x0x1079636b_cls = msk_top_regs_config_nco_fw_config_data_0x0x1079636b_cls( + parent_register=self, + size_props=FieldSizeProps( + width=32, + lsb=0, + msb=31, + low=0, + high=31), + misc_props=FieldMiscProps( + default=0, + is_volatile=False), + logger_handle=logger_handle+'.config_data', + inst_name='config_data', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.config_data + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def config_data(self) -> msk_top_regs_config_nco_fw_config_data_0x0x1079636b_cls: + """ + Property to access config_data field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Frequency Control Word | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Sets the center frequency of the NCO as FW = Fn * 2^32/Fs, | + | | where Fn is the desired NCO frequency, and Fs is the NCO sample | + | | rate

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__config_data + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'config_data':'config_data', + } + + + + + + + + + def get_child_by_system_rdl_name(self, name: Any) -> msk_top_regs_config_nco_fw_config_data_0x0x1079636b_cls: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + + @property + def rdl_name(self) -> str: + return "Tx F1 NCO Frequency Control Word" + @property + def rdl_desc(self) -> str: + return "Set Modulator F1 Frequency" + + + + + + + +class msk_top_regs_config_nco_fw_config_data_0x0x11011ef6_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Frequency Control Word | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Sets the center frequency of the NCO as FW = Fn * 2^32/Fs, | + | | where Fn is the desired NCO frequency, and Fs is the NCO sample | + | | rate

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Frequency Control Word" + @property + def rdl_desc(self) -> str: + return "Sets the center frequency of the NCO as FW = Fn * 2^32/Fs, \nwhere Fn is the desired NCO frequency, and Fs is the NCO sample rate" + + + + + + +class msk_top_regs_config_nco_fw_desc_c4924cc6_name_0c494469_cls(RegAsyncReadWrite): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Bitrate NCO Frequency Control Word | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Set Modem Data Rate

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__config_data'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,MemoryAsyncReadWrite]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__config_data:msk_top_regs_config_nco_fw_config_data_0x0x11011ef6_cls = msk_top_regs_config_nco_fw_config_data_0x0x11011ef6_cls( + parent_register=self, + size_props=FieldSizeProps( + width=32, + lsb=0, + msb=31, + low=0, + high=31), + misc_props=FieldMiscProps( + default=0, + is_volatile=False), + logger_handle=logger_handle+'.config_data', + inst_name='config_data', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.config_data + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def config_data(self) -> msk_top_regs_config_nco_fw_config_data_0x0x11011ef6_cls: + """ + Property to access config_data field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Frequency Control Word | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Sets the center frequency of the NCO as FW = Fn * 2^32/Fs, | + | | where Fn is the desired NCO frequency, and Fs is the NCO sample | + | | rate

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__config_data + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'config_data':'config_data', + } + + + + + + + + + def get_child_by_system_rdl_name(self, name: Any) -> msk_top_regs_config_nco_fw_config_data_0x0x11011ef6_cls: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + + @property + def rdl_name(self) -> str: + return "Bitrate NCO Frequency Control Word" + @property + def rdl_desc(self) -> str: + return "Set Modem Data Rate" + + + + + + + +class msk_top_regs_msk_stat_2_data_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Tx Enable Count | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Number of clocks on which Tx Enable is active

This | + | | register is write-to-capture.

To read data the following | + | | steps are required:

1 - Write any value to this register to | + | | capture read data

2 - Read the register

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Tx Enable Count" + @property + def rdl_desc(self) -> str: + return "Number of clocks on which Tx Enable is active\n\nThis register is write-to-capture.\n\nTo read data the following steps are required:\n\n1 - Write any value to this register to capture read data\n\n2 - Read the register" + + + + + + +class msk_top_regs_msk_stat_2_cls(RegAsyncReadWrite): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | MSK Modem Status 2 | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Modem status data

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__data'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,MemoryAsyncReadWrite]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__data:msk_top_regs_msk_stat_2_data_cls = msk_top_regs_msk_stat_2_data_cls( + parent_register=self, + size_props=FieldSizeProps( + width=32, + lsb=0, + msb=31, + low=0, + high=31), + misc_props=FieldMiscProps( + default=0, + is_volatile=True), + logger_handle=logger_handle+'.data', + inst_name='data', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.data + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def data(self) -> msk_top_regs_msk_stat_2_data_cls: + """ + Property to access data field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Tx Enable Count | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Number of clocks on which Tx Enable is active

This | + | | register is write-to-capture.

To read data the following | + | | steps are required:

1 - Write any value to this register to | + | | capture read data

2 - Read the register

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__data + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'data':'data', + } + + + + + + + + + def get_child_by_system_rdl_name(self, name: Any) -> msk_top_regs_msk_stat_2_data_cls: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + + @property + def rdl_name(self) -> str: + return "MSK Modem Status 2" + @property + def rdl_desc(self) -> str: + return "Modem status data" + + + + + + + +class msk_top_regs_msk_stat_1_data_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Tx Bit Count | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Count of data requests made by modem

This register is | + | | write-to-capture.

To read data the following steps are | + | | required:

1 - Write any value to this register to capture | + | | read data

2 - Read the register

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Tx Bit Count" + @property + def rdl_desc(self) -> str: + return "Count of data requests made by modem\n\nThis register is write-to-capture.\n\nTo read data the following steps are required:\n\n1 - Write any value to this register to capture read data\n\n2 - Read the register" + + + + + + +class msk_top_regs_msk_stat_1_cls(RegAsyncReadWrite): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | MSK Modem Status 1 | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Modem status data

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__data'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,MemoryAsyncReadWrite]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__data:msk_top_regs_msk_stat_1_data_cls = msk_top_regs_msk_stat_1_data_cls( + parent_register=self, + size_props=FieldSizeProps( + width=32, + lsb=0, + msb=31, + low=0, + high=31), + misc_props=FieldMiscProps( + default=0, + is_volatile=True), + logger_handle=logger_handle+'.data', + inst_name='data', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.data + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def data(self) -> msk_top_regs_msk_stat_1_data_cls: + """ + Property to access data field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Tx Bit Count | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Count of data requests made by modem

This register is | + | | write-to-capture.

To read data the following steps are | + | | required:

1 - Write any value to this register to capture | + | | read data

2 - Read the register

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__data + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'data':'data', + } + + + + + + + + + def get_child_by_system_rdl_name(self, name: Any) -> msk_top_regs_msk_stat_1_data_cls: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + + @property + def rdl_name(self) -> str: + return "MSK Modem Status 1" + @property + def rdl_desc(self) -> str: + return "Modem status data" + + + + + + + +class msk_top_regs_msk_stat_0_tx_axis_valid_cls(FieldAsyncReadOnly): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Tx S_AXIS_VALID | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

1 -> S_AXIS_VALID Enabled

0 -> S_AXIS_VALID | + | | Disabled

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Tx S_AXIS_VALID" + @property + def rdl_desc(self) -> str: + return "1 -\u003e S_AXIS_VALID Enabled\n\n0 -\u003e S_AXIS_VALID Disabled" + + + + + + + +class msk_top_regs_msk_stat_0_rx_enable_cls(FieldAsyncReadOnly): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | AD9363 ADC Interface Rx Enable Input Active | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

1 -> Data from ADC Enabled

0 -> Data from ADC | + | | Disabled

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "AD9363 ADC Interface Rx Enable Input Active" + @property + def rdl_desc(self) -> str: + return "1 -\u003e Data from ADC Enabled\n\n0 -\u003e Data from ADC Disabled" + + + + + + + +class msk_top_regs_msk_stat_0_tx_enable_cls(FieldAsyncReadOnly): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | AD9363 DAC Interface Tx Enable Input Active | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

1 -> Data to DAC Enabled

0 -> Data to DAC | + | | Disabled

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "AD9363 DAC Interface Tx Enable Input Active" + @property + def rdl_desc(self) -> str: + return "1 -\u003e Data to DAC Enabled\n\n0 -\u003e Data to DAC Disabled" + + + + + + + +class msk_top_regs_msk_stat_0_demod_sync_lock_cls(FieldAsyncReadOnly): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Demodulator Sync Status | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Demodulator Sync Status - not currently implemented

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Demodulator Sync Status" + @property + def rdl_desc(self) -> str: + return "Demodulator Sync Status - not currently implemented" + + + + + + +class msk_top_regs_msk_stat_0_cls(RegAsyncReadOnly): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | MSK Modem Status 0 | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Modem status bits

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__demod_sync_lock', '__tx_enable', '__rx_enable', '__tx_axis_valid'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,ReadableAsyncMemory]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__demod_sync_lock:msk_top_regs_msk_stat_0_demod_sync_lock_cls = msk_top_regs_msk_stat_0_demod_sync_lock_cls( + parent_register=self, + size_props=FieldSizeProps( + width=1, + lsb=0, + msb=0, + low=0, + high=0), + misc_props=FieldMiscProps( + default=0, + is_volatile=True), + logger_handle=logger_handle+'.demod_sync_lock', + inst_name='demod_sync_lock', + field_type=int) + self.__tx_enable:msk_top_regs_msk_stat_0_tx_enable_cls = msk_top_regs_msk_stat_0_tx_enable_cls( + parent_register=self, + size_props=FieldSizeProps( + width=1, + lsb=1, + msb=1, + low=1, + high=1), + misc_props=FieldMiscProps( + default=0, + is_volatile=True), + logger_handle=logger_handle+'.tx_enable', + inst_name='tx_enable', + field_type=int) + self.__rx_enable:msk_top_regs_msk_stat_0_rx_enable_cls = msk_top_regs_msk_stat_0_rx_enable_cls( + parent_register=self, + size_props=FieldSizeProps( + width=1, + lsb=2, + msb=2, + low=2, + high=2), + misc_props=FieldMiscProps( + default=0, + is_volatile=True), + logger_handle=logger_handle+'.rx_enable', + inst_name='rx_enable', + field_type=int) + self.__tx_axis_valid:msk_top_regs_msk_stat_0_tx_axis_valid_cls = msk_top_regs_msk_stat_0_tx_axis_valid_cls( + parent_register=self, + size_props=FieldSizeProps( + width=1, + lsb=3, + msb=3, + low=3, + high=3), + misc_props=FieldMiscProps( + default=0, + is_volatile=True), + logger_handle=logger_handle+'.tx_axis_valid', + inst_name='tx_axis_valid', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.demod_sync_lock + yield self.tx_enable + yield self.rx_enable + yield self.tx_axis_valid + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def demod_sync_lock(self) -> msk_top_regs_msk_stat_0_demod_sync_lock_cls: + """ + Property to access demod_sync_lock field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Demodulator Sync Status | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Demodulator Sync Status - not currently implemented

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__demod_sync_lock + @property + def tx_enable(self) -> msk_top_regs_msk_stat_0_tx_enable_cls: + """ + Property to access tx_enable field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | AD9363 DAC Interface Tx Enable Input Active | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

1 -> Data to DAC Enabled

0 -> Data to DAC | + | | Disabled

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__tx_enable + @property + def rx_enable(self) -> msk_top_regs_msk_stat_0_rx_enable_cls: + """ + Property to access rx_enable field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | AD9363 ADC Interface Rx Enable Input Active | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

1 -> Data from ADC Enabled

0 -> Data from ADC | + | | Disabled

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__rx_enable + @property + def tx_axis_valid(self) -> msk_top_regs_msk_stat_0_tx_axis_valid_cls: + """ + Property to access tx_axis_valid field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Tx S_AXIS_VALID | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

1 -> S_AXIS_VALID Enabled

0 -> S_AXIS_VALID | + | | Disabled

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__tx_axis_valid + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'demod_sync_lock':'demod_sync_lock','tx_enable':'tx_enable','rx_enable':'rx_enable','tx_axis_valid':'tx_axis_valid', + } + + + + + + + + # nodes:4 + + @overload + def get_child_by_system_rdl_name(self, name: Literal["demod_sync_lock"]) -> msk_top_regs_msk_stat_0_demod_sync_lock_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["tx_enable"]) -> msk_top_regs_msk_stat_0_tx_enable_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["rx_enable"]) -> msk_top_regs_msk_stat_0_rx_enable_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["tx_axis_valid"]) -> msk_top_regs_msk_stat_0_tx_axis_valid_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: str) -> Union[msk_top_regs_msk_stat_0_demod_sync_lock_cls, msk_top_regs_msk_stat_0_tx_enable_cls, msk_top_regs_msk_stat_0_rx_enable_cls, msk_top_regs_msk_stat_0_tx_axis_valid_cls, ]: ... + + def get_child_by_system_rdl_name(self, name: Any) -> Any: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + @property + def rdl_name(self) -> str: + return "MSK Modem Status 0" + @property + def rdl_desc(self) -> str: + return "Modem status bits" + + + + + + + +class msk_top_regs_msk_ctrl_diff_encoder_loopback_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Differential Encoder -> Decoder Loopback Enable | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

0 -> Differential Encoder -> Decoder loopback | + | | disabled

1 -> Differential Encoder -> Decoder | + | | loopback enabled

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Differential Encoder -\u003e Decoder Loopback Enable" + @property + def rdl_desc(self) -> str: + return "0 -\u003e Differential Encoder -\u003e Decoder loopback disabled\n\n1 -\u003e Differential Encoder -\u003e Decoder loopback enabled" + + + + + + + +class msk_top_regs_msk_ctrl_clear_counts_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Clear Status Counters | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Clear Tx Bit Counter and Tx Enable Counter

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Clear Status Counters" + @property + def rdl_desc(self) -> str: + return "Clear Tx Bit Counter and Tx Enable Counter" + + + + + + + +class msk_top_regs_msk_ctrl_rx_invert_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Rx Data Invert Enable | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

0 -> Rx data normal 1 -> Rx data inverted

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Rx Data Invert Enable" + @property + def rdl_desc(self) -> str: + return "0 -\u003e Rx data normal\n1 -\u003e Rx data inverted" + + + + + + + +class msk_top_regs_msk_ctrl_loopback_ena_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Modem Digital Tx -> Rx Loopback Enable | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

0 -> Modem loopback disabled

1 -> Modem loopback | + | | enabled

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Modem Digital Tx -\u003e Rx Loopback Enable" + @property + def rdl_desc(self) -> str: + return "0 -\u003e Modem loopback disabled\n\n1 -\u003e Modem loopback enabled" + + + + + + + +class msk_top_regs_msk_ctrl_ptt_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Push-to-Talk Enable | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

0 -> PTT Disabled 1 -> PTT Enabled

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Push-to-Talk Enable" + @property + def rdl_desc(self) -> str: + return "0 -\u003e PTT Disabled\n1 -\u003e PTT Enabled" + + + + + + +class msk_top_regs_msk_ctrl_cls(RegAsyncReadWrite): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | MSK Modem Control | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

MSK Modem Configuration and Control

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__ptt', '__loopback_ena', '__rx_invert', '__clear_counts', '__diff_encoder_loopback'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,MemoryAsyncReadWrite]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__ptt:msk_top_regs_msk_ctrl_ptt_cls = msk_top_regs_msk_ctrl_ptt_cls( + parent_register=self, + size_props=FieldSizeProps( + width=1, + lsb=0, + msb=0, + low=0, + high=0), + misc_props=FieldMiscProps( + default=0, + is_volatile=False), + logger_handle=logger_handle+'.ptt', + inst_name='ptt', + field_type=int) + self.__loopback_ena:msk_top_regs_msk_ctrl_loopback_ena_cls = msk_top_regs_msk_ctrl_loopback_ena_cls( + parent_register=self, + size_props=FieldSizeProps( + width=1, + lsb=1, + msb=1, + low=1, + high=1), + misc_props=FieldMiscProps( + default=0, + is_volatile=False), + logger_handle=logger_handle+'.loopback_ena', + inst_name='loopback_ena', + field_type=int) + self.__rx_invert:msk_top_regs_msk_ctrl_rx_invert_cls = msk_top_regs_msk_ctrl_rx_invert_cls( + parent_register=self, + size_props=FieldSizeProps( + width=1, + lsb=2, + msb=2, + low=2, + high=2), + misc_props=FieldMiscProps( + default=0, + is_volatile=False), + logger_handle=logger_handle+'.rx_invert', + inst_name='rx_invert', + field_type=int) + self.__clear_counts:msk_top_regs_msk_ctrl_clear_counts_cls = msk_top_regs_msk_ctrl_clear_counts_cls( + parent_register=self, + size_props=FieldSizeProps( + width=1, + lsb=3, + msb=3, + low=3, + high=3), + misc_props=FieldMiscProps( + default=0, + is_volatile=False), + logger_handle=logger_handle+'.clear_counts', + inst_name='clear_counts', + field_type=int) + self.__diff_encoder_loopback:msk_top_regs_msk_ctrl_diff_encoder_loopback_cls = msk_top_regs_msk_ctrl_diff_encoder_loopback_cls( + parent_register=self, + size_props=FieldSizeProps( + width=1, + lsb=4, + msb=4, + low=4, + high=4), + misc_props=FieldMiscProps( + default=0, + is_volatile=False), + logger_handle=logger_handle+'.diff_encoder_loopback', + inst_name='diff_encoder_loopback', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.ptt + yield self.loopback_ena + yield self.rx_invert + yield self.clear_counts + yield self.diff_encoder_loopback + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def ptt(self) -> msk_top_regs_msk_ctrl_ptt_cls: + """ + Property to access ptt field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Push-to-Talk Enable | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

0 -> PTT Disabled 1 -> PTT Enabled

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__ptt + @property + def loopback_ena(self) -> msk_top_regs_msk_ctrl_loopback_ena_cls: + """ + Property to access loopback_ena field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Modem Digital Tx -> Rx Loopback Enable | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

0 -> Modem loopback disabled

1 -> Modem loopback | + | | enabled

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__loopback_ena + @property + def rx_invert(self) -> msk_top_regs_msk_ctrl_rx_invert_cls: + """ + Property to access rx_invert field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Rx Data Invert Enable | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

0 -> Rx data normal 1 -> Rx data inverted

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__rx_invert + @property + def clear_counts(self) -> msk_top_regs_msk_ctrl_clear_counts_cls: + """ + Property to access clear_counts field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Clear Status Counters | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Clear Tx Bit Counter and Tx Enable Counter

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__clear_counts + @property + def diff_encoder_loopback(self) -> msk_top_regs_msk_ctrl_diff_encoder_loopback_cls: + """ + Property to access diff_encoder_loopback field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Differential Encoder -> Decoder Loopback Enable | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

0 -> Differential Encoder -> Decoder loopback | + | | disabled

1 -> Differential Encoder -> Decoder | + | | loopback enabled

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__diff_encoder_loopback + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'ptt':'ptt','loopback_ena':'loopback_ena','rx_invert':'rx_invert','clear_counts':'clear_counts','diff_encoder_loopback':'diff_encoder_loopback', + } + + + + + + + + # nodes:5 + + @overload + def get_child_by_system_rdl_name(self, name: Literal["ptt"]) -> msk_top_regs_msk_ctrl_ptt_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["loopback_ena"]) -> msk_top_regs_msk_ctrl_loopback_ena_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["rx_invert"]) -> msk_top_regs_msk_ctrl_rx_invert_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["clear_counts"]) -> msk_top_regs_msk_ctrl_clear_counts_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["diff_encoder_loopback"]) -> msk_top_regs_msk_ctrl_diff_encoder_loopback_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: str) -> Union[msk_top_regs_msk_ctrl_ptt_cls, msk_top_regs_msk_ctrl_loopback_ena_cls, msk_top_regs_msk_ctrl_rx_invert_cls, msk_top_regs_msk_ctrl_clear_counts_cls, msk_top_regs_msk_ctrl_diff_encoder_loopback_cls, ]: ... + + def get_child_by_system_rdl_name(self, name: Any) -> Any: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + @property + def rdl_name(self) -> str: + return "MSK Modem Control" + @property + def rdl_desc(self) -> str: + return "MSK Modem Configuration and Control" + + + + + + + +class msk_top_regs_msk_init_rxinit_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Rx Init Enable | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

0 -> Normal Rx operation

1 -> Initialize Rx

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Rx Init Enable" + @property + def rdl_desc(self) -> str: + return "0 -\u003e Normal Rx operation \n\n1 -\u003e Initialize Rx" + + + + + + + +class msk_top_regs_msk_init_txinit_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Tx Init Enable | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

0 -> Normal Tx operation

1 -> Initialize Tx

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Tx Init Enable" + @property + def rdl_desc(self) -> str: + return "0 -\u003e Normal Tx operation\n\n1 -\u003e Initialize Tx" + + + + + + + +class msk_top_regs_msk_init_txrxinit_cls(FieldAsyncReadWrite): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Tx/Rx Init Enable | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

0 -> Normal modem operation

1 -> Initialize Tx | + | | and Rx

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Tx/Rx Init Enable" + @property + def rdl_desc(self) -> str: + return "0 -\u003e Normal modem operation \n\n1 -\u003e Initialize Tx and Rx" + + + + + + +class msk_top_regs_msk_init_cls(RegAsyncReadWrite): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | MSK Modem Initialization Control | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Synchronous initialization of MSK Modem functions, does not | + | | affect configuration registers.

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__txrxinit', '__txinit', '__rxinit'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,MemoryAsyncReadWrite]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__txrxinit:msk_top_regs_msk_init_txrxinit_cls = msk_top_regs_msk_init_txrxinit_cls( + parent_register=self, + size_props=FieldSizeProps( + width=1, + lsb=0, + msb=0, + low=0, + high=0), + misc_props=FieldMiscProps( + default=1, + is_volatile=False), + logger_handle=logger_handle+'.txrxinit', + inst_name='txrxinit', + field_type=int) + self.__txinit:msk_top_regs_msk_init_txinit_cls = msk_top_regs_msk_init_txinit_cls( + parent_register=self, + size_props=FieldSizeProps( + width=1, + lsb=1, + msb=1, + low=1, + high=1), + misc_props=FieldMiscProps( + default=1, + is_volatile=False), + logger_handle=logger_handle+'.txinit', + inst_name='txinit', + field_type=int) + self.__rxinit:msk_top_regs_msk_init_rxinit_cls = msk_top_regs_msk_init_rxinit_cls( + parent_register=self, + size_props=FieldSizeProps( + width=1, + lsb=2, + msb=2, + low=2, + high=2), + misc_props=FieldMiscProps( + default=1, + is_volatile=False), + logger_handle=logger_handle+'.rxinit', + inst_name='rxinit', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.txrxinit + yield self.txinit + yield self.rxinit + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def txrxinit(self) -> msk_top_regs_msk_init_txrxinit_cls: + """ + Property to access txrxinit field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Tx/Rx Init Enable | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

0 -> Normal modem operation

1 -> Initialize Tx | + | | and Rx

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__txrxinit + @property + def txinit(self) -> msk_top_regs_msk_init_txinit_cls: + """ + Property to access txinit field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Tx Init Enable | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

0 -> Normal Tx operation

1 -> Initialize Tx

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__txinit + @property + def rxinit(self) -> msk_top_regs_msk_init_rxinit_cls: + """ + Property to access rxinit field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Rx Init Enable | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

0 -> Normal Rx operation

1 -> Initialize Rx

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__rxinit + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'txrxinit':'txrxinit','txinit':'txinit','rxinit':'rxinit', + } + + + + + + + + # nodes:3 + + @overload + def get_child_by_system_rdl_name(self, name: Literal["txrxinit"]) -> msk_top_regs_msk_init_txrxinit_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["txinit"]) -> msk_top_regs_msk_init_txinit_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["rxinit"]) -> msk_top_regs_msk_init_rxinit_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: str) -> Union[msk_top_regs_msk_init_txrxinit_cls, msk_top_regs_msk_init_txinit_cls, msk_top_regs_msk_init_rxinit_cls, ]: ... + + def get_child_by_system_rdl_name(self, name: Any) -> Any: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + @property + def rdl_name(self) -> str: + return "MSK Modem Initialization Control" + @property + def rdl_desc(self) -> str: + return "Synchronous initialization of MSK Modem functions, does not affect configuration registers." + + + + + + + +class msk_top_regs_msk_hash_hi_hash_id_hi_cls(FieldAsyncReadOnly): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Hash ID Upper 32-bits | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Upper 32-bits of Pluto MSK FPGA Hash ID

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Hash ID Upper 32-bits" + @property + def rdl_desc(self) -> str: + return "Upper 32-bits of Pluto MSK FPGA Hash ID" + + + + + + +class msk_top_regs_msk_hash_hi_cls(RegAsyncReadOnly): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Pluto MSK FPGA Hash ID - Upper 32-bits | + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__hash_id_hi'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,ReadableAsyncMemory]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__hash_id_hi:msk_top_regs_msk_hash_hi_hash_id_hi_cls = msk_top_regs_msk_hash_hi_hash_id_hi_cls( + parent_register=self, + size_props=FieldSizeProps( + width=32, + lsb=0, + msb=31, + low=0, + high=31), + misc_props=FieldMiscProps( + default=1431677610, + is_volatile=False), + logger_handle=logger_handle+'.hash_id_hi', + inst_name='hash_id_hi', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.hash_id_hi + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def hash_id_hi(self) -> msk_top_regs_msk_hash_hi_hash_id_hi_cls: + """ + Property to access hash_id_hi field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Hash ID Upper 32-bits | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Upper 32-bits of Pluto MSK FPGA Hash ID

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__hash_id_hi + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'hash_id_hi':'hash_id_hi', + } + + + + + + + + + def get_child_by_system_rdl_name(self, name: Any) -> msk_top_regs_msk_hash_hi_hash_id_hi_cls: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + + @property + def rdl_name(self) -> str: + return "Pluto MSK FPGA Hash ID - Upper 32-bits" + + + + + + + +class msk_top_regs_msk_hash_lo_hash_id_lo_cls(FieldAsyncReadOnly): + + """ + Class to represent a register field in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Hash ID Lower 32-bits | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Lower 32-bits of Pluto MSK FPGA Hash ID

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = [] + + + + + + + @property + def rdl_name(self) -> str: + return "Hash ID Lower 32-bits" + @property + def rdl_desc(self) -> str: + return "Lower 32-bits of Pluto MSK FPGA Hash ID" + + + + + + +class msk_top_regs_msk_hash_lo_cls(RegAsyncReadOnly): + """ + Class to represent a register in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Pluto MSK FPGA Hash ID - Lower 32-bits | + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__hash_id_lo'] + + def __init__(self, + address: int, + width: int, + accesswidth: int, + logger_handle: str, + inst_name: str, + parent: Union[AsyncAddressMap,AsyncRegFile,ReadableAsyncMemory]): + + super().__init__(address=address, + width=width, + accesswidth=accesswidth, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + # build the field attributes + + self.__hash_id_lo:msk_top_regs_msk_hash_lo_hash_id_lo_cls = msk_top_regs_msk_hash_lo_hash_id_lo_cls( + parent_register=self, + size_props=FieldSizeProps( + width=32, + lsb=0, + msb=31, + low=0, + high=31), + misc_props=FieldMiscProps( + default=2863289685, + is_volatile=False), + logger_handle=logger_handle+'.hash_id_lo', + inst_name='hash_id_lo', + field_type=int) + + @property + def fields(self) -> Iterator[Union[FieldAsyncReadOnly, FieldAsyncWriteOnly,FieldAsyncReadWrite]]: + """ + generator that produces has all the fields within the register + """ + yield self.hash_id_lo + + # Empty generator in case there are no children of this type + if False: yield + + + + + # build the properties for the fields + + @property + def hash_id_lo(self) -> msk_top_regs_msk_hash_lo_hash_id_lo_cls: + """ + Property to access hash_id_lo field of the register + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Hash ID Lower 32-bits | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Lower 32-bits of Pluto MSK FPGA Hash ID

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__hash_id_lo + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'hash_id_lo':'hash_id_lo', + } + + + + + + + + + def get_child_by_system_rdl_name(self, name: Any) -> msk_top_regs_msk_hash_lo_hash_id_lo_cls: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + + @property + def rdl_name(self) -> str: + return "Pluto MSK FPGA Hash ID - Lower 32-bits" + + + + + + +class msk_top_regs_cls(AsyncAddressMap): + """ + Class to represent a address map in the register model + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Pluto MSK Registers | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

MSK Modem Configuration and Status Registers

| + +--------------+-------------------------------------------------------------------------+ + """ + + __slots__ : list[str] = ['__Hash_ID_Low', '__Hash_ID_High', '__MSK_Init', '__MSK_Control', '__MSK_Status', '__Tx_Bit_Count', '__Tx_Enable_Count', '__Fb_FreqWord', '__TX_F1_FreqWord', '__TX_F2_FreqWord', '__RX_F1_FreqWord', '__RX_F2_FreqWord', '__LPF_Config_0', '__LPF_Config_1', '__Tx_Data_Width', '__Rx_Data_Width', '__PRBS_Control', '__PRBS_Initial_State', '__PRBS_Polynomial', '__PRBS_Error_Mask', '__PRBS_Bit_Count', '__PRBS_Error_Count', '__LPF_Accum_F1', '__LPF_Accum_F2', '__axis_xfer_count', '__Rx_Sample_Discard', '__LPF_Config_2', '__f1_nco_adjust', '__f2_nco_adjust', '__f1_error', '__f2_error', '__Tx_Sync_Ctrl', '__Tx_Sync_Cnt', '__lowpass_ema_alpha1', '__lowpass_ema_alpha2', '__rx_power', '__tx_async_fifo_rd_wr_ptr', '__rx_async_fifo_rd_wr_ptr', '__rx_frame_sync_status'] + + def __init__(self, *, + address:int=0, + logger_handle:str='reg_model.msk_top_regs', + inst_name:str='msk_top_regs', + callbacks: Optional[Union[AsyncCallbackSet, AsyncCallbackSetLegacy]]=None, + parent:Optional[AsyncAddressMap]=None): + + if callbacks is not None: + if not isinstance(callbacks, (AsyncCallbackSet, AsyncCallbackSetLegacy)): + raise TypeError(f'callbacks should be AsyncCallbackSet, AsyncCallbackSetLegacy got {type(callbacks)}') + + super().__init__(callbacks=callbacks, + address=address, + logger_handle=logger_handle, + inst_name=inst_name, + parent=parent) + + + + self.__Hash_ID_Low:msk_top_regs_msk_hash_lo_cls = msk_top_regs_msk_hash_lo_cls( + address=self.address+0, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.Hash_ID_Low', + inst_name='Hash_ID_Low', parent=self) + + + self.__Hash_ID_High:msk_top_regs_msk_hash_hi_cls = msk_top_regs_msk_hash_hi_cls( + address=self.address+4, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.Hash_ID_High', + inst_name='Hash_ID_High', parent=self) + + + self.__MSK_Init:msk_top_regs_msk_init_cls = msk_top_regs_msk_init_cls( + address=self.address+8, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.MSK_Init', + inst_name='MSK_Init', parent=self) + + + self.__MSK_Control:msk_top_regs_msk_ctrl_cls = msk_top_regs_msk_ctrl_cls( + address=self.address+12, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.MSK_Control', + inst_name='MSK_Control', parent=self) + + + self.__MSK_Status:msk_top_regs_msk_stat_0_cls = msk_top_regs_msk_stat_0_cls( + address=self.address+16, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.MSK_Status', + inst_name='MSK_Status', parent=self) + + + self.__Tx_Bit_Count:msk_top_regs_msk_stat_1_cls = msk_top_regs_msk_stat_1_cls( + address=self.address+20, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.Tx_Bit_Count', + inst_name='Tx_Bit_Count', parent=self) + + + self.__Tx_Enable_Count:msk_top_regs_msk_stat_2_cls = msk_top_regs_msk_stat_2_cls( + address=self.address+24, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.Tx_Enable_Count', + inst_name='Tx_Enable_Count', parent=self) + + + self.__Fb_FreqWord:msk_top_regs_config_nco_fw_desc_c4924cc6_name_0c494469_cls = msk_top_regs_config_nco_fw_desc_c4924cc6_name_0c494469_cls( + address=self.address+28, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.Fb_FreqWord', + inst_name='Fb_FreqWord', parent=self) + + + self.__TX_F1_FreqWord:msk_top_regs_config_nco_fw_desc_94d7aaf5_name_84dd0c1c_cls = msk_top_regs_config_nco_fw_desc_94d7aaf5_name_84dd0c1c_cls( + address=self.address+32, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.TX_F1_FreqWord', + inst_name='TX_F1_FreqWord', parent=self) + + + self.__TX_F2_FreqWord:msk_top_regs_config_nco_fw_desc_42134a4f_name_d97dbd51_cls = msk_top_regs_config_nco_fw_desc_42134a4f_name_d97dbd51_cls( + address=self.address+36, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.TX_F2_FreqWord', + inst_name='TX_F2_FreqWord', parent=self) + + + self.__RX_F1_FreqWord:msk_top_regs_config_nco_fw_desc_16fb48c8_name_8d01a20d_cls = msk_top_regs_config_nco_fw_desc_16fb48c8_name_8d01a20d_cls( + address=self.address+40, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.RX_F1_FreqWord', + inst_name='RX_F1_FreqWord', parent=self) + + + self.__RX_F2_FreqWord:msk_top_regs_config_nco_fw_desc_43c0828f_name_bdc60ecf_cls = msk_top_regs_config_nco_fw_desc_43c0828f_name_bdc60ecf_cls( + address=self.address+44, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.RX_F2_FreqWord', + inst_name='RX_F2_FreqWord', parent=self) + + + self.__LPF_Config_0:msk_top_regs_lpf_config_0_cls = msk_top_regs_lpf_config_0_cls( + address=self.address+48, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.LPF_Config_0', + inst_name='LPF_Config_0', parent=self) + + + self.__LPF_Config_1:msk_top_regs_lpf_config_1_cls = msk_top_regs_lpf_config_1_cls( + address=self.address+52, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.LPF_Config_1', + inst_name='LPF_Config_1', parent=self) + + + self.__Tx_Data_Width:msk_top_regs_data_width_desc_58c848dd_name_2fbd8eba_cls = msk_top_regs_data_width_desc_58c848dd_name_2fbd8eba_cls( + address=self.address+56, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.Tx_Data_Width', + inst_name='Tx_Data_Width', parent=self) + + + self.__Rx_Data_Width:msk_top_regs_data_width_desc_6097df38_name_4609588b_cls = msk_top_regs_data_width_desc_6097df38_name_4609588b_cls( + address=self.address+60, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.Rx_Data_Width', + inst_name='Rx_Data_Width', parent=self) + + + self.__PRBS_Control:msk_top_regs_prbs_ctrl_cls = msk_top_regs_prbs_ctrl_cls( + address=self.address+64, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.PRBS_Control', + inst_name='PRBS_Control', parent=self) + + + self.__PRBS_Initial_State:msk_top_regs_config_prbs_seed_cls = msk_top_regs_config_prbs_seed_cls( + address=self.address+68, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.PRBS_Initial_State', + inst_name='PRBS_Initial_State', parent=self) + + + self.__PRBS_Polynomial:msk_top_regs_config_prbs_poly_cls = msk_top_regs_config_prbs_poly_cls( + address=self.address+72, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.PRBS_Polynomial', + inst_name='PRBS_Polynomial', parent=self) + + + self.__PRBS_Error_Mask:msk_top_regs_config_prbs_errmask_cls = msk_top_regs_config_prbs_errmask_cls( + address=self.address+76, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.PRBS_Error_Mask', + inst_name='PRBS_Error_Mask', parent=self) + + + self.__PRBS_Bit_Count:msk_top_regs_stat_32_bits_cls = msk_top_regs_stat_32_bits_cls( + address=self.address+80, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.PRBS_Bit_Count', + inst_name='PRBS_Bit_Count', parent=self) + + + self.__PRBS_Error_Count:msk_top_regs_stat_32_errs_cls = msk_top_regs_stat_32_errs_cls( + address=self.address+84, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.PRBS_Error_Count', + inst_name='PRBS_Error_Count', parent=self) + + + self.__LPF_Accum_F1:msk_top_regs_stat_32_lpf_acc_desc_8cebc7dc_name_f20c6670_cls = msk_top_regs_stat_32_lpf_acc_desc_8cebc7dc_name_f20c6670_cls( + address=self.address+88, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.LPF_Accum_F1', + inst_name='LPF_Accum_F1', parent=self) + + + self.__LPF_Accum_F2:msk_top_regs_stat_32_lpf_acc_desc_dea6bd99_name_758fd0ce_cls = msk_top_regs_stat_32_lpf_acc_desc_dea6bd99_name_758fd0ce_cls( + address=self.address+92, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.LPF_Accum_F2', + inst_name='LPF_Accum_F2', parent=self) + + + self.__axis_xfer_count:msk_top_regs_msk_stat_3_cls = msk_top_regs_msk_stat_3_cls( + address=self.address+96, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.axis_xfer_count', + inst_name='axis_xfer_count', parent=self) + + + self.__Rx_Sample_Discard:msk_top_regs_rx_sample_discard_cls = msk_top_regs_rx_sample_discard_cls( + address=self.address+100, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.Rx_Sample_Discard', + inst_name='Rx_Sample_Discard', parent=self) + + + self.__LPF_Config_2:msk_top_regs_lpf_config_2_cls = msk_top_regs_lpf_config_2_cls( + address=self.address+104, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.LPF_Config_2', + inst_name='LPF_Config_2', parent=self) + + + self.__f1_nco_adjust:msk_top_regs_status_reg_data_f53978c8_name_d8ad3b25_cls = msk_top_regs_status_reg_data_f53978c8_name_d8ad3b25_cls( + address=self.address+108, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.f1_nco_adjust', + inst_name='f1_nco_adjust', parent=self) + + + self.__f2_nco_adjust:msk_top_regs_status_reg_data_05243a4e_name_2c154788_cls = msk_top_regs_status_reg_data_05243a4e_name_2c154788_cls( + address=self.address+112, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.f2_nco_adjust', + inst_name='f2_nco_adjust', parent=self) + + + self.__f1_error:msk_top_regs_status_reg_data_10a2e5b5_name_3b640507_cls = msk_top_regs_status_reg_data_10a2e5b5_name_3b640507_cls( + address=self.address+116, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.f1_error', + inst_name='f1_error', parent=self) + + + self.__f2_error:msk_top_regs_status_reg_data_642692cf_name_3de9a0d3_cls = msk_top_regs_status_reg_data_642692cf_name_3de9a0d3_cls( + address=self.address+120, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.f2_error', + inst_name='f2_error', parent=self) + + + self.__Tx_Sync_Ctrl:msk_top_regs_tx_sync_ctrl_cls = msk_top_regs_tx_sync_ctrl_cls( + address=self.address+124, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.Tx_Sync_Ctrl', + inst_name='Tx_Sync_Ctrl', parent=self) + + + self.__Tx_Sync_Cnt:msk_top_regs_tx_sync_cnt_cls = msk_top_regs_tx_sync_cnt_cls( + address=self.address+128, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.Tx_Sync_Cnt', + inst_name='Tx_Sync_Cnt', parent=self) + + + self.__lowpass_ema_alpha1:msk_top_regs_lowpass_ema_alpha_0x0x1101991f_cls = msk_top_regs_lowpass_ema_alpha_0x0x1101991f_cls( + address=self.address+132, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.lowpass_ema_alpha1', + inst_name='lowpass_ema_alpha1', parent=self) + + + self.__lowpass_ema_alpha2:msk_top_regs_lowpass_ema_alpha_cls = msk_top_regs_lowpass_ema_alpha_cls( + address=self.address+136, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.lowpass_ema_alpha2', + inst_name='lowpass_ema_alpha2', parent=self) + + + self.__rx_power:msk_top_regs_rx_power_cls = msk_top_regs_rx_power_cls( + address=self.address+140, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.rx_power', + inst_name='rx_power', parent=self) + + + self.__tx_async_fifo_rd_wr_ptr:msk_top_regs_status_reg_data_8a67e1fe_desc_aa4ec676_name_aa4ec676_cls = msk_top_regs_status_reg_data_8a67e1fe_desc_aa4ec676_name_aa4ec676_cls( + address=self.address+144, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.tx_async_fifo_rd_wr_ptr', + inst_name='tx_async_fifo_rd_wr_ptr', parent=self) + + + self.__rx_async_fifo_rd_wr_ptr:msk_top_regs_status_reg_data_8a67e1fe_desc_8a90eed1_name_8a90eed1_cls = msk_top_regs_status_reg_data_8a67e1fe_desc_8a90eed1_name_8a90eed1_cls( + address=self.address+148, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.rx_async_fifo_rd_wr_ptr', + inst_name='rx_async_fifo_rd_wr_ptr', parent=self) + + + self.__rx_frame_sync_status:msk_top_regs_frame_sync_status_cls = msk_top_regs_frame_sync_status_cls( + address=self.address+152, + accesswidth=32, + width=32, + logger_handle=logger_handle+'.rx_frame_sync_status', + inst_name='rx_frame_sync_status', parent=self) + + + @property + def size(self) -> int: + return 156 + @property + def Hash_ID_Low(self) -> msk_top_regs_msk_hash_lo_cls: + """ + Property to access Hash_ID_Low + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Pluto MSK FPGA Hash ID - Lower 32-bits | + +--------------+-------------------------------------------------------------------------+ + """ + return self.__Hash_ID_Low + + @property + def Hash_ID_High(self) -> msk_top_regs_msk_hash_hi_cls: + """ + Property to access Hash_ID_High + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Pluto MSK FPGA Hash ID - Upper 32-bits | + +--------------+-------------------------------------------------------------------------+ + """ + return self.__Hash_ID_High + + @property + def MSK_Init(self) -> msk_top_regs_msk_init_cls: + """ + Property to access MSK_Init + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | MSK Modem Initialization Control | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Synchronous initialization of MSK Modem functions, does not | + | | affect configuration registers.

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__MSK_Init + + @property + def MSK_Control(self) -> msk_top_regs_msk_ctrl_cls: + """ + Property to access MSK_Control + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | MSK Modem Control | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

MSK Modem Configuration and Control

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__MSK_Control + + @property + def MSK_Status(self) -> msk_top_regs_msk_stat_0_cls: + """ + Property to access MSK_Status + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | MSK Modem Status 0 | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Modem status bits

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__MSK_Status + + @property + def Tx_Bit_Count(self) -> msk_top_regs_msk_stat_1_cls: + """ + Property to access Tx_Bit_Count + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | MSK Modem Status 1 | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Modem status data

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__Tx_Bit_Count + + @property + def Tx_Enable_Count(self) -> msk_top_regs_msk_stat_2_cls: + """ + Property to access Tx_Enable_Count + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | MSK Modem Status 2 | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Modem status data

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__Tx_Enable_Count + + @property + def Fb_FreqWord(self) -> msk_top_regs_config_nco_fw_desc_c4924cc6_name_0c494469_cls: + """ + Property to access Fb_FreqWord + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Bitrate NCO Frequency Control Word | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Set Modem Data Rate

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__Fb_FreqWord + + @property + def TX_F1_FreqWord(self) -> msk_top_regs_config_nco_fw_desc_94d7aaf5_name_84dd0c1c_cls: + """ + Property to access TX_F1_FreqWord + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Tx F1 NCO Frequency Control Word | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Set Modulator F1 Frequency

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__TX_F1_FreqWord + + @property + def TX_F2_FreqWord(self) -> msk_top_regs_config_nco_fw_desc_42134a4f_name_d97dbd51_cls: + """ + Property to access TX_F2_FreqWord + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Tx F2 NCO Frequency Control Word | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Set Modulator F2 Frequency

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__TX_F2_FreqWord + + @property + def RX_F1_FreqWord(self) -> msk_top_regs_config_nco_fw_desc_16fb48c8_name_8d01a20d_cls: + """ + Property to access RX_F1_FreqWord + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Rx F1 NCO Frequency Control Word | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Set Demodulator F1 Frequency

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__RX_F1_FreqWord + + @property + def RX_F2_FreqWord(self) -> msk_top_regs_config_nco_fw_desc_43c0828f_name_bdc60ecf_cls: + """ + Property to access RX_F2_FreqWord + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Rx F2 NCO Frequency Control Word | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Set Demodulator F2 Frequency

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__RX_F2_FreqWord + + @property + def LPF_Config_0(self) -> msk_top_regs_lpf_config_0_cls: + """ + Property to access LPF_Config_0 + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PI Controller Configuration and Low-pass Filter Configuration | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Configure PI controller and low-pass filter

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__LPF_Config_0 + + @property + def LPF_Config_1(self) -> msk_top_regs_lpf_config_1_cls: + """ + Property to access LPF_Config_1 + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PI Controller Configuration Configuration Register 1 | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Configures PI Controller I-gain and divisor

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__LPF_Config_1 + + @property + def Tx_Data_Width(self) -> msk_top_regs_data_width_desc_58c848dd_name_2fbd8eba_cls: + """ + Property to access Tx_Data_Width + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Modem Tx Input Data Width | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Set the parallel data width of the parallel-to-serial | + | | converter

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__Tx_Data_Width + + @property + def Rx_Data_Width(self) -> msk_top_regs_data_width_desc_6097df38_name_4609588b_cls: + """ + Property to access Rx_Data_Width + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Modem Rx Output Data Width | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Set the parallel data width of the serial-to-parallel | + | | converter

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__Rx_Data_Width + + @property + def PRBS_Control(self) -> msk_top_regs_prbs_ctrl_cls: + """ + Property to access PRBS_Control + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PRBS Control 0 | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Configures operation of the PRBS Generator and Monitor

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__PRBS_Control + + @property + def PRBS_Initial_State(self) -> msk_top_regs_config_prbs_seed_cls: + """ + Property to access PRBS_Initial_State + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PRBS Control 1 | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

PRBS Initial State

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__PRBS_Initial_State + + @property + def PRBS_Polynomial(self) -> msk_top_regs_config_prbs_poly_cls: + """ + Property to access PRBS_Polynomial + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PRBS Control 2 | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

PRBS Polynomial

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__PRBS_Polynomial + + @property + def PRBS_Error_Mask(self) -> msk_top_regs_config_prbs_errmask_cls: + """ + Property to access PRBS_Error_Mask + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PRBS Control 3 | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

PRBS Error Mask

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__PRBS_Error_Mask + + @property + def PRBS_Bit_Count(self) -> msk_top_regs_stat_32_bits_cls: + """ + Property to access PRBS_Bit_Count + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PRBS Status 0 | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

PRBS Bits Received

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__PRBS_Bit_Count + + @property + def PRBS_Error_Count(self) -> msk_top_regs_stat_32_errs_cls: + """ + Property to access PRBS_Error_Count + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PRBS Status 1 | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

PRBS Bit Errors

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__PRBS_Error_Count + + @property + def LPF_Accum_F1(self) -> msk_top_regs_stat_32_lpf_acc_desc_8cebc7dc_name_f20c6670_cls: + """ + Property to access LPF_Accum_F1 + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | F1 PI Controller Accumulator | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Value of the F1 PI Controller Accumulator

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__LPF_Accum_F1 + + @property + def LPF_Accum_F2(self) -> msk_top_regs_stat_32_lpf_acc_desc_dea6bd99_name_758fd0ce_cls: + """ + Property to access LPF_Accum_F2 + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | F2 PI Controller Accumulator | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Value of the F2 PI Controller Accumulator

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__LPF_Accum_F2 + + @property + def axis_xfer_count(self) -> msk_top_regs_msk_stat_3_cls: + """ + Property to access axis_xfer_count + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | MSK Modem Status 3 | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Modem status data

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__axis_xfer_count + + @property + def Rx_Sample_Discard(self) -> msk_top_regs_rx_sample_discard_cls: + """ + Property to access Rx_Sample_Discard + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Rx Sample Discard | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Configure samples discard operation for demodulator

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__Rx_Sample_Discard + + @property + def LPF_Config_2(self) -> msk_top_regs_lpf_config_2_cls: + """ + Property to access LPF_Config_2 + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | PI Controller Configuration Configuration Register 2 | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Configures PI Controller I-gain and divisor

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__LPF_Config_2 + + @property + def f1_nco_adjust(self) -> msk_top_regs_status_reg_data_f53978c8_name_d8ad3b25_cls: + """ + Property to access f1_nco_adjust + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | F1 NCO Frequency Adjust | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Status Register

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__f1_nco_adjust + + @property + def f2_nco_adjust(self) -> msk_top_regs_status_reg_data_05243a4e_name_2c154788_cls: + """ + Property to access f2_nco_adjust + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | F2 NCO Frequency Adjust | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Status Register

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__f2_nco_adjust + + @property + def f1_error(self) -> msk_top_regs_status_reg_data_10a2e5b5_name_3b640507_cls: + """ + Property to access f1_error + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | F1 Error Value | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Status Register

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__f1_error + + @property + def f2_error(self) -> msk_top_regs_status_reg_data_642692cf_name_3de9a0d3_cls: + """ + Property to access f2_error + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | F2 Error Value | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Status Register

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__f2_error + + @property + def Tx_Sync_Ctrl(self) -> msk_top_regs_tx_sync_ctrl_cls: + """ + Property to access Tx_Sync_Ctrl + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Transmitter Sync Control | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Provides control bits for generation of transmitter | + | | synchronization patterns

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__Tx_Sync_Ctrl + + @property + def Tx_Sync_Cnt(self) -> msk_top_regs_tx_sync_cnt_cls: + """ + Property to access Tx_Sync_Cnt + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Transmitter Sync Duration | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Sets the duration of the synchronization tones when enabled

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__Tx_Sync_Cnt + + @property + def lowpass_ema_alpha1(self) -> msk_top_regs_lowpass_ema_alpha_0x0x1101991f_cls: + """ + Property to access lowpass_ema_alpha1 + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Exponential Moving Average Alpha | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Sets the alpha for the EMA

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__lowpass_ema_alpha1 + + @property + def lowpass_ema_alpha2(self) -> msk_top_regs_lowpass_ema_alpha_cls: + """ + Property to access lowpass_ema_alpha2 + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Exponential Moving Average Alpha | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Sets the alpha for the EMA

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__lowpass_ema_alpha2 + + @property + def rx_power(self) -> msk_top_regs_rx_power_cls: + """ + Property to access rx_power + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Receive Power | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Receive power computed from I/Q samples

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__rx_power + + @property + def tx_async_fifo_rd_wr_ptr(self) -> msk_top_regs_status_reg_data_8a67e1fe_desc_aa4ec676_name_aa4ec676_cls: + """ + Property to access tx_async_fifo_rd_wr_ptr + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Tx async FIFO read and write pointers | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Tx async FIFO read and write pointers

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__tx_async_fifo_rd_wr_ptr + + @property + def rx_async_fifo_rd_wr_ptr(self) -> msk_top_regs_status_reg_data_8a67e1fe_desc_8a90eed1_name_8a90eed1_cls: + """ + Property to access rx_async_fifo_rd_wr_ptr + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Rx async FIFO read and write pointers | + +--------------+-------------------------------------------------------------------------+ + | Description | .. raw:: html | + | | | + | |

Rx async FIFO read and write pointers

| + +--------------+-------------------------------------------------------------------------+ + """ + return self.__rx_async_fifo_rd_wr_ptr + + @property + def rx_frame_sync_status(self) -> msk_top_regs_frame_sync_status_cls: + """ + Property to access rx_frame_sync_status + + +--------------+-------------------------------------------------------------------------+ + | SystemRDL | Value | + | Field | | + +==============+=========================================================================+ + | Name | .. raw:: html | + | | | + | | Frame Sync Status | + +--------------+-------------------------------------------------------------------------+ + """ + return self.__rx_frame_sync_status + + + + @property + def systemrdl_python_child_name_map(self) -> dict[str, str]: + """ + In some cases systemRDL names need to be converted make them python safe, this dictionary + is used to map the original systemRDL names to the names of the python attributes of this + class + + Returns: dictionary whose key is the systemRDL names and value it the property name + """ + return {'Hash_ID_Low':'Hash_ID_Low','Hash_ID_High':'Hash_ID_High','MSK_Init':'MSK_Init','MSK_Control':'MSK_Control','MSK_Status':'MSK_Status','Tx_Bit_Count':'Tx_Bit_Count','Tx_Enable_Count':'Tx_Enable_Count','Fb_FreqWord':'Fb_FreqWord','TX_F1_FreqWord':'TX_F1_FreqWord','TX_F2_FreqWord':'TX_F2_FreqWord','RX_F1_FreqWord':'RX_F1_FreqWord','RX_F2_FreqWord':'RX_F2_FreqWord','LPF_Config_0':'LPF_Config_0','LPF_Config_1':'LPF_Config_1','Tx_Data_Width':'Tx_Data_Width','Rx_Data_Width':'Rx_Data_Width','PRBS_Control':'PRBS_Control','PRBS_Initial_State':'PRBS_Initial_State','PRBS_Polynomial':'PRBS_Polynomial','PRBS_Error_Mask':'PRBS_Error_Mask','PRBS_Bit_Count':'PRBS_Bit_Count','PRBS_Error_Count':'PRBS_Error_Count','LPF_Accum_F1':'LPF_Accum_F1','LPF_Accum_F2':'LPF_Accum_F2','axis_xfer_count':'axis_xfer_count','Rx_Sample_Discard':'Rx_Sample_Discard','LPF_Config_2':'LPF_Config_2','f1_nco_adjust':'f1_nco_adjust','f2_nco_adjust':'f2_nco_adjust','f1_error':'f1_error','f2_error':'f2_error','Tx_Sync_Ctrl':'Tx_Sync_Ctrl','Tx_Sync_Cnt':'Tx_Sync_Cnt','lowpass_ema_alpha1':'lowpass_ema_alpha1','lowpass_ema_alpha2':'lowpass_ema_alpha2','rx_power':'rx_power','tx_async_fifo_rd_wr_ptr':'tx_async_fifo_rd_wr_ptr','rx_async_fifo_rd_wr_ptr':'rx_async_fifo_rd_wr_ptr','rx_frame_sync_status':'rx_frame_sync_status', + } + + + + + + + + # nodes:39 + + @overload + def get_child_by_system_rdl_name(self, name: Literal["Hash_ID_Low"]) -> msk_top_regs_msk_hash_lo_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["Hash_ID_High"]) -> msk_top_regs_msk_hash_hi_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["MSK_Init"]) -> msk_top_regs_msk_init_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["MSK_Control"]) -> msk_top_regs_msk_ctrl_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["MSK_Status"]) -> msk_top_regs_msk_stat_0_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["Tx_Bit_Count"]) -> msk_top_regs_msk_stat_1_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["Tx_Enable_Count"]) -> msk_top_regs_msk_stat_2_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["Fb_FreqWord"]) -> msk_top_regs_config_nco_fw_desc_c4924cc6_name_0c494469_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["TX_F1_FreqWord"]) -> msk_top_regs_config_nco_fw_desc_94d7aaf5_name_84dd0c1c_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["TX_F2_FreqWord"]) -> msk_top_regs_config_nco_fw_desc_42134a4f_name_d97dbd51_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["RX_F1_FreqWord"]) -> msk_top_regs_config_nco_fw_desc_16fb48c8_name_8d01a20d_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["RX_F2_FreqWord"]) -> msk_top_regs_config_nco_fw_desc_43c0828f_name_bdc60ecf_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["LPF_Config_0"]) -> msk_top_regs_lpf_config_0_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["LPF_Config_1"]) -> msk_top_regs_lpf_config_1_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["Tx_Data_Width"]) -> msk_top_regs_data_width_desc_58c848dd_name_2fbd8eba_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["Rx_Data_Width"]) -> msk_top_regs_data_width_desc_6097df38_name_4609588b_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["PRBS_Control"]) -> msk_top_regs_prbs_ctrl_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["PRBS_Initial_State"]) -> msk_top_regs_config_prbs_seed_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["PRBS_Polynomial"]) -> msk_top_regs_config_prbs_poly_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["PRBS_Error_Mask"]) -> msk_top_regs_config_prbs_errmask_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["PRBS_Bit_Count"]) -> msk_top_regs_stat_32_bits_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["PRBS_Error_Count"]) -> msk_top_regs_stat_32_errs_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["LPF_Accum_F1"]) -> msk_top_regs_stat_32_lpf_acc_desc_8cebc7dc_name_f20c6670_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["LPF_Accum_F2"]) -> msk_top_regs_stat_32_lpf_acc_desc_dea6bd99_name_758fd0ce_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["axis_xfer_count"]) -> msk_top_regs_msk_stat_3_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["Rx_Sample_Discard"]) -> msk_top_regs_rx_sample_discard_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["LPF_Config_2"]) -> msk_top_regs_lpf_config_2_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["f1_nco_adjust"]) -> msk_top_regs_status_reg_data_f53978c8_name_d8ad3b25_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["f2_nco_adjust"]) -> msk_top_regs_status_reg_data_05243a4e_name_2c154788_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["f1_error"]) -> msk_top_regs_status_reg_data_10a2e5b5_name_3b640507_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["f2_error"]) -> msk_top_regs_status_reg_data_642692cf_name_3de9a0d3_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["Tx_Sync_Ctrl"]) -> msk_top_regs_tx_sync_ctrl_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["Tx_Sync_Cnt"]) -> msk_top_regs_tx_sync_cnt_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["lowpass_ema_alpha1"]) -> msk_top_regs_lowpass_ema_alpha_0x0x1101991f_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["lowpass_ema_alpha2"]) -> msk_top_regs_lowpass_ema_alpha_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["rx_power"]) -> msk_top_regs_rx_power_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["tx_async_fifo_rd_wr_ptr"]) -> msk_top_regs_status_reg_data_8a67e1fe_desc_aa4ec676_name_aa4ec676_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["rx_async_fifo_rd_wr_ptr"]) -> msk_top_regs_status_reg_data_8a67e1fe_desc_8a90eed1_name_8a90eed1_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: Literal["rx_frame_sync_status"]) -> msk_top_regs_frame_sync_status_cls: ... + + + @overload + def get_child_by_system_rdl_name(self, name: str) -> Union[msk_top_regs_msk_hash_lo_cls, msk_top_regs_msk_hash_hi_cls, msk_top_regs_msk_init_cls, msk_top_regs_msk_ctrl_cls, msk_top_regs_msk_stat_0_cls, msk_top_regs_msk_stat_1_cls, msk_top_regs_msk_stat_2_cls, msk_top_regs_config_nco_fw_desc_c4924cc6_name_0c494469_cls, msk_top_regs_config_nco_fw_desc_94d7aaf5_name_84dd0c1c_cls, msk_top_regs_config_nco_fw_desc_42134a4f_name_d97dbd51_cls, msk_top_regs_config_nco_fw_desc_16fb48c8_name_8d01a20d_cls, msk_top_regs_config_nco_fw_desc_43c0828f_name_bdc60ecf_cls, msk_top_regs_lpf_config_0_cls, msk_top_regs_lpf_config_1_cls, msk_top_regs_data_width_desc_58c848dd_name_2fbd8eba_cls, msk_top_regs_data_width_desc_6097df38_name_4609588b_cls, msk_top_regs_prbs_ctrl_cls, msk_top_regs_config_prbs_seed_cls, msk_top_regs_config_prbs_poly_cls, msk_top_regs_config_prbs_errmask_cls, msk_top_regs_stat_32_bits_cls, msk_top_regs_stat_32_errs_cls, msk_top_regs_stat_32_lpf_acc_desc_8cebc7dc_name_f20c6670_cls, msk_top_regs_stat_32_lpf_acc_desc_dea6bd99_name_758fd0ce_cls, msk_top_regs_msk_stat_3_cls, msk_top_regs_rx_sample_discard_cls, msk_top_regs_lpf_config_2_cls, msk_top_regs_status_reg_data_f53978c8_name_d8ad3b25_cls, msk_top_regs_status_reg_data_05243a4e_name_2c154788_cls, msk_top_regs_status_reg_data_10a2e5b5_name_3b640507_cls, msk_top_regs_status_reg_data_642692cf_name_3de9a0d3_cls, msk_top_regs_tx_sync_ctrl_cls, msk_top_regs_tx_sync_cnt_cls, msk_top_regs_lowpass_ema_alpha_0x0x1101991f_cls, msk_top_regs_lowpass_ema_alpha_cls, msk_top_regs_rx_power_cls, msk_top_regs_status_reg_data_8a67e1fe_desc_aa4ec676_name_aa4ec676_cls, msk_top_regs_status_reg_data_8a67e1fe_desc_8a90eed1_name_8a90eed1_cls, msk_top_regs_frame_sync_status_cls, ]: ... + + def get_child_by_system_rdl_name(self, name: Any) -> Any: + return super().get_child_by_system_rdl_name(name) + + + + + + + + + @property + def rdl_name(self) -> str: + return "Pluto MSK Registers" + @property + def rdl_desc(self) -> str: + return "MSK Modem Configuration and Status Registers" + + + + + def get_registers(self, unroll:bool=False) -> Iterator[Union[AsyncReg, AsyncRegArray]]: + """ + generator that produces all the registers of this node + """ + + + yield self.Hash_ID_Low + + + yield self.Hash_ID_High + + + yield self.MSK_Init + + + yield self.MSK_Control + + + yield self.MSK_Status + + + yield self.Tx_Bit_Count + + + yield self.Tx_Enable_Count + + + yield self.Fb_FreqWord + + + yield self.TX_F1_FreqWord + + + yield self.TX_F2_FreqWord + + + yield self.RX_F1_FreqWord + + + yield self.RX_F2_FreqWord + + + yield self.LPF_Config_0 + + + yield self.LPF_Config_1 + + + yield self.Tx_Data_Width + + + yield self.Rx_Data_Width + + + yield self.PRBS_Control + + + yield self.PRBS_Initial_State + + + yield self.PRBS_Polynomial + + + yield self.PRBS_Error_Mask + + + yield self.PRBS_Bit_Count + + + yield self.PRBS_Error_Count + + + yield self.LPF_Accum_F1 + + + yield self.LPF_Accum_F2 + + + yield self.axis_xfer_count + + + yield self.Rx_Sample_Discard + + + yield self.LPF_Config_2 + + + yield self.f1_nco_adjust + + + yield self.f2_nco_adjust + + + yield self.f1_error + + + yield self.f2_error + + + yield self.Tx_Sync_Ctrl + + + yield self.Tx_Sync_Cnt + + + yield self.lowpass_ema_alpha1 + + + yield self.lowpass_ema_alpha2 + + + yield self.rx_power + + + yield self.tx_async_fifo_rd_wr_ptr + + + yield self.rx_async_fifo_rd_wr_ptr + + + yield self.rx_frame_sync_status + + + # Empty generator in case there are no children of this type + if False: yield + + + def get_sections(self, unroll:bool=False) -> Iterator[Union[AsyncAddressMap, AsyncRegFile, AsyncAddressMapArray, AsyncRegFileArray]]: + """ + generator that produces all the AsyncAddressMap, AsyncRegFile, AsyncAddressMapArray, AsyncRegFileArray children of this node + """ + + + # Empty generator in case there are no children of this type + if False: yield + + def get_memories(self, unroll:bool=False) -> Iterator[Union[AsyncMemory, AsyncMemoryArray]]: + """ + generator that produces all the AsyncMemory, AsyncMemoryArray children of this node + """ + + + # Empty generator in case there are no children of this type + if False: yield + + + + + +if __name__ == '__main__': + # dummy functions to demonstrate the class + async def read_addr_space(addr: int, width: int, accesswidth: int) -> int: + """ + Callback to simulate the operation of the package, everytime the read is called, it will + request the user input the value to be read back. + + Args: + addr: Address to write to + width: Width of the register in bits + accesswidth: Minimum access width of the register in bits + + Returns: + value inputted by the used + """ + assert isinstance(addr, int) + assert isinstance(width, int) + assert isinstance(accesswidth, int) + return int(input('value to read from address:0x%X'%addr)) + + async def write_addr_space(addr: int, width: int, accesswidth: int, data: int) -> None: + """ + Callback to simulate the operation of the package, everytime the read is called, it will + request the user input the value to be read back. + + Args: + addr: Address to write to + width: Width of the register in bits + accesswidth: Minimum access width of the register in bits + data: value to be written to the register + + Returns: + None + """ + assert isinstance(addr, int) + assert isinstance(width, int) + assert isinstance(accesswidth, int) + assert isinstance(data, int) + print('write data:0x%X to address:0x%X'%(data, addr)) + + # create an instance of the class + msk_top_regs = msk_top_regs_cls(callbacks = AsyncCallbackSet(read_callback=read_addr_space, + write_callback=write_addr_space)) \ No newline at end of file diff --git a/rdl/outputs/python/msk_top_regs/sim/__init__.py b/rdl/outputs/python/msk_top_regs/sim/__init__.py new file mode 100644 index 0000000..2ae2839 --- /dev/null +++ b/rdl/outputs/python/msk_top_regs/sim/__init__.py @@ -0,0 +1 @@ +pass diff --git a/rdl/outputs/python/msk_top_regs/sim/msk_top_regs.py b/rdl/outputs/python/msk_top_regs/sim/msk_top_regs.py new file mode 100644 index 0000000..5dc9718 --- /dev/null +++ b/rdl/outputs/python/msk_top_regs/sim/msk_top_regs.py @@ -0,0 +1,187 @@ + + + +""" +Python Wrapper for the msk_top_regs register model + +This code was generated from the PeakRDL-python package version 1.4.0 + +""" + +from typing import Union + +from ..sim_lib.register import Register, MemoryRegister +from ..sim_lib.memory import Memory +from ..sim_lib.simulator import MemoryEntry +from ..sim_lib.field import FieldDefinition +from ..sim_lib.simulator import AsyncSimulator as Simulator + + +class msk_top_regs_simulator_cls(Simulator): + + def _build_registers(self) -> dict[int, Union[list[Union[MemoryRegister, Register]], Union[MemoryRegister, Register]]]: + return { + 0 : + Register(width=32, full_inst_name='msk_top_regs.Hash_ID_Low', readable=True, writable=False, + fields=[FieldDefinition(high=31, low=0, msb=31, lsb=0, inst_name='hash_id_lo'), + ]), + 4 : + Register(width=32, full_inst_name='msk_top_regs.Hash_ID_High', readable=True, writable=False, + fields=[FieldDefinition(high=31, low=0, msb=31, lsb=0, inst_name='hash_id_hi'), + ]), + 8 : + Register(width=32, full_inst_name='msk_top_regs.MSK_Init', readable=True, writable=True, + fields=[FieldDefinition(high=0, low=0, msb=0, lsb=0, inst_name='txrxinit'),FieldDefinition(high=1, low=1, msb=1, lsb=1, inst_name='txinit'),FieldDefinition(high=2, low=2, msb=2, lsb=2, inst_name='rxinit'), + ]), + 12 : + Register(width=32, full_inst_name='msk_top_regs.MSK_Control', readable=True, writable=True, + fields=[FieldDefinition(high=0, low=0, msb=0, lsb=0, inst_name='ptt'),FieldDefinition(high=1, low=1, msb=1, lsb=1, inst_name='loopback_ena'),FieldDefinition(high=2, low=2, msb=2, lsb=2, inst_name='rx_invert'),FieldDefinition(high=3, low=3, msb=3, lsb=3, inst_name='clear_counts'),FieldDefinition(high=4, low=4, msb=4, lsb=4, inst_name='diff_encoder_loopback'), + ]), + 16 : + Register(width=32, full_inst_name='msk_top_regs.MSK_Status', readable=True, writable=False, + fields=[FieldDefinition(high=0, low=0, msb=0, lsb=0, inst_name='demod_sync_lock'),FieldDefinition(high=1, low=1, msb=1, lsb=1, inst_name='tx_enable'),FieldDefinition(high=2, low=2, msb=2, lsb=2, inst_name='rx_enable'),FieldDefinition(high=3, low=3, msb=3, lsb=3, inst_name='tx_axis_valid'), + ]), + 20 : + Register(width=32, full_inst_name='msk_top_regs.Tx_Bit_Count', readable=True, writable=True, + fields=[FieldDefinition(high=31, low=0, msb=31, lsb=0, inst_name='data'), + ]), + 24 : + Register(width=32, full_inst_name='msk_top_regs.Tx_Enable_Count', readable=True, writable=True, + fields=[FieldDefinition(high=31, low=0, msb=31, lsb=0, inst_name='data'), + ]), + 28 : + Register(width=32, full_inst_name='msk_top_regs.Fb_FreqWord', readable=True, writable=True, + fields=[FieldDefinition(high=31, low=0, msb=31, lsb=0, inst_name='config_data'), + ]), + 32 : + Register(width=32, full_inst_name='msk_top_regs.TX_F1_FreqWord', readable=True, writable=True, + fields=[FieldDefinition(high=31, low=0, msb=31, lsb=0, inst_name='config_data'), + ]), + 36 : + Register(width=32, full_inst_name='msk_top_regs.TX_F2_FreqWord', readable=True, writable=True, + fields=[FieldDefinition(high=31, low=0, msb=31, lsb=0, inst_name='config_data'), + ]), + 40 : + Register(width=32, full_inst_name='msk_top_regs.RX_F1_FreqWord', readable=True, writable=True, + fields=[FieldDefinition(high=31, low=0, msb=31, lsb=0, inst_name='config_data'), + ]), + 44 : + Register(width=32, full_inst_name='msk_top_regs.RX_F2_FreqWord', readable=True, writable=True, + fields=[FieldDefinition(high=31, low=0, msb=31, lsb=0, inst_name='config_data'), + ]), + 48 : + Register(width=32, full_inst_name='msk_top_regs.LPF_Config_0', readable=True, writable=True, + fields=[FieldDefinition(high=0, low=0, msb=0, lsb=0, inst_name='lpf_freeze'),FieldDefinition(high=1, low=1, msb=1, lsb=1, inst_name='lpf_zero'),FieldDefinition(high=7, low=2, msb=7, lsb=2, inst_name='prbs_reserved'),FieldDefinition(high=31, low=8, msb=31, lsb=8, inst_name='lpf_alpha'), + ]), + 52 : + Register(width=32, full_inst_name='msk_top_regs.LPF_Config_1', readable=True, writable=True, + fields=[FieldDefinition(high=23, low=0, msb=23, lsb=0, inst_name='i_gain'),FieldDefinition(high=31, low=24, msb=31, lsb=24, inst_name='i_shift'), + ]), + 56 : + Register(width=32, full_inst_name='msk_top_regs.Tx_Data_Width', readable=True, writable=True, + fields=[FieldDefinition(high=7, low=0, msb=7, lsb=0, inst_name='data_width'), + ]), + 60 : + Register(width=32, full_inst_name='msk_top_regs.Rx_Data_Width', readable=True, writable=True, + fields=[FieldDefinition(high=7, low=0, msb=7, lsb=0, inst_name='data_width'), + ]), + 64 : + Register(width=32, full_inst_name='msk_top_regs.PRBS_Control', readable=True, writable=True, + fields=[FieldDefinition(high=0, low=0, msb=0, lsb=0, inst_name='prbs_sel'),FieldDefinition(high=1, low=1, msb=1, lsb=1, inst_name='prbs_error_insert'),FieldDefinition(high=2, low=2, msb=2, lsb=2, inst_name='prbs_clear'),FieldDefinition(high=3, low=3, msb=3, lsb=3, inst_name='prbs_manual_sync'),FieldDefinition(high=15, low=4, msb=15, lsb=4, inst_name='prbs_reserved'),FieldDefinition(high=31, low=16, msb=31, lsb=16, inst_name='prbs_sync_threshold'), + ]), + 68 : + Register(width=32, full_inst_name='msk_top_regs.PRBS_Initial_State', readable=True, writable=True, + fields=[FieldDefinition(high=31, low=0, msb=31, lsb=0, inst_name='config_data'), + ]), + 72 : + Register(width=32, full_inst_name='msk_top_regs.PRBS_Polynomial', readable=True, writable=True, + fields=[FieldDefinition(high=31, low=0, msb=31, lsb=0, inst_name='config_data'), + ]), + 76 : + Register(width=32, full_inst_name='msk_top_regs.PRBS_Error_Mask', readable=True, writable=True, + fields=[FieldDefinition(high=31, low=0, msb=31, lsb=0, inst_name='config_data'), + ]), + 80 : + Register(width=32, full_inst_name='msk_top_regs.PRBS_Bit_Count', readable=True, writable=True, + fields=[FieldDefinition(high=31, low=0, msb=31, lsb=0, inst_name='data'), + ]), + 84 : + Register(width=32, full_inst_name='msk_top_regs.PRBS_Error_Count', readable=True, writable=True, + fields=[FieldDefinition(high=31, low=0, msb=31, lsb=0, inst_name='data'), + ]), + 88 : + Register(width=32, full_inst_name='msk_top_regs.LPF_Accum_F1', readable=True, writable=True, + fields=[FieldDefinition(high=31, low=0, msb=31, lsb=0, inst_name='data'), + ]), + 92 : + Register(width=32, full_inst_name='msk_top_regs.LPF_Accum_F2', readable=True, writable=True, + fields=[FieldDefinition(high=31, low=0, msb=31, lsb=0, inst_name='data'), + ]), + 96 : + Register(width=32, full_inst_name='msk_top_regs.axis_xfer_count', readable=True, writable=True, + fields=[FieldDefinition(high=31, low=0, msb=31, lsb=0, inst_name='data'), + ]), + 100 : + Register(width=32, full_inst_name='msk_top_regs.Rx_Sample_Discard', readable=True, writable=True, + fields=[FieldDefinition(high=7, low=0, msb=7, lsb=0, inst_name='rx_sample_discard'),FieldDefinition(high=15, low=8, msb=15, lsb=8, inst_name='rx_nco_discard'), + ]), + 104 : + Register(width=32, full_inst_name='msk_top_regs.LPF_Config_2', readable=True, writable=True, + fields=[FieldDefinition(high=23, low=0, msb=23, lsb=0, inst_name='p_gain'),FieldDefinition(high=31, low=24, msb=31, lsb=24, inst_name='p_shift'), + ]), + 108 : + Register(width=32, full_inst_name='msk_top_regs.f1_nco_adjust', readable=True, writable=True, + fields=[FieldDefinition(high=31, low=0, msb=31, lsb=0, inst_name='data'), + ]), + 112 : + Register(width=32, full_inst_name='msk_top_regs.f2_nco_adjust', readable=True, writable=True, + fields=[FieldDefinition(high=31, low=0, msb=31, lsb=0, inst_name='data'), + ]), + 116 : + Register(width=32, full_inst_name='msk_top_regs.f1_error', readable=True, writable=True, + fields=[FieldDefinition(high=31, low=0, msb=31, lsb=0, inst_name='data'), + ]), + 120 : + Register(width=32, full_inst_name='msk_top_regs.f2_error', readable=True, writable=True, + fields=[FieldDefinition(high=31, low=0, msb=31, lsb=0, inst_name='data'), + ]), + 124 : + Register(width=32, full_inst_name='msk_top_regs.Tx_Sync_Ctrl', readable=True, writable=True, + fields=[FieldDefinition(high=0, low=0, msb=0, lsb=0, inst_name='tx_sync_ena'),FieldDefinition(high=1, low=1, msb=1, lsb=1, inst_name='tx_sync_force'), + ]), + 128 : + Register(width=32, full_inst_name='msk_top_regs.Tx_Sync_Cnt', readable=True, writable=True, + fields=[FieldDefinition(high=23, low=0, msb=23, lsb=0, inst_name='tx_sync_cnt'), + ]), + 132 : + Register(width=32, full_inst_name='msk_top_regs.lowpass_ema_alpha1', readable=True, writable=True, + fields=[FieldDefinition(high=17, low=0, msb=17, lsb=0, inst_name='alpha'), + ]), + 136 : + Register(width=32, full_inst_name='msk_top_regs.lowpass_ema_alpha2', readable=True, writable=True, + fields=[FieldDefinition(high=17, low=0, msb=17, lsb=0, inst_name='alpha'), + ]), + 140 : + Register(width=32, full_inst_name='msk_top_regs.rx_power', readable=True, writable=True, + fields=[FieldDefinition(high=22, low=0, msb=22, lsb=0, inst_name='data'), + ]), + 144 : + Register(width=32, full_inst_name='msk_top_regs.tx_async_fifo_rd_wr_ptr', readable=True, writable=True, + fields=[FieldDefinition(high=31, low=0, msb=31, lsb=0, inst_name='data'), + ]), + 148 : + Register(width=32, full_inst_name='msk_top_regs.rx_async_fifo_rd_wr_ptr', readable=True, writable=True, + fields=[FieldDefinition(high=31, low=0, msb=31, lsb=0, inst_name='data'), + ]), + 152 : + Register(width=32, full_inst_name='msk_top_regs.rx_frame_sync_status', readable=True, writable=True, + fields=[FieldDefinition(high=0, low=0, msb=0, lsb=0, inst_name='frame_sync_locked'),FieldDefinition(high=1, low=1, msb=1, lsb=1, inst_name='frame_buffer_overflow'),FieldDefinition(high=25, low=2, msb=25, lsb=2, inst_name='frames_received'),FieldDefinition(high=31, low=26, msb=31, lsb=26, inst_name='frame_sync_errors'), + ]), + } + + def _build_memories(self) -> list[MemoryEntry]: + return [ + ] + +if __name__ == '__main__': + pass diff --git a/rdl/cocotb/desyrdl/__init__.py b/rdl/outputs/python/msk_top_regs/sim_lib/__init__.py similarity index 100% rename from rdl/cocotb/desyrdl/__init__.py rename to rdl/outputs/python/msk_top_regs/sim_lib/__init__.py diff --git a/rdl/outputs/python/msk_top_regs/sim_lib/_callbacks.py b/rdl/outputs/python/msk_top_regs/sim_lib/_callbacks.py new file mode 100644 index 0000000..e294617 --- /dev/null +++ b/rdl/outputs/python/msk_top_regs/sim_lib/_callbacks.py @@ -0,0 +1,79 @@ +""" +peakrdl-python is a tool to generate Python Register Access Layer (RAL) from SystemRDL +Copyright (C) 2021 - 2023 + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +This module is intended to distributed as part of automatically generated code by the +peakrdl-python tool. It provides a set of types used by the autogenerated code to callbacks +""" +from typing import Protocol + + +class RegisterReadCallback(Protocol): + """ + Callback definition software read to a field, register or memory + """ + + # pylint: disable=too-few-public-methods + def __call__(self, value: int) -> None: + pass + + +class RegisterWriteCallback(Protocol): + """ + Callback definition software write to a field, register or memory + """ + + # pylint: disable=too-few-public-methods + def __call__(self, value: int) -> None: + pass + +class FieldReadCallback(Protocol): + """ + Callback definition software read to a field, register or memory + """ + + # pylint: disable=too-few-public-methods + def __call__(self, value: int) -> None: + pass + + +class FieldWriteCallback(Protocol): + """ + Callback definition software write to a field, register or memory + """ + + # pylint: disable=too-few-public-methods + def __call__(self, value: int) -> None: + pass + +class MemoryReadCallback(Protocol): + """ + Callback definition software read to a field, register or memory + """ + + # pylint: disable=too-few-public-methods + def __call__(self, offset: int, value: int) -> None: + pass + + +class MemoryWriteCallback(Protocol): + """ + Callback definition software write to a field, register or memory + """ + + # pylint: disable=too-few-public-methods + def __call__(self, offset: int, value: int) -> None: + pass diff --git a/rdl/outputs/python/msk_top_regs/sim_lib/base.py b/rdl/outputs/python/msk_top_regs/sim_lib/base.py new file mode 100644 index 0000000..22077ad --- /dev/null +++ b/rdl/outputs/python/msk_top_regs/sim_lib/base.py @@ -0,0 +1,34 @@ +""" +peakrdl-python is a tool to generate Python Register Access Layer (RAL) from SystemRDL +Copyright (C) 2021 - 2023 + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +This module is intended to distributed as part of automatically generated code by the +peakrdl-python tool. It provides a set of base classes used by the autogenerated code +""" +from abc import ABC + + +# pylint: disable=too-few-public-methods +class Base(ABC): + """ + base class for the simulator nodes + """ + + __slots__ = ['full_inst_name'] + + def __init__(self, *, + full_inst_name: str): + self.full_inst_name = full_inst_name diff --git a/rdl/outputs/python/msk_top_regs/sim_lib/dummy_callbacks.py b/rdl/outputs/python/msk_top_regs/sim_lib/dummy_callbacks.py new file mode 100644 index 0000000..07215a8 --- /dev/null +++ b/rdl/outputs/python/msk_top_regs/sim_lib/dummy_callbacks.py @@ -0,0 +1,256 @@ +""" +peakrdl-python is a tool to generate Python Register Access Layer (RAL) from SystemRDL +Copyright (C) 2021 - 2023 + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +This module provides a set of "dummy" callbacks that provide the most basic of operations +""" +from array import array as Array +import asyncio + +from ..lib.utility_functions import get_array_typecode + +# many of the functions in this file do not use all the arguments, this is because they are stub +# functions +# pylint: disable=unused-argument + + +def dummy_read(addr: int, width: int, accesswidth: int) -> int: + """ + Callback to simulate the operation of the package, everytime the read is called, it return + an integer value of 0 + + Args: + addr: Address to write to + width: Width of the register in bits + accesswidth: Minimum access width of the register in bits + + Returns: + value inputted by the used + """ + return int(0) + + +def dummy_write(addr: int, width: int, accesswidth: int, data: int) -> None: + """ + Callback to simulate the operation of the package, everytime the write is called, it will + print the content + + Args: + addr: Address to write to + width: Width of the register in bits + accesswidth: Minimum access width of the register in bits + data: value to be written to the register + + Returns: + None + """ + # pylint: disable-next=bad-builtin + print(f'0x{data:X} written to 0x{addr:X}') + + +def dummy_read_block(addr: int, width: int, accesswidth: int, length:int) -> list[int]: + """ + Callback to simulate the operation of the package, everytime the read_block is called, it + return an integer value of array of o's + + Args: + addr: Address to write to + width: Width of the register in bits + accesswidth: Minimum access width of the register in bits + length: number of array entries + + Returns: + an array with the correct type (based on width) populated with 0's + + """ + return [0 for x in range(length)] + + +def dummy_read_block_legacy(addr: int, width: int, accesswidth: int, length:int) -> Array: + """ + Callback to simulate the operation of the package, everytime the read_block is called, it + return an integer value of array of o's + + Args: + addr: Address to write to + width: Width of the register in bits + accesswidth: Minimum access width of the register in bits + length: number of array entries + + Returns: + an list with the correct type (based on width) populated with 0's + + """ + return Array(get_array_typecode(width=width), [0 for x in range(length)]) + + +def dummy_write_block(addr: int, width: int, accesswidth: int, data: list[int]) -> None: + """ + Callback to simulate the operation of the package, everytime the read_block is called, it + return an integer value of array of o's + + Args: + addr: Address to write to + width: Width of the register in bits + accesswidth: Minimum access width of the register in bits + data: number of array entries + + Returns: + None + + """ + # pylint: disable=unnecessary-pass + pass + + +def dummy_write_block_legacy(addr: int, width: int, accesswidth: int, data: Array) -> None: + """ + Callback to simulate the operation of the package, everytime the read_block is called, it + return an integer value of array of o's + + Args: + addr: Address to write to + width: Width of the register in bits + accesswidth: Minimum access width of the register in bits + data: number of array entries + + Returns: + None + + """ + # pylint: disable=unnecessary-pass + pass + + +async def async_dummy_read(addr: int, width: int, accesswidth: int) -> int: + """ + async Callback to simulate the operation of the package, everytime the read is called, it + return an integer value of 0 + + Args: + addr: Address to write to + width: Width of the register in bits + accesswidth: Minimum access width of the register in bits + + Returns: + value inputted by the used + """ + await asyncio.sleep(0) + return dummy_read(addr, width, accesswidth) + + +async def async_dummy_write(addr: int, width: int, accesswidth: int, data: int) -> None: + """ + Callback to simulate the operation of the package, everytime the write is called, it will + print the content + + Args: + addr: Address to write to + width: Width of the register in bits + accesswidth: Minimum access width of the register in bits + data: value to be written to the register + + Returns: + None + """ + await asyncio.sleep(0) + return dummy_write(addr, width, accesswidth, data) + + +async def async_dummy_read_block(addr: int, + width: int, + accesswidth: int, + length: int) -> list[int]: + """ + Callback to simulate the operation of the package, everytime the read_block is called, it + return an integer value of array of o's + + Args: + addr: Address to write to + width: Width of the register in bits + accesswidth: Minimum access width of the register in bits + length: number of array entries + + Returns: + an array with the correct type (based on width) populated with 0's + + """ + await asyncio.sleep(0) + return dummy_read_block(addr, width, accesswidth, length) + + +async def async_dummy_read_block_legacy(addr: int, + width: int, + accesswidth: int, + length: int) -> Array: + """ + Callback to simulate the operation of the package, everytime the read_block is called, it + return an integer value of array of o's + + Args: + addr: Address to write to + width: Width of the register in bits + accesswidth: Minimum access width of the register in bits + length: number of array entries + + Returns: + an List with the correct type (based on width) populated with 0's + + """ + await asyncio.sleep(0) + return dummy_read_block_legacy(addr, width, accesswidth, length) + + +async def async_dummy_write_block(addr: int, + width: int, + accesswidth: int, data: list[int]) -> None: + """ + Callback to simulate the operation of the package, everytime the read_block is called, it + return an integer value of array of o's + + Args: + addr: Address to write to + width: Width of the register in bits + accesswidth: Minimum access width of the register in bits + data: number of array entries + + Returns: + None + + """ + await asyncio.sleep(0) + return dummy_write_block(addr, width, accesswidth, data) + + +async def async_dummy_write_block_legacy(addr: int, + width: int, + accesswidth: int, data: Array) -> None: + """ + Callback to simulate the operation of the package, everytime the read_block is called, it + return an integer value of array of o's + + Args: + addr: Address to write to + width: Width of the register in bits + accesswidth: Minimum access width of the register in bits + data: number of array entries + + Returns: + None + + """ + await asyncio.sleep(0) + return dummy_write_block_legacy(addr, width, accesswidth, data) diff --git a/rdl/outputs/python/msk_top_regs/sim_lib/field.py b/rdl/outputs/python/msk_top_regs/sim_lib/field.py new file mode 100644 index 0000000..2516905 --- /dev/null +++ b/rdl/outputs/python/msk_top_regs/sim_lib/field.py @@ -0,0 +1,154 @@ +""" +peakrdl-python is a tool to generate Python Register Access Layer (RAL) from SystemRDL +Copyright (C) 2021 - 2023 + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +This module is intended to distributed as part of automatically generated code by the +peakrdl-python tool. It provides a set of base classes used by the autogenerated code +""" +from dataclasses import dataclass +from typing import TYPE_CHECKING +from typing import Optional + +from ..lib.utility_functions import swap_msb_lsb_ordering + +from ._callbacks import FieldReadCallback, FieldWriteCallback + +from .base import Base + +if TYPE_CHECKING: + from .register import BaseRegister + +# pylint: disable=too-many-instance-attributes,too-many-arguments + + +@dataclass +class FieldDefinition: + """ + Class for an entry in the list of memories in the simulator + """ + high: int + low: int + msb: int + lsb: int + inst_name: str + +class Field(Base): + """ + class for all fields + + Note: + It is not expected that this class will be instantiated under normal + circumstances however, it is useful for type checking + """ + + __slots__ = ['__high', '__low', '__msb', '__lsb', + '__bitmask', '__inverse_bitmask', + '__msb0', '__lsb0', + '__parent_register','__parent_width', + '__read_callback', '__write_callback'] + + def __init__(self, *, low: int, high: int, msb: int, lsb: int, + parent_register: 'BaseRegister', parent_width: int, inst_name: str): + + super().__init__(full_inst_name=parent_register.full_inst_name + '.' + inst_name) + + self.__low = low + self.__high = high + + # there are a couple of properties that have been included because they may be needed in + # the future but are currently unused + # pylint: disable=unused-private-member + self.__lsb = lsb + self.__msb = msb + + if (msb == high) and (lsb == low): + self.__lsb0 = True + self.__msb0 = False + elif (msb == low) and (lsb == high): + self.__lsb0 = False + self.__msb0 = True + else: + raise ValueError('msb/lsb are inconsistent with low/high') + # pylint: enable=unused-private-member + + self.__parent_register = parent_register + self.__parent_width = parent_width + + self.__bitmask = 0 + for bit_position in range(low, high+1): + self.__bitmask |= (1 << bit_position) + + parent_max_value = (2 ** parent_width) - 1 + self.__inverse_bitmask = parent_max_value ^ self.__bitmask + + self.__read_callback: Optional[FieldReadCallback] = None + self.__write_callback: Optional[FieldWriteCallback] = None + + @property + def read_callback(self) -> Optional[FieldReadCallback]: + """ + Callback made during each read operation + """ + return self.__read_callback + + @read_callback.setter + def read_callback(self, callback: Optional[FieldReadCallback]) -> None: + self.__read_callback = callback + + @property + def write_callback(self) -> Optional[FieldWriteCallback]: + """ + Callback made during each write operation + """ + return self.__write_callback + + @write_callback.setter + def write_callback(self, callback: Optional[FieldWriteCallback]) -> None: + self.__write_callback = callback + + @property + def __width(self) -> int: + return self.__high - self.__low + 1 + + @property + def value(self) -> int: + """ + Access the register value without triggering the callbacks + """ + + reg_value = self.__parent_register.value + + if self.__msb0: + return swap_msb_lsb_ordering(value=(reg_value & self.__bitmask) >> self.__low, + width=self.__width) + + return (reg_value & self.__bitmask) >> self.__low + + @value.setter + def value(self, value: int) -> None: + + if self.__msb0: + value = swap_msb_lsb_ordering(value=value, width=self.__width) + + if (self.__high == (self.__parent_width - 1)) and (self.__low == 0): + # special case where the field occupies the whole register, + # there a straight write can be performed + self.__parent_register.value = value + else: + # do a read, modify write + reg_value = self.__parent_register.read() + self.__parent_register.value = (reg_value & self.__inverse_bitmask) | \ + (value << self.__low) diff --git a/rdl/outputs/python/msk_top_regs/sim_lib/memory.py b/rdl/outputs/python/msk_top_regs/sim_lib/memory.py new file mode 100644 index 0000000..209f0ca --- /dev/null +++ b/rdl/outputs/python/msk_top_regs/sim_lib/memory.py @@ -0,0 +1,159 @@ +""" +peakrdl-python is a tool to generate Python Register Access Layer (RAL) from SystemRDL +Copyright (C) 2021 - 2023 + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +This module is intended to distributed as part of automatically generated code by the +peakrdl-python tool. It provides a set of base classes used by the autogenerated code +""" +from typing import Optional + +from .base import Base +from ._callbacks import MemoryReadCallback, MemoryWriteCallback + + +class _MemoryContent: + + __slots__ = ['__value', '__default_value', '__length'] + + def __init__(self, *, + default_value: int): + self.__value:dict[int, int] = {} + self.__default_value = default_value + + def __getitem__(self, item: int) -> int: + if item in self.__value: + return self.__value[item] + + return self.__default_value + + def __setitem__(self, key: int, value: int) -> None: + self.__value[key] = value + + +class Memory(Base): + """ + Simulation of a memory, this is implemented using a sparse approach to avoid the simulator + storing every possible entry in a register map, which could be very big. + """ + __slots__ = ['__value', '__width', '__length', + '__read_callback', '__write_callback'] + + def __init__(self, *, + width: int, + length: int, + default_value: int, + full_inst_name: str): + + super().__init__(full_inst_name=full_inst_name) + + self.__value = _MemoryContent(default_value=default_value) + self.__width = width + self.__length = length + self.__read_callback: Optional[MemoryReadCallback] = None + self.__write_callback: Optional[MemoryWriteCallback] = None + + @property + def read_callback(self) -> Optional[MemoryReadCallback]: + """ + Callback made during each read operation + """ + return self.__read_callback + + @read_callback.setter + def read_callback(self, callback: Optional[MemoryReadCallback]) -> None: + self.__read_callback = callback + + @property + def write_callback(self) -> Optional[MemoryWriteCallback]: + """ + Callback made during each write operation + """ + return self.__write_callback + + @write_callback.setter + def write_callback(self, callback: Optional[MemoryWriteCallback]) -> None: + self.__write_callback = callback + + def read(self, offset: int) -> int: + """ + Read a memory word + + Args: + offset (int): Word offset in the memory + + Returns: + memory word content + + """ + self.__offset_range_check(offset) + value = self.value[offset] + if self.read_callback is not None: + # pylint does not recognise that the property is returning a callback therefore it + # is legal to call it. + # pylint: disable-next=not-callable + self.read_callback(offset=offset, value=value) + return value + + def write(self, offset: int, data: int) -> None: + """ + Write a memory word + + Args: + offset: (int): Word offset in the memory + data: data word + + Returns: + None + + """ + self.__offset_range_check(offset) + if self.write_callback is not None: + # pylint does not recognise that the property is returning a callback therefore it + # is legal to call it. + # pylint: disable-next=not-callable + self.write_callback(offset=offset, value=data) + self.value[offset] = data + + @property + def _width_in_bytes(self) -> int: + def roundup_pow2(x: int) -> int: + return 1 << (x - 1).bit_length() + + return roundup_pow2(self.__width) // 8 + + def byte_offset_to_word_offset(self, byte_offset: int) -> int: + """ + Determine a memory word offset + + Args: + byte_offset (int): byte offset from memory start + + Returns: + word offset + + """ + return byte_offset // self._width_in_bytes + + @property + def value(self) -> _MemoryContent: + """ + Access to the memory content, bypassing the callbacks + """ + return self.__value + + def __offset_range_check(self, offset: int) -> None: + if not 0 <= offset < self.__length: + raise IndexError(f'offset must in in range 0 to {self.__length-1}, got {offset:d}') diff --git a/rdl/outputs/python/msk_top_regs/sim_lib/register.py b/rdl/outputs/python/msk_top_regs/sim_lib/register.py new file mode 100644 index 0000000..9f5b72a --- /dev/null +++ b/rdl/outputs/python/msk_top_regs/sim_lib/register.py @@ -0,0 +1,211 @@ +""" +peakrdl-python is a tool to generate Python Register Access Layer (RAL) from SystemRDL +Copyright (C) 2021 - 2023 + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +This module is intended to distributed as part of automatically generated code by the +peakrdl-python tool. It provides a set of base classes used by the autogenerated code +""" +from abc import ABC, abstractmethod +from typing import Optional + +from .memory import Memory +from .base import Base +from .field import FieldDefinition, Field +from ._callbacks import RegisterReadCallback,RegisterWriteCallback + +# pylint: disable=too-many-arguments + +class BaseRegister(Base, ABC): + """ + Base class for registers + """ + + __slots__ = ['_width', '_readable', '_writable', 'fields', + '__read_callback', '__write_callback'] + + def __init__(self, *, + width: int, + full_inst_name: str, + readable: bool, + writable: bool, + fields: list[FieldDefinition]): + super().__init__(full_inst_name=full_inst_name) + self._width = width + self._readable = readable + self._writable = writable + self.fields = [Field(low=field_def.low, + high=field_def.high, + msb=field_def.msb, + lsb=field_def.lsb, + inst_name=field_def.inst_name, + parent_register=self, + parent_width=width) for field_def in fields] + self.__read_callback: Optional[RegisterReadCallback] = None + self.__write_callback: Optional[RegisterWriteCallback] = None + + @property + def read_callback(self) -> Optional[RegisterReadCallback]: + """ + Callback made during each read operation + """ + return self.__read_callback + + @read_callback.setter + def read_callback(self, callback: Optional[RegisterReadCallback]) -> None: + self.__read_callback = callback + + @property + def write_callback(self) -> Optional[RegisterWriteCallback]: + """ + Callback made during each write operation + """ + return self.__write_callback + + @write_callback.setter + def write_callback(self, callback: Optional[RegisterWriteCallback]) -> None: + self.__write_callback = callback + + def _action_read_callback(self) -> None: + if self.read_callback is not None: + # pylint does not recognise that the property is returning a callback therefore it + # is legal to call it. + # pylint: disable-next=not-callable + self.read_callback(value=self.value) + + for field in self.fields: + if field.read_callback is not None: + field.read_callback(value=field.value) + + def _action_write_callback(self) -> None: + if self.write_callback is not None: + # pylint does not recognise that the property is returning a callback therefore it + # is legal to call it. + # pylint: disable-next=not-callable + self.write_callback(value=self.value) + + for field in self.fields: + if field.write_callback is not None: + field.write_callback(value=field.value) + + @abstractmethod + def read(self) -> int: + """ + Read the register + + Returns: + register content + + """ + + @abstractmethod + def write(self, data: int) -> None: + """ + Write the register + + Args: + data (int): new register content + + Returns: + None + + """ + + @property + @abstractmethod + def value(self) -> int: + """ + Access the register value without triggering the callbacks + """ + + @value.setter + @abstractmethod + def value(self, value:int) -> None: + ... + + +class Register(BaseRegister): + """ + Class for Register that is created in normal logic + """ + + __slots__ = ['__value'] + + def __init__(self, *, + width: int, + full_inst_name: str, + readable: bool, + writable: bool, + fields: list[FieldDefinition]): + super().__init__(width=width, full_inst_name=full_inst_name, + readable=readable, writable=writable, fields=fields) + self.__value = 0 + + def read(self) -> int: + + self._action_read_callback() + return self.__value + + def write(self, data: int) -> None: + + self.__value = data + self._action_write_callback() + + @property + def value(self) -> int: + return self.__value + + @value.setter + def value(self, value: int) -> None: + self.__value = value + + +class MemoryRegister(BaseRegister): + """ + Class for Register that maps onto a memory + """ + + __slots__ = ['__memory', '__offset'] + + def __init__(self, *, + width: int, + full_inst_name: str, + readable: bool, + writable: bool, + memory: Memory, + memory_address_offset: int, + fields: list[FieldDefinition]): + super().__init__(width=width, full_inst_name=full_inst_name, + readable=readable, writable=writable, fields=fields) + if not isinstance(memory, Memory): + raise TypeError(f'memory type is wrong, got {type(memory)}') + self.__memory = memory + self.__offset = memory.byte_offset_to_word_offset(memory_address_offset) + + def read(self) -> int: + self._action_read_callback() + return self.__memory.read(self.__offset) + + def write(self, data: int) -> None: + self.__memory.write(self.__offset, data) + self._action_write_callback() + + @property + def value(self) -> int: + return self.__memory.value[self.__offset] + + @value.setter + def value(self, value: int) -> None: + self.__memory.value[self.__offset] = value diff --git a/rdl/outputs/python/msk_top_regs/sim_lib/simulator.py b/rdl/outputs/python/msk_top_regs/sim_lib/simulator.py new file mode 100644 index 0000000..e7cef5b --- /dev/null +++ b/rdl/outputs/python/msk_top_regs/sim_lib/simulator.py @@ -0,0 +1,500 @@ +""" +peakrdl-python is a tool to generate Python Register Access Layer (RAL) from SystemRDL +Copyright (C) 2021 - 2023 + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +This module is intended to distributed as part of automatically generated code by the +peakrdl-python tool. It provides a set of base classes used by the autogenerated code +""" +from abc import ABC, abstractmethod +from dataclasses import dataclass +from typing import Optional, Union +from array import array as Array +import asyncio + +from .register import Register, MemoryRegister +from .memory import Memory +from .field import Field + +from ..lib.utility_functions import get_array_typecode + +@dataclass +class MemoryEntry: + """ + Class for an entry in the list of memories in the simulator + """ + start_address: int + end_address: int + memory: Memory + + def memory_offset(self, address: int) -> int: + """ + Convert an absolute address to word offset within a memory + + Args: + address: byte address + + Returns: memory word offset + + """ + return self.memory.byte_offset_to_word_offset(address - self.start_address) + + + def address_in_memory(self, address: int) -> bool: + """ + Determine if an address is within a memory or not + + Args: + address: byte address + + Returns: + if address is within the range of the memory + + """ + return self.start_address <= address <= self.end_address + + +class BaseSimulator(ABC): + """ + Base class of a simple simulate that can be used to test and debug peakrdl-python generated + register access layer (RAL) + """ + # pylint: disable=too-few-public-methods + + def __init__(self, address: int): + + # it is important to build the memories first as some registers may be within memories + self._memories = self._build_memories() + self._registers = self._build_registers() + self.address = address + + @abstractmethod + def _build_registers(self) -> dict[int, Union[list[Union[MemoryRegister, Register]], + Union[MemoryRegister, Register]]]: + """ + populate the register structure, this method is intended to implemented by the generated + code based on then design + """ + + @abstractmethod + def _build_memories(self) -> list[MemoryEntry]: + """ + populate the memory structure, this method is intended to written by the generated code + based on then design + """ + + def memory_for_address(self, address: int) -> Optional[MemoryEntry]: + """ + Find a memory entry for a given address + + Args: + address: byte address + + Returns: + None or matching memory entry + + """ + + memory_subset = list(filter(lambda x : x.address_in_memory(address=address), + self._memories)) + + if len(memory_subset) > 1: + raise RuntimeError(f'multiple memory matches on address 0x{address:X}({address:d})') + + if len(memory_subset) == 1: + return memory_subset[0] + + return None + + def memory_for_address_with_exception(self, address: int) -> MemoryEntry: + """ + Find a memory entry for a given address + + Args: + address: byte address + + Returns: + matching memory entry + + """ + + memory_entry = self.memory_for_address(address=address) + if memory_entry is None: + raise RuntimeError(f'Memory not found at address 0x{address:X}') + + return memory_entry + + def _read(self, addr: int, + width: int, # pylint: disable=unused-argument + accesswidth: int) -> int: # pylint: disable=unused-argument + """ + function to simulate a device read, this needs to match the protocol for the callbacks + """ + + # see if the address is a register first this ensures that registers in memories are + # accessed directly + if addr in self._registers: + addr_entry = self._registers[addr] + if isinstance(addr_entry, list): + # search the list for a readable register + for inner_reg in addr_entry: + # pylint: disable-next=protected-access + if inner_reg._readable: + return inner_reg.read() + else: + return addr_entry.read() + + potential_memory = self.memory_for_address(address=addr) + if potential_memory is not None: + return potential_memory.memory.read(offset=potential_memory.memory_offset(addr)) + + # catch all for other addresses + return 0 + + def _write(self, addr: int, + width: int, # pylint: disable=unused-argument + accesswidth: int, # pylint: disable=unused-argument + data: int) -> None: + """ + function to simulate a device write, this needs to match the protocol for the callbacks + """ + # see if the address is a register first this ensures that registers in memories are + # accessed directly + if addr in self._registers: + addr_entry = self._registers[addr] + if isinstance(addr_entry, list): + for inner_reg in addr_entry: + # pylint: disable-next=protected-access + if inner_reg._writable: + inner_reg.write(data) + else: + addr_entry.write(data) + else: + potential_memory = self.memory_for_address(address=addr) + if potential_memory is not None: + potential_memory.memory.write(offset=potential_memory.memory_offset(addr), + data=data) + + def _read_block_legacy(self, addr: int, width: int, accesswidth: int, length: int) -> Array: + """ + function to simulate a device block read, this needs to match the protocol for the + callbacks + + This currently uses a simplified implementation of converting all the block operations + to discrete operations, a future enhancement could be to access slices of memories + """ + return Array(get_array_typecode(width),self._read_block(addr=addr, + width=width, + accesswidth=accesswidth, + length=length)) + + def _read_block(self, addr: int, width: int, accesswidth: int, length: int) -> list[int]: + """ + function to simulate a device block read, this needs to match the protocol for the + callbacks + + This currently uses a simplified implementation of converting all the block operations + to discrete operations, a future enhancement could be to access slices of memories + """ + addresses = self._block_access_addresses(start_address=addr, width=width, length=length) + return [self._read(element_addr, + width=width, + accesswidth=accesswidth) for element_addr in addresses] + + def _write_block(self, addr: int, width: int, accesswidth: int, + data: Union[list, Array]) -> None: + """ + function to simulate a device block write, this needs to match the protocol for the + callbacks + + This currently uses a simplified implementation of converting all the block operations + to discrete operations, a future enhancement could be to access slices of memories + """ + addresses = self._block_access_addresses(start_address=addr, + width=width, + length=len(data)) + for (element_address, element_data) in zip(addresses, data): + self._write(addr=element_address, + data=element_data, + width=width, + accesswidth=accesswidth) + + @staticmethod + def _block_access_addresses(start_address: int, width: int, length: int) -> range: + """ + + Args: + start_address: start byte address + width: word width + length: number of word in the block + + Returns: range iterator for the addresses in the block + """ + def roundup_pow2(x: int) -> int: + return 1 << (x - 1).bit_length() + + address_increment = roundup_pow2(width) // 8 + end_address = start_address + (length * address_increment) + return range(start_address, end_address, address_increment) + + def register_by_full_name(self, name: str) -> Union[MemoryRegister, Register]: + """ + Find a register in the simulator by its fully qualified name + + Args: + name: fully qualified register name + + Returns: Register + + """ + for reg in self._registers.values(): + if isinstance(reg, list): + for reg_list_entry in reg: + if reg_list_entry.full_inst_name == name: + return reg_list_entry + else: + if reg.full_inst_name == name: + return reg + + raise ValueError(f'register name not matched: {name}') + + def field_by_full_name(self, name: str) -> Field: + """ + Find a register field in the simulator by its fully qualified name + + Args: + name: fully qualified field name + + Returns: Field + + """ + for reg in self._registers.values(): + if isinstance(reg, list): + for reg_list_entry in reg: + for field in reg_list_entry.fields: + if field.full_inst_name == name: + return field + else: + for field in reg.fields: + if field.full_inst_name == name: + return field + + raise ValueError(f'field name not matched: {name}') + + def node_by_full_name(self, name: str) -> Union[Memory, MemoryRegister, Register, Field]: + """ + Find a node in the simulator by its fully qualified name + + Args: + name: fully qualified node name + + Returns: Node + + """ + + for mem in self._memories: + if mem.memory.full_inst_name == name: + return mem.memory + + for reg in self._registers.values(): + if isinstance(reg, list): + for reg_list_entry in reg: + if reg_list_entry.full_inst_name == name: + return reg_list_entry + + for field in reg_list_entry.fields: + if field.full_inst_name == name: + return field + else: + if reg.full_inst_name == name: + return reg + + for field in reg.fields: + if field.full_inst_name == name: + return field + + raise ValueError(f'node name not matched: {name}') + + +class Simulator(BaseSimulator, ABC): + """ + Base class of a simple simulator that uses non-async callbacks that can be used to test and + debug peakrdl-python generated register access layer (RAL) + """ + + def read(self, addr: int, + width: int, # pylint: disable=unused-argument + accesswidth: int) -> int: # pylint: disable=unused-argument + """ + function to simulate a device read, this needs to match the protocol for the callbacks + """ + return self._read(addr, width, accesswidth) + + def write(self, addr: int, width: int, accesswidth: int, data: int) -> None: + """ + function to simulate a device write, this needs to match the protocol for the callbacks + """ + return self._write(addr, width, accesswidth, data) + + def read_block(self, addr: int, width: int, accesswidth: int, length: int) -> list[int]: + """ + function to simulate a device block read, this needs to match the protocol for the + callbacks + + This currently uses a simplified implementation of converting all the block operations + to discrete operations, a future enhancement could be to access slices of memories + """ + return self._read_block(addr, width, accesswidth, length) + + def write_block(self, addr: int, width: int, accesswidth: int, data: list[int]) -> None: + """ + function to simulate a device block write, this needs to match the protocol for the + callbacks + + This currently uses a simplified implementation of converting all the block operations + to discrete operations, a future enhancement could be to access slices of memories + """ + return self._write_block(addr, width, accesswidth, data) + + +class SimulatorLegacy(BaseSimulator, ABC): + """ + Base class of a simple simulator that uses non-async callbacks that can be used to test and + debug peakrdl-python generated register access layer (RAL) + """ + + def read(self, addr: int, + width: int, # pylint: disable=unused-argument + accesswidth: int) -> int: # pylint: disable=unused-argument + """ + function to simulate a device read, this needs to match the protocol for the callbacks + """ + return self._read(addr, width, accesswidth) + + def write(self, addr: int, width: int, accesswidth: int, data: int) -> None: + """ + function to simulate a device write, this needs to match the protocol for the callbacks + """ + return self._write(addr, width, accesswidth, data) + + def read_block(self, addr: int, width: int, accesswidth: int, length: int) -> Array: + """ + function to simulate a device block read, this needs to match the protocol for the + callbacks + + This currently uses a simplified implementation of converting all the block operations + to discrete operations, a future enhancement could be to access slices of memories + """ + return self._read_block_legacy(addr, width, accesswidth, length) + + def write_block(self, addr: int, width: int, accesswidth: int, data: Array) -> None: + """ + function to simulate a device block write, this needs to match the protocol for the + callbacks + + This currently uses a simplified implementation of converting all the block operations + to discrete operations, a future enhancement could be to access slices of memories + """ + return self._write_block(addr, width, accesswidth, data) + + +class AsyncSimulator(BaseSimulator, ABC): + """ + Base class of a simple simulator that uses async callbacks that can be used to test and + debug peakrdl-python generated register access layer (RAL) + """ + + async def read(self, addr: int, + width: int, # pylint: disable=unused-argument + accesswidth: int) -> int: # pylint: disable=unused-argument + """ + function to simulate a device read, this needs to match the protocol for the callbacks + """ + await asyncio.sleep(0) + return self._read(addr, width, accesswidth) + + async def write(self, addr: int, width: int, accesswidth: int, data: int) -> None: + """ + function to simulate a device write, this needs to match the protocol for the callbacks + """ + await asyncio.sleep(0) + return self._write(addr, width, accesswidth, data) + + async def read_block(self, addr: int, width: int, accesswidth: int, length: int) -> list[int]: + """ + function to simulate a device block read, this needs to match the protocol for the + callbacks + + This currently uses a simplified implementation of converting all the block operations + to discrete operations, a future enhancement could be to access slices of memories + """ + await asyncio.sleep(0) + return self._read_block(addr, width, accesswidth, length) + + async def write_block(self, addr: int, width: int, accesswidth: int, data: list[int]) -> None: + """ + function to simulate a device block write, this needs to match the protocol for the + callbacks + + This currently uses a simplified implementation of converting all the block operations + to discrete operations, a future enhancement could be to access slices of memories + """ + await asyncio.sleep(0) + return self._write_block(addr, width, accesswidth, data) + + +class AsyncSimulatorLegacy(BaseSimulator, ABC): + """ + Base class of a simple simulator that uses async callbacks that can be used to test and + debug peakrdl-python generated register access layer (RAL) + """ + + async def read(self, addr: int, + width: int, # pylint: disable=unused-argument + accesswidth: int) -> int: # pylint: disable=unused-argument + """ + function to simulate a device read, this needs to match the protocol for the callbacks + """ + await asyncio.sleep(0) + return self._read(addr, width, accesswidth) + + async def write(self, addr: int, width: int, accesswidth: int, data: int) -> None: + """ + function to simulate a device write, this needs to match the protocol for the callbacks + """ + await asyncio.sleep(0) + return self._write(addr, width, accesswidth, data) + + async def read_block(self, addr: int, width: int, accesswidth: int, length: int) -> Array: + """ + function to simulate a device block read, this needs to match the protocol for the + callbacks + + This currently uses a simplified implementation of converting all the block operations + to discrete operations, a future enhancement could be to access slices of memories + """ + await asyncio.sleep(0) + return self._read_block_legacy(addr, width, accesswidth, length) + + async def write_block(self, addr: int, width: int, accesswidth: int, data: Array) -> None: + """ + function to simulate a device block write, this needs to match the protocol for the + callbacks + + This currently uses a simplified implementation of converting all the block operations + to discrete operations, a future enhancement could be to access slices of memories + """ + await asyncio.sleep(0) + return self._write_block(addr, width, accesswidth, data) diff --git a/rdl/outputs/python/msk_top_regs/tests/__init__.py b/rdl/outputs/python/msk_top_regs/tests/__init__.py new file mode 100644 index 0000000..2ae2839 --- /dev/null +++ b/rdl/outputs/python/msk_top_regs/tests/__init__.py @@ -0,0 +1 @@ +pass diff --git a/rdl/outputs/python/msk_top_regs/tests/_msk_top_regs_sim_test_base.py b/rdl/outputs/python/msk_top_regs/tests/_msk_top_regs_sim_test_base.py new file mode 100644 index 0000000..65350f8 --- /dev/null +++ b/rdl/outputs/python/msk_top_regs/tests/_msk_top_regs_sim_test_base.py @@ -0,0 +1,50 @@ + + + +""" +Unit Tests for the msk_top_regs register model Python Wrapper + +This code was generated from the PeakRDL-python package version 1.4.0 +""" + + +import sys +import asyncio +if sys.version_info < (3, 8): + import asynctest # type: ignore[import] +else: + import unittest + + + +from ..lib import RegisterWriteVerifyError + +from ..lib import AsyncCallbackSet + + +from ._msk_top_regs_test_base import msk_top_regs_TestCase, msk_top_regs_TestCase_BlockAccess + +from ..reg_model.msk_top_regs import msk_top_regs_cls +from ..sim.msk_top_regs import msk_top_regs_simulator_cls + +class msk_top_regs_SimTestCase(msk_top_regs_TestCase): # type: ignore[valid-type,misc] + + def setUp(self) -> None: + self.sim = msk_top_regs_simulator_cls(address=0) + self.dut = msk_top_regs_cls(callbacks=AsyncCallbackSet(read_callback=self.sim.read, + write_callback=self.sim.write)) + +class msk_top_regs_SimTestCase_BlockAccess(msk_top_regs_TestCase_BlockAccess): # type: ignore[valid-type,misc] + + def setUp(self) -> None: + self.sim = msk_top_regs_simulator_cls(address=0) + self.dut = msk_top_regs_cls(callbacks=AsyncCallbackSet(read_callback=self.sim.read, + write_callback=self.sim.write, + read_block_callback=self.sim.read_block, + write_block_callback=self.sim.write_block)) + + + + +if __name__ == '__main__': + pass \ No newline at end of file diff --git a/rdl/outputs/python/msk_top_regs/tests/_msk_top_regs_test_base.py b/rdl/outputs/python/msk_top_regs/tests/_msk_top_regs_test_base.py new file mode 100644 index 0000000..eebf57f --- /dev/null +++ b/rdl/outputs/python/msk_top_regs/tests/_msk_top_regs_test_base.py @@ -0,0 +1,121 @@ + + + +""" +Unit Tests for the msk_top_regs register model Python Wrapper + +This code was generated from the PeakRDL-python package version 1.4.0 +""" +from array import array as Array + +import sys +import asyncio +if sys.version_info < (3, 8): + import asynctest # type: ignore[import] +else: + import unittest + +import random + + + +from ..lib import RegisterWriteVerifyError + +from ..lib import AsyncCallbackSet, AsyncCallbackSetLegacy + + + +from ..reg_model.msk_top_regs import msk_top_regs_cls + +from ..sim_lib.dummy_callbacks import async_dummy_read as read_addr_space +from ..sim_lib.dummy_callbacks import async_dummy_write as write_addr_space +from ..sim_lib.dummy_callbacks import async_dummy_read_block as read_block_addr_space +from ..sim_lib.dummy_callbacks import async_dummy_write_block as write_block_addr_space +from ..sim_lib.dummy_callbacks import async_dummy_read_block_legacy as read_block_addr_space_alt +from ..sim_lib.dummy_callbacks import async_dummy_write_block_legacy as write_block_addr_space_alt + + + +from ..lib import SystemRDLEnum, SystemRDLEnumEntry + + +async def read_callback(addr: int, width: int, accesswidth: int) -> int: + return await read_addr_space(addr=addr, width=width, accesswidth=accesswidth) + +async def read_block_callback(addr: int, width: int, accesswidth: int, length: int) -> list[int]: + return await read_block_addr_space(addr=addr, width=width, accesswidth=accesswidth, length=length) + +async def read_block_callback_alt(addr: int, width: int, accesswidth: int, length: int) -> Array: + return await read_block_addr_space_alt(addr=addr, width=width, accesswidth=accesswidth, length=length) + +async def write_callback(addr: int, width: int, accesswidth: int, data: int) -> None: + await write_addr_space(addr=addr, width=width, accesswidth=accesswidth, data=data) + +async def write_block_callback(addr: int, width: int, accesswidth: int, data: list[int]) -> None: + await write_block_addr_space(addr=addr, width=width, accesswidth=accesswidth, data=data) + +async def write_block_callback_alt(addr: int, width: int, accesswidth: int, data: Array) -> None: + await write_block_addr_space_alt(addr=addr, width=width, accesswidth=accesswidth, data=data) + +def random_enum_reg_value(enum_class: type[SystemRDLEnum]) -> SystemRDLEnum: + return random.choice(list(enum_class)) + + +if sys.version_info < (3, 8): + TestCaseBase = asynctest.TestCase +else: + TestCaseBase = unittest.IsolatedAsyncioTestCase + + +class msk_top_regs_TestCase(TestCaseBase): # type: ignore[valid-type,misc] + + def setUp(self) -> None: + self.dut = msk_top_regs_cls(callbacks=AsyncCallbackSet(read_callback=read_callback, + write_callback=write_callback)) + + @staticmethod + def _reverse_bits(value: int, number_bits: int) -> int: + """ + + Args: + value: value to reverse + number_bits: number of bits used in the value + + Returns: + reversed valued + """ + result = 0 + for i in range(number_bits): + if (value >> i) & 1: + result |= 1 << (number_bits - 1 - i) + return result + +class msk_top_regs_TestCase_BlockAccess(TestCaseBase): # type: ignore[valid-type,misc] + + def setUp(self) -> None: + self.dut = msk_top_regs_cls(callbacks=AsyncCallbackSet(read_callback=read_callback, + write_callback=write_callback, + read_block_callback=read_block_callback, + write_block_callback=write_block_callback)) + +class msk_top_regs_TestCase_AltBlockAccess(TestCaseBase): # type: ignore[valid-type,misc] + """ + Based test to use with the alternative call backs, this allow the legacy output API to be tested + with the new callbacks and visa versa. + """ + + def setUp(self) -> None: + self.dut = msk_top_regs_cls(callbacks=AsyncCallbackSetLegacy( + read_callback=read_callback, + write_callback=write_callback, + read_block_callback=read_block_callback_alt, + write_block_callback=write_block_callback_alt)) + + + + +if __name__ == '__main__': + pass + + + diff --git a/rdl/outputs/python/msk_top_regs/tests/test_msk_top_regs.py b/rdl/outputs/python/msk_top_regs/tests/test_msk_top_regs.py new file mode 100644 index 0000000..f3025d6 --- /dev/null +++ b/rdl/outputs/python/msk_top_regs/tests/test_msk_top_regs.py @@ -0,0 +1,18831 @@ + + + +""" +Unit Tests for the msk_top_regs register model Python Wrapper + +This code was generated from the PeakRDL-python package version 1.4.0 +""" +from typing import Union,Iterable +from array import array as Array + +import sys +import asyncio +import unittest +from unittest.mock import patch, call + +import random +from itertools import combinations, chain +import math + + +from ..lib import RegisterWriteVerifyError, UnsupportedWidthError + +from ..reg_model.msk_top_regs import msk_top_regs_cls + + + + +from ..lib import FieldAsyncReadOnly, FieldAsyncWriteOnly, FieldAsyncReadWrite +from ..lib import WritableAsyncRegister, ReadableAsyncRegister +from ..lib import RegAsyncReadWrite, RegAsyncReadOnly, RegAsyncWriteOnly +from ..lib import RegAsyncReadWriteArray, RegAsyncReadOnlyArray, RegAsyncWriteOnlyArray +from ..lib import MemoryAsyncReadOnly, MemoryAsyncWriteOnly, MemoryAsyncReadWrite +from ..lib import MemoryAsyncReadOnlyArray, MemoryAsyncWriteOnlyArray, MemoryAsyncReadWriteArray +from ..lib import AsyncAddressMap, AsyncRegFile +from ..lib import AsyncAddressMapArray, AsyncRegFileArray +from ..lib import AsyncMemory + + + +from ..lib import Field +from ..lib import Reg + +from ..lib import SystemRDLEnum, SystemRDLEnumEntry + + +from ._msk_top_regs_test_base import msk_top_regs_TestCase, msk_top_regs_TestCase_BlockAccess, msk_top_regs_TestCase_AltBlockAccess +from ._msk_top_regs_test_base import __name__ as base_name +from ._msk_top_regs_test_base import random_enum_reg_value + + + +class msk_top_regs_single_access(msk_top_regs_TestCase): # type: ignore[valid-type,misc] + + def test_inst_name(self) -> None: + """ + Walk the address map and check the inst name has been correctly populated + """ + with self.subTest(msg='node: msk_top_regs.Hash_ID_Low'): + self.assertEqual(self.dut.Hash_ID_Low.inst_name, 'Hash_ID_Low') # type: ignore[union-attr] + self.assertEqual(self.dut.Hash_ID_Low.full_inst_name, 'msk_top_regs.Hash_ID_Low') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.Hash_ID_High'): + self.assertEqual(self.dut.Hash_ID_High.inst_name, 'Hash_ID_High') # type: ignore[union-attr] + self.assertEqual(self.dut.Hash_ID_High.full_inst_name, 'msk_top_regs.Hash_ID_High') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.MSK_Init'): + self.assertEqual(self.dut.MSK_Init.inst_name, 'MSK_Init') # type: ignore[union-attr] + self.assertEqual(self.dut.MSK_Init.full_inst_name, 'msk_top_regs.MSK_Init') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.MSK_Control'): + self.assertEqual(self.dut.MSK_Control.inst_name, 'MSK_Control') # type: ignore[union-attr] + self.assertEqual(self.dut.MSK_Control.full_inst_name, 'msk_top_regs.MSK_Control') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.MSK_Status'): + self.assertEqual(self.dut.MSK_Status.inst_name, 'MSK_Status') # type: ignore[union-attr] + self.assertEqual(self.dut.MSK_Status.full_inst_name, 'msk_top_regs.MSK_Status') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.Tx_Bit_Count'): + self.assertEqual(self.dut.Tx_Bit_Count.inst_name, 'Tx_Bit_Count') # type: ignore[union-attr] + self.assertEqual(self.dut.Tx_Bit_Count.full_inst_name, 'msk_top_regs.Tx_Bit_Count') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.Tx_Enable_Count'): + self.assertEqual(self.dut.Tx_Enable_Count.inst_name, 'Tx_Enable_Count') # type: ignore[union-attr] + self.assertEqual(self.dut.Tx_Enable_Count.full_inst_name, 'msk_top_regs.Tx_Enable_Count') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.Fb_FreqWord'): + self.assertEqual(self.dut.Fb_FreqWord.inst_name, 'Fb_FreqWord') # type: ignore[union-attr] + self.assertEqual(self.dut.Fb_FreqWord.full_inst_name, 'msk_top_regs.Fb_FreqWord') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.TX_F1_FreqWord'): + self.assertEqual(self.dut.TX_F1_FreqWord.inst_name, 'TX_F1_FreqWord') # type: ignore[union-attr] + self.assertEqual(self.dut.TX_F1_FreqWord.full_inst_name, 'msk_top_regs.TX_F1_FreqWord') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.TX_F2_FreqWord'): + self.assertEqual(self.dut.TX_F2_FreqWord.inst_name, 'TX_F2_FreqWord') # type: ignore[union-attr] + self.assertEqual(self.dut.TX_F2_FreqWord.full_inst_name, 'msk_top_regs.TX_F2_FreqWord') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.RX_F1_FreqWord'): + self.assertEqual(self.dut.RX_F1_FreqWord.inst_name, 'RX_F1_FreqWord') # type: ignore[union-attr] + self.assertEqual(self.dut.RX_F1_FreqWord.full_inst_name, 'msk_top_regs.RX_F1_FreqWord') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.RX_F2_FreqWord'): + self.assertEqual(self.dut.RX_F2_FreqWord.inst_name, 'RX_F2_FreqWord') # type: ignore[union-attr] + self.assertEqual(self.dut.RX_F2_FreqWord.full_inst_name, 'msk_top_regs.RX_F2_FreqWord') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.LPF_Config_0'): + self.assertEqual(self.dut.LPF_Config_0.inst_name, 'LPF_Config_0') # type: ignore[union-attr] + self.assertEqual(self.dut.LPF_Config_0.full_inst_name, 'msk_top_regs.LPF_Config_0') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.LPF_Config_1'): + self.assertEqual(self.dut.LPF_Config_1.inst_name, 'LPF_Config_1') # type: ignore[union-attr] + self.assertEqual(self.dut.LPF_Config_1.full_inst_name, 'msk_top_regs.LPF_Config_1') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.Tx_Data_Width'): + self.assertEqual(self.dut.Tx_Data_Width.inst_name, 'Tx_Data_Width') # type: ignore[union-attr] + self.assertEqual(self.dut.Tx_Data_Width.full_inst_name, 'msk_top_regs.Tx_Data_Width') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.Rx_Data_Width'): + self.assertEqual(self.dut.Rx_Data_Width.inst_name, 'Rx_Data_Width') # type: ignore[union-attr] + self.assertEqual(self.dut.Rx_Data_Width.full_inst_name, 'msk_top_regs.Rx_Data_Width') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Control'): + self.assertEqual(self.dut.PRBS_Control.inst_name, 'PRBS_Control') # type: ignore[union-attr] + self.assertEqual(self.dut.PRBS_Control.full_inst_name, 'msk_top_regs.PRBS_Control') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Initial_State'): + self.assertEqual(self.dut.PRBS_Initial_State.inst_name, 'PRBS_Initial_State') # type: ignore[union-attr] + self.assertEqual(self.dut.PRBS_Initial_State.full_inst_name, 'msk_top_regs.PRBS_Initial_State') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Polynomial'): + self.assertEqual(self.dut.PRBS_Polynomial.inst_name, 'PRBS_Polynomial') # type: ignore[union-attr] + self.assertEqual(self.dut.PRBS_Polynomial.full_inst_name, 'msk_top_regs.PRBS_Polynomial') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Error_Mask'): + self.assertEqual(self.dut.PRBS_Error_Mask.inst_name, 'PRBS_Error_Mask') # type: ignore[union-attr] + self.assertEqual(self.dut.PRBS_Error_Mask.full_inst_name, 'msk_top_regs.PRBS_Error_Mask') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Bit_Count'): + self.assertEqual(self.dut.PRBS_Bit_Count.inst_name, 'PRBS_Bit_Count') # type: ignore[union-attr] + self.assertEqual(self.dut.PRBS_Bit_Count.full_inst_name, 'msk_top_regs.PRBS_Bit_Count') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Error_Count'): + self.assertEqual(self.dut.PRBS_Error_Count.inst_name, 'PRBS_Error_Count') # type: ignore[union-attr] + self.assertEqual(self.dut.PRBS_Error_Count.full_inst_name, 'msk_top_regs.PRBS_Error_Count') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.LPF_Accum_F1'): + self.assertEqual(self.dut.LPF_Accum_F1.inst_name, 'LPF_Accum_F1') # type: ignore[union-attr] + self.assertEqual(self.dut.LPF_Accum_F1.full_inst_name, 'msk_top_regs.LPF_Accum_F1') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.LPF_Accum_F2'): + self.assertEqual(self.dut.LPF_Accum_F2.inst_name, 'LPF_Accum_F2') # type: ignore[union-attr] + self.assertEqual(self.dut.LPF_Accum_F2.full_inst_name, 'msk_top_regs.LPF_Accum_F2') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.axis_xfer_count'): + self.assertEqual(self.dut.axis_xfer_count.inst_name, 'axis_xfer_count') # type: ignore[union-attr] + self.assertEqual(self.dut.axis_xfer_count.full_inst_name, 'msk_top_regs.axis_xfer_count') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.Rx_Sample_Discard'): + self.assertEqual(self.dut.Rx_Sample_Discard.inst_name, 'Rx_Sample_Discard') # type: ignore[union-attr] + self.assertEqual(self.dut.Rx_Sample_Discard.full_inst_name, 'msk_top_regs.Rx_Sample_Discard') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.LPF_Config_2'): + self.assertEqual(self.dut.LPF_Config_2.inst_name, 'LPF_Config_2') # type: ignore[union-attr] + self.assertEqual(self.dut.LPF_Config_2.full_inst_name, 'msk_top_regs.LPF_Config_2') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.f1_nco_adjust'): + self.assertEqual(self.dut.f1_nco_adjust.inst_name, 'f1_nco_adjust') # type: ignore[union-attr] + self.assertEqual(self.dut.f1_nco_adjust.full_inst_name, 'msk_top_regs.f1_nco_adjust') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.f2_nco_adjust'): + self.assertEqual(self.dut.f2_nco_adjust.inst_name, 'f2_nco_adjust') # type: ignore[union-attr] + self.assertEqual(self.dut.f2_nco_adjust.full_inst_name, 'msk_top_regs.f2_nco_adjust') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.f1_error'): + self.assertEqual(self.dut.f1_error.inst_name, 'f1_error') # type: ignore[union-attr] + self.assertEqual(self.dut.f1_error.full_inst_name, 'msk_top_regs.f1_error') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.f2_error'): + self.assertEqual(self.dut.f2_error.inst_name, 'f2_error') # type: ignore[union-attr] + self.assertEqual(self.dut.f2_error.full_inst_name, 'msk_top_regs.f2_error') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.Tx_Sync_Ctrl'): + self.assertEqual(self.dut.Tx_Sync_Ctrl.inst_name, 'Tx_Sync_Ctrl') # type: ignore[union-attr] + self.assertEqual(self.dut.Tx_Sync_Ctrl.full_inst_name, 'msk_top_regs.Tx_Sync_Ctrl') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.Tx_Sync_Cnt'): + self.assertEqual(self.dut.Tx_Sync_Cnt.inst_name, 'Tx_Sync_Cnt') # type: ignore[union-attr] + self.assertEqual(self.dut.Tx_Sync_Cnt.full_inst_name, 'msk_top_regs.Tx_Sync_Cnt') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.lowpass_ema_alpha1'): + self.assertEqual(self.dut.lowpass_ema_alpha1.inst_name, 'lowpass_ema_alpha1') # type: ignore[union-attr] + self.assertEqual(self.dut.lowpass_ema_alpha1.full_inst_name, 'msk_top_regs.lowpass_ema_alpha1') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.lowpass_ema_alpha2'): + self.assertEqual(self.dut.lowpass_ema_alpha2.inst_name, 'lowpass_ema_alpha2') # type: ignore[union-attr] + self.assertEqual(self.dut.lowpass_ema_alpha2.full_inst_name, 'msk_top_regs.lowpass_ema_alpha2') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.rx_power'): + self.assertEqual(self.dut.rx_power.inst_name, 'rx_power') # type: ignore[union-attr] + self.assertEqual(self.dut.rx_power.full_inst_name, 'msk_top_regs.rx_power') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.tx_async_fifo_rd_wr_ptr'): + self.assertEqual(self.dut.tx_async_fifo_rd_wr_ptr.inst_name, 'tx_async_fifo_rd_wr_ptr') # type: ignore[union-attr] + self.assertEqual(self.dut.tx_async_fifo_rd_wr_ptr.full_inst_name, 'msk_top_regs.tx_async_fifo_rd_wr_ptr') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.rx_async_fifo_rd_wr_ptr'): + self.assertEqual(self.dut.rx_async_fifo_rd_wr_ptr.inst_name, 'rx_async_fifo_rd_wr_ptr') # type: ignore[union-attr] + self.assertEqual(self.dut.rx_async_fifo_rd_wr_ptr.full_inst_name, 'msk_top_regs.rx_async_fifo_rd_wr_ptr') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.rx_frame_sync_status'): + self.assertEqual(self.dut.rx_frame_sync_status.inst_name, 'rx_frame_sync_status') # type: ignore[union-attr] + self.assertEqual(self.dut.rx_frame_sync_status.full_inst_name, 'msk_top_regs.rx_frame_sync_status') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.Hash_ID_Low.hash_id_lo'): + self.assertEqual(self.dut.Hash_ID_Low.hash_id_lo.inst_name, 'hash_id_lo') # type: ignore[union-attr] + self.assertEqual(self.dut.Hash_ID_Low.hash_id_lo.full_inst_name, 'msk_top_regs.Hash_ID_Low.hash_id_lo') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.Hash_ID_High.hash_id_hi'): + self.assertEqual(self.dut.Hash_ID_High.hash_id_hi.inst_name, 'hash_id_hi') # type: ignore[union-attr] + self.assertEqual(self.dut.Hash_ID_High.hash_id_hi.full_inst_name, 'msk_top_regs.Hash_ID_High.hash_id_hi') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.MSK_Init.txrxinit'): + self.assertEqual(self.dut.MSK_Init.txrxinit.inst_name, 'txrxinit') # type: ignore[union-attr] + self.assertEqual(self.dut.MSK_Init.txrxinit.full_inst_name, 'msk_top_regs.MSK_Init.txrxinit') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.MSK_Init.txinit'): + self.assertEqual(self.dut.MSK_Init.txinit.inst_name, 'txinit') # type: ignore[union-attr] + self.assertEqual(self.dut.MSK_Init.txinit.full_inst_name, 'msk_top_regs.MSK_Init.txinit') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.MSK_Init.rxinit'): + self.assertEqual(self.dut.MSK_Init.rxinit.inst_name, 'rxinit') # type: ignore[union-attr] + self.assertEqual(self.dut.MSK_Init.rxinit.full_inst_name, 'msk_top_regs.MSK_Init.rxinit') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.MSK_Control.ptt'): + self.assertEqual(self.dut.MSK_Control.ptt.inst_name, 'ptt') # type: ignore[union-attr] + self.assertEqual(self.dut.MSK_Control.ptt.full_inst_name, 'msk_top_regs.MSK_Control.ptt') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.MSK_Control.loopback_ena'): + self.assertEqual(self.dut.MSK_Control.loopback_ena.inst_name, 'loopback_ena') # type: ignore[union-attr] + self.assertEqual(self.dut.MSK_Control.loopback_ena.full_inst_name, 'msk_top_regs.MSK_Control.loopback_ena') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.MSK_Control.rx_invert'): + self.assertEqual(self.dut.MSK_Control.rx_invert.inst_name, 'rx_invert') # type: ignore[union-attr] + self.assertEqual(self.dut.MSK_Control.rx_invert.full_inst_name, 'msk_top_regs.MSK_Control.rx_invert') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.MSK_Control.clear_counts'): + self.assertEqual(self.dut.MSK_Control.clear_counts.inst_name, 'clear_counts') # type: ignore[union-attr] + self.assertEqual(self.dut.MSK_Control.clear_counts.full_inst_name, 'msk_top_regs.MSK_Control.clear_counts') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.MSK_Control.diff_encoder_loopback'): + self.assertEqual(self.dut.MSK_Control.diff_encoder_loopback.inst_name, 'diff_encoder_loopback') # type: ignore[union-attr] + self.assertEqual(self.dut.MSK_Control.diff_encoder_loopback.full_inst_name, 'msk_top_regs.MSK_Control.diff_encoder_loopback') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.MSK_Status.demod_sync_lock'): + self.assertEqual(self.dut.MSK_Status.demod_sync_lock.inst_name, 'demod_sync_lock') # type: ignore[union-attr] + self.assertEqual(self.dut.MSK_Status.demod_sync_lock.full_inst_name, 'msk_top_regs.MSK_Status.demod_sync_lock') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.MSK_Status.tx_enable'): + self.assertEqual(self.dut.MSK_Status.tx_enable.inst_name, 'tx_enable') # type: ignore[union-attr] + self.assertEqual(self.dut.MSK_Status.tx_enable.full_inst_name, 'msk_top_regs.MSK_Status.tx_enable') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.MSK_Status.rx_enable'): + self.assertEqual(self.dut.MSK_Status.rx_enable.inst_name, 'rx_enable') # type: ignore[union-attr] + self.assertEqual(self.dut.MSK_Status.rx_enable.full_inst_name, 'msk_top_regs.MSK_Status.rx_enable') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.MSK_Status.tx_axis_valid'): + self.assertEqual(self.dut.MSK_Status.tx_axis_valid.inst_name, 'tx_axis_valid') # type: ignore[union-attr] + self.assertEqual(self.dut.MSK_Status.tx_axis_valid.full_inst_name, 'msk_top_regs.MSK_Status.tx_axis_valid') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.Tx_Bit_Count.data'): + self.assertEqual(self.dut.Tx_Bit_Count.data.inst_name, 'data') # type: ignore[union-attr] + self.assertEqual(self.dut.Tx_Bit_Count.data.full_inst_name, 'msk_top_regs.Tx_Bit_Count.data') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.Tx_Enable_Count.data'): + self.assertEqual(self.dut.Tx_Enable_Count.data.inst_name, 'data') # type: ignore[union-attr] + self.assertEqual(self.dut.Tx_Enable_Count.data.full_inst_name, 'msk_top_regs.Tx_Enable_Count.data') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.Fb_FreqWord.config_data'): + self.assertEqual(self.dut.Fb_FreqWord.config_data.inst_name, 'config_data') # type: ignore[union-attr] + self.assertEqual(self.dut.Fb_FreqWord.config_data.full_inst_name, 'msk_top_regs.Fb_FreqWord.config_data') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.TX_F1_FreqWord.config_data'): + self.assertEqual(self.dut.TX_F1_FreqWord.config_data.inst_name, 'config_data') # type: ignore[union-attr] + self.assertEqual(self.dut.TX_F1_FreqWord.config_data.full_inst_name, 'msk_top_regs.TX_F1_FreqWord.config_data') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.TX_F2_FreqWord.config_data'): + self.assertEqual(self.dut.TX_F2_FreqWord.config_data.inst_name, 'config_data') # type: ignore[union-attr] + self.assertEqual(self.dut.TX_F2_FreqWord.config_data.full_inst_name, 'msk_top_regs.TX_F2_FreqWord.config_data') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.RX_F1_FreqWord.config_data'): + self.assertEqual(self.dut.RX_F1_FreqWord.config_data.inst_name, 'config_data') # type: ignore[union-attr] + self.assertEqual(self.dut.RX_F1_FreqWord.config_data.full_inst_name, 'msk_top_regs.RX_F1_FreqWord.config_data') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.RX_F2_FreqWord.config_data'): + self.assertEqual(self.dut.RX_F2_FreqWord.config_data.inst_name, 'config_data') # type: ignore[union-attr] + self.assertEqual(self.dut.RX_F2_FreqWord.config_data.full_inst_name, 'msk_top_regs.RX_F2_FreqWord.config_data') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.LPF_Config_0.lpf_freeze'): + self.assertEqual(self.dut.LPF_Config_0.lpf_freeze.inst_name, 'lpf_freeze') # type: ignore[union-attr] + self.assertEqual(self.dut.LPF_Config_0.lpf_freeze.full_inst_name, 'msk_top_regs.LPF_Config_0.lpf_freeze') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.LPF_Config_0.lpf_zero'): + self.assertEqual(self.dut.LPF_Config_0.lpf_zero.inst_name, 'lpf_zero') # type: ignore[union-attr] + self.assertEqual(self.dut.LPF_Config_0.lpf_zero.full_inst_name, 'msk_top_regs.LPF_Config_0.lpf_zero') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.LPF_Config_0.prbs_reserved'): + self.assertEqual(self.dut.LPF_Config_0.prbs_reserved.inst_name, 'prbs_reserved') # type: ignore[union-attr] + self.assertEqual(self.dut.LPF_Config_0.prbs_reserved.full_inst_name, 'msk_top_regs.LPF_Config_0.prbs_reserved') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.LPF_Config_0.lpf_alpha'): + self.assertEqual(self.dut.LPF_Config_0.lpf_alpha.inst_name, 'lpf_alpha') # type: ignore[union-attr] + self.assertEqual(self.dut.LPF_Config_0.lpf_alpha.full_inst_name, 'msk_top_regs.LPF_Config_0.lpf_alpha') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.LPF_Config_1.i_gain'): + self.assertEqual(self.dut.LPF_Config_1.i_gain.inst_name, 'i_gain') # type: ignore[union-attr] + self.assertEqual(self.dut.LPF_Config_1.i_gain.full_inst_name, 'msk_top_regs.LPF_Config_1.i_gain') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.LPF_Config_1.i_shift'): + self.assertEqual(self.dut.LPF_Config_1.i_shift.inst_name, 'i_shift') # type: ignore[union-attr] + self.assertEqual(self.dut.LPF_Config_1.i_shift.full_inst_name, 'msk_top_regs.LPF_Config_1.i_shift') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.Tx_Data_Width.data_width'): + self.assertEqual(self.dut.Tx_Data_Width.data_width.inst_name, 'data_width') # type: ignore[union-attr] + self.assertEqual(self.dut.Tx_Data_Width.data_width.full_inst_name, 'msk_top_regs.Tx_Data_Width.data_width') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.Rx_Data_Width.data_width'): + self.assertEqual(self.dut.Rx_Data_Width.data_width.inst_name, 'data_width') # type: ignore[union-attr] + self.assertEqual(self.dut.Rx_Data_Width.data_width.full_inst_name, 'msk_top_regs.Rx_Data_Width.data_width') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Control.prbs_sel'): + self.assertEqual(self.dut.PRBS_Control.prbs_sel.inst_name, 'prbs_sel') # type: ignore[union-attr] + self.assertEqual(self.dut.PRBS_Control.prbs_sel.full_inst_name, 'msk_top_regs.PRBS_Control.prbs_sel') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Control.prbs_error_insert'): + self.assertEqual(self.dut.PRBS_Control.prbs_error_insert.inst_name, 'prbs_error_insert') # type: ignore[union-attr] + self.assertEqual(self.dut.PRBS_Control.prbs_error_insert.full_inst_name, 'msk_top_regs.PRBS_Control.prbs_error_insert') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Control.prbs_clear'): + self.assertEqual(self.dut.PRBS_Control.prbs_clear.inst_name, 'prbs_clear') # type: ignore[union-attr] + self.assertEqual(self.dut.PRBS_Control.prbs_clear.full_inst_name, 'msk_top_regs.PRBS_Control.prbs_clear') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Control.prbs_manual_sync'): + self.assertEqual(self.dut.PRBS_Control.prbs_manual_sync.inst_name, 'prbs_manual_sync') # type: ignore[union-attr] + self.assertEqual(self.dut.PRBS_Control.prbs_manual_sync.full_inst_name, 'msk_top_regs.PRBS_Control.prbs_manual_sync') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Control.prbs_reserved'): + self.assertEqual(self.dut.PRBS_Control.prbs_reserved.inst_name, 'prbs_reserved') # type: ignore[union-attr] + self.assertEqual(self.dut.PRBS_Control.prbs_reserved.full_inst_name, 'msk_top_regs.PRBS_Control.prbs_reserved') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Control.prbs_sync_threshold'): + self.assertEqual(self.dut.PRBS_Control.prbs_sync_threshold.inst_name, 'prbs_sync_threshold') # type: ignore[union-attr] + self.assertEqual(self.dut.PRBS_Control.prbs_sync_threshold.full_inst_name, 'msk_top_regs.PRBS_Control.prbs_sync_threshold') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Initial_State.config_data'): + self.assertEqual(self.dut.PRBS_Initial_State.config_data.inst_name, 'config_data') # type: ignore[union-attr] + self.assertEqual(self.dut.PRBS_Initial_State.config_data.full_inst_name, 'msk_top_regs.PRBS_Initial_State.config_data') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Polynomial.config_data'): + self.assertEqual(self.dut.PRBS_Polynomial.config_data.inst_name, 'config_data') # type: ignore[union-attr] + self.assertEqual(self.dut.PRBS_Polynomial.config_data.full_inst_name, 'msk_top_regs.PRBS_Polynomial.config_data') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Error_Mask.config_data'): + self.assertEqual(self.dut.PRBS_Error_Mask.config_data.inst_name, 'config_data') # type: ignore[union-attr] + self.assertEqual(self.dut.PRBS_Error_Mask.config_data.full_inst_name, 'msk_top_regs.PRBS_Error_Mask.config_data') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Bit_Count.data'): + self.assertEqual(self.dut.PRBS_Bit_Count.data.inst_name, 'data') # type: ignore[union-attr] + self.assertEqual(self.dut.PRBS_Bit_Count.data.full_inst_name, 'msk_top_regs.PRBS_Bit_Count.data') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Error_Count.data'): + self.assertEqual(self.dut.PRBS_Error_Count.data.inst_name, 'data') # type: ignore[union-attr] + self.assertEqual(self.dut.PRBS_Error_Count.data.full_inst_name, 'msk_top_regs.PRBS_Error_Count.data') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.LPF_Accum_F1.data'): + self.assertEqual(self.dut.LPF_Accum_F1.data.inst_name, 'data') # type: ignore[union-attr] + self.assertEqual(self.dut.LPF_Accum_F1.data.full_inst_name, 'msk_top_regs.LPF_Accum_F1.data') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.LPF_Accum_F2.data'): + self.assertEqual(self.dut.LPF_Accum_F2.data.inst_name, 'data') # type: ignore[union-attr] + self.assertEqual(self.dut.LPF_Accum_F2.data.full_inst_name, 'msk_top_regs.LPF_Accum_F2.data') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.axis_xfer_count.data'): + self.assertEqual(self.dut.axis_xfer_count.data.inst_name, 'data') # type: ignore[union-attr] + self.assertEqual(self.dut.axis_xfer_count.data.full_inst_name, 'msk_top_regs.axis_xfer_count.data') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.Rx_Sample_Discard.rx_sample_discard'): + self.assertEqual(self.dut.Rx_Sample_Discard.rx_sample_discard.inst_name, 'rx_sample_discard') # type: ignore[union-attr] + self.assertEqual(self.dut.Rx_Sample_Discard.rx_sample_discard.full_inst_name, 'msk_top_regs.Rx_Sample_Discard.rx_sample_discard') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.Rx_Sample_Discard.rx_nco_discard'): + self.assertEqual(self.dut.Rx_Sample_Discard.rx_nco_discard.inst_name, 'rx_nco_discard') # type: ignore[union-attr] + self.assertEqual(self.dut.Rx_Sample_Discard.rx_nco_discard.full_inst_name, 'msk_top_regs.Rx_Sample_Discard.rx_nco_discard') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.LPF_Config_2.p_gain'): + self.assertEqual(self.dut.LPF_Config_2.p_gain.inst_name, 'p_gain') # type: ignore[union-attr] + self.assertEqual(self.dut.LPF_Config_2.p_gain.full_inst_name, 'msk_top_regs.LPF_Config_2.p_gain') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.LPF_Config_2.p_shift'): + self.assertEqual(self.dut.LPF_Config_2.p_shift.inst_name, 'p_shift') # type: ignore[union-attr] + self.assertEqual(self.dut.LPF_Config_2.p_shift.full_inst_name, 'msk_top_regs.LPF_Config_2.p_shift') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.f1_nco_adjust.data'): + self.assertEqual(self.dut.f1_nco_adjust.data.inst_name, 'data') # type: ignore[union-attr] + self.assertEqual(self.dut.f1_nco_adjust.data.full_inst_name, 'msk_top_regs.f1_nco_adjust.data') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.f2_nco_adjust.data'): + self.assertEqual(self.dut.f2_nco_adjust.data.inst_name, 'data') # type: ignore[union-attr] + self.assertEqual(self.dut.f2_nco_adjust.data.full_inst_name, 'msk_top_regs.f2_nco_adjust.data') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.f1_error.data'): + self.assertEqual(self.dut.f1_error.data.inst_name, 'data') # type: ignore[union-attr] + self.assertEqual(self.dut.f1_error.data.full_inst_name, 'msk_top_regs.f1_error.data') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.f2_error.data'): + self.assertEqual(self.dut.f2_error.data.inst_name, 'data') # type: ignore[union-attr] + self.assertEqual(self.dut.f2_error.data.full_inst_name, 'msk_top_regs.f2_error.data') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.Tx_Sync_Ctrl.tx_sync_ena'): + self.assertEqual(self.dut.Tx_Sync_Ctrl.tx_sync_ena.inst_name, 'tx_sync_ena') # type: ignore[union-attr] + self.assertEqual(self.dut.Tx_Sync_Ctrl.tx_sync_ena.full_inst_name, 'msk_top_regs.Tx_Sync_Ctrl.tx_sync_ena') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.Tx_Sync_Ctrl.tx_sync_force'): + self.assertEqual(self.dut.Tx_Sync_Ctrl.tx_sync_force.inst_name, 'tx_sync_force') # type: ignore[union-attr] + self.assertEqual(self.dut.Tx_Sync_Ctrl.tx_sync_force.full_inst_name, 'msk_top_regs.Tx_Sync_Ctrl.tx_sync_force') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.Tx_Sync_Cnt.tx_sync_cnt'): + self.assertEqual(self.dut.Tx_Sync_Cnt.tx_sync_cnt.inst_name, 'tx_sync_cnt') # type: ignore[union-attr] + self.assertEqual(self.dut.Tx_Sync_Cnt.tx_sync_cnt.full_inst_name, 'msk_top_regs.Tx_Sync_Cnt.tx_sync_cnt') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.lowpass_ema_alpha1.alpha'): + self.assertEqual(self.dut.lowpass_ema_alpha1.alpha.inst_name, 'alpha') # type: ignore[union-attr] + self.assertEqual(self.dut.lowpass_ema_alpha1.alpha.full_inst_name, 'msk_top_regs.lowpass_ema_alpha1.alpha') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.lowpass_ema_alpha2.alpha'): + self.assertEqual(self.dut.lowpass_ema_alpha2.alpha.inst_name, 'alpha') # type: ignore[union-attr] + self.assertEqual(self.dut.lowpass_ema_alpha2.alpha.full_inst_name, 'msk_top_regs.lowpass_ema_alpha2.alpha') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.rx_power.data'): + self.assertEqual(self.dut.rx_power.data.inst_name, 'data') # type: ignore[union-attr] + self.assertEqual(self.dut.rx_power.data.full_inst_name, 'msk_top_regs.rx_power.data') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.tx_async_fifo_rd_wr_ptr.data'): + self.assertEqual(self.dut.tx_async_fifo_rd_wr_ptr.data.inst_name, 'data') # type: ignore[union-attr] + self.assertEqual(self.dut.tx_async_fifo_rd_wr_ptr.data.full_inst_name, 'msk_top_regs.tx_async_fifo_rd_wr_ptr.data') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.rx_async_fifo_rd_wr_ptr.data'): + self.assertEqual(self.dut.rx_async_fifo_rd_wr_ptr.data.inst_name, 'data') # type: ignore[union-attr] + self.assertEqual(self.dut.rx_async_fifo_rd_wr_ptr.data.full_inst_name, 'msk_top_regs.rx_async_fifo_rd_wr_ptr.data') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.rx_frame_sync_status.frame_sync_locked'): + self.assertEqual(self.dut.rx_frame_sync_status.frame_sync_locked.inst_name, 'frame_sync_locked') # type: ignore[union-attr] + self.assertEqual(self.dut.rx_frame_sync_status.frame_sync_locked.full_inst_name, 'msk_top_regs.rx_frame_sync_status.frame_sync_locked') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.rx_frame_sync_status.frame_buffer_overflow'): + self.assertEqual(self.dut.rx_frame_sync_status.frame_buffer_overflow.inst_name, 'frame_buffer_overflow') # type: ignore[union-attr] + self.assertEqual(self.dut.rx_frame_sync_status.frame_buffer_overflow.full_inst_name, 'msk_top_regs.rx_frame_sync_status.frame_buffer_overflow') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.rx_frame_sync_status.frames_received'): + self.assertEqual(self.dut.rx_frame_sync_status.frames_received.inst_name, 'frames_received') # type: ignore[union-attr] + self.assertEqual(self.dut.rx_frame_sync_status.frames_received.full_inst_name, 'msk_top_regs.rx_frame_sync_status.frames_received') # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.rx_frame_sync_status.frame_sync_errors'): + self.assertEqual(self.dut.rx_frame_sync_status.frame_sync_errors.inst_name, 'frame_sync_errors') # type: ignore[union-attr] + self.assertEqual(self.dut.rx_frame_sync_status.frame_sync_errors.full_inst_name, 'msk_top_regs.rx_frame_sync_status.frame_sync_errors') # type: ignore[union-attr] + + + def test_name_property(self) -> None: + """ + Walk the address map and check the name property has been correctly populated + """ + with self.subTest(msg='node: msk_top_regs.Hash_ID_Low'): + + + self.assertEqual(self.dut.Hash_ID_Low.rdl_name, "Pluto MSK FPGA Hash ID - Lower 32-bits") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Hash_ID_High'): + + + self.assertEqual(self.dut.Hash_ID_High.rdl_name, "Pluto MSK FPGA Hash ID - Upper 32-bits") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.MSK_Init'): + + + self.assertEqual(self.dut.MSK_Init.rdl_name, "MSK Modem Initialization Control") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.MSK_Control'): + + + self.assertEqual(self.dut.MSK_Control.rdl_name, "MSK Modem Control") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.MSK_Status'): + + + self.assertEqual(self.dut.MSK_Status.rdl_name, "MSK Modem Status 0") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Tx_Bit_Count'): + + + self.assertEqual(self.dut.Tx_Bit_Count.rdl_name, "MSK Modem Status 1") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Tx_Enable_Count'): + + + self.assertEqual(self.dut.Tx_Enable_Count.rdl_name, "MSK Modem Status 2") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Fb_FreqWord'): + + + self.assertEqual(self.dut.Fb_FreqWord.rdl_name, "Bitrate NCO Frequency Control Word") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.TX_F1_FreqWord'): + + + self.assertEqual(self.dut.TX_F1_FreqWord.rdl_name, "Tx F1 NCO Frequency Control Word") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.TX_F2_FreqWord'): + + + self.assertEqual(self.dut.TX_F2_FreqWord.rdl_name, "Tx F2 NCO Frequency Control Word") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.RX_F1_FreqWord'): + + + self.assertEqual(self.dut.RX_F1_FreqWord.rdl_name, "Rx F1 NCO Frequency Control Word") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.RX_F2_FreqWord'): + + + self.assertEqual(self.dut.RX_F2_FreqWord.rdl_name, "Rx F2 NCO Frequency Control Word") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.LPF_Config_0'): + + + self.assertEqual(self.dut.LPF_Config_0.rdl_name, "PI Controller Configuration and Low-pass Filter Configuration") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.LPF_Config_1'): + + + self.assertEqual(self.dut.LPF_Config_1.rdl_name, "PI Controller Configuration Configuration Register 1") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Tx_Data_Width'): + + + self.assertEqual(self.dut.Tx_Data_Width.rdl_name, "Modem Tx Input Data Width") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Rx_Data_Width'): + + + self.assertEqual(self.dut.Rx_Data_Width.rdl_name, "Modem Rx Output Data Width") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.PRBS_Control'): + + + self.assertEqual(self.dut.PRBS_Control.rdl_name, "PRBS Control 0") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.PRBS_Initial_State'): + + + self.assertEqual(self.dut.PRBS_Initial_State.rdl_name, "PRBS Control 1") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.PRBS_Polynomial'): + + + self.assertEqual(self.dut.PRBS_Polynomial.rdl_name, "PRBS Control 2") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.PRBS_Error_Mask'): + + + self.assertEqual(self.dut.PRBS_Error_Mask.rdl_name, "PRBS Control 3") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.PRBS_Bit_Count'): + + + self.assertEqual(self.dut.PRBS_Bit_Count.rdl_name, "PRBS Status 0") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.PRBS_Error_Count'): + + + self.assertEqual(self.dut.PRBS_Error_Count.rdl_name, "PRBS Status 1") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.LPF_Accum_F1'): + + + self.assertEqual(self.dut.LPF_Accum_F1.rdl_name, "F1 PI Controller Accumulator") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.LPF_Accum_F2'): + + + self.assertEqual(self.dut.LPF_Accum_F2.rdl_name, "F2 PI Controller Accumulator") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.axis_xfer_count'): + + + self.assertEqual(self.dut.axis_xfer_count.rdl_name, "MSK Modem Status 3") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Rx_Sample_Discard'): + + + self.assertEqual(self.dut.Rx_Sample_Discard.rdl_name, "Rx Sample Discard") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.LPF_Config_2'): + + + self.assertEqual(self.dut.LPF_Config_2.rdl_name, "PI Controller Configuration Configuration Register 2") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.f1_nco_adjust'): + + + self.assertEqual(self.dut.f1_nco_adjust.rdl_name, "F1 NCO Frequency Adjust") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.f2_nco_adjust'): + + + self.assertEqual(self.dut.f2_nco_adjust.rdl_name, "F2 NCO Frequency Adjust") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.f1_error'): + + + self.assertEqual(self.dut.f1_error.rdl_name, "F1 Error Value") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.f2_error'): + + + self.assertEqual(self.dut.f2_error.rdl_name, "F2 Error Value") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Tx_Sync_Ctrl'): + + + self.assertEqual(self.dut.Tx_Sync_Ctrl.rdl_name, "Transmitter Sync Control") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Tx_Sync_Cnt'): + + + self.assertEqual(self.dut.Tx_Sync_Cnt.rdl_name, "Transmitter Sync Duration") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.lowpass_ema_alpha1'): + + + self.assertEqual(self.dut.lowpass_ema_alpha1.rdl_name, "Exponential Moving Average Alpha") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.lowpass_ema_alpha2'): + + + self.assertEqual(self.dut.lowpass_ema_alpha2.rdl_name, "Exponential Moving Average Alpha") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.rx_power'): + + + self.assertEqual(self.dut.rx_power.rdl_name, "Receive Power") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.tx_async_fifo_rd_wr_ptr'): + + + self.assertEqual(self.dut.tx_async_fifo_rd_wr_ptr.rdl_name, "Tx async FIFO read and write pointers") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.rx_async_fifo_rd_wr_ptr'): + + + self.assertEqual(self.dut.rx_async_fifo_rd_wr_ptr.rdl_name, "Rx async FIFO read and write pointers") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.rx_frame_sync_status'): + + + self.assertEqual(self.dut.rx_frame_sync_status.rdl_name, "Frame Sync Status") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Hash_ID_Low.hash_id_lo'): + + + self.assertEqual(self.dut.Hash_ID_Low.hash_id_lo.rdl_name, "Hash ID Lower 32-bits") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Hash_ID_High.hash_id_hi'): + + + self.assertEqual(self.dut.Hash_ID_High.hash_id_hi.rdl_name, "Hash ID Upper 32-bits") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.MSK_Init.txrxinit'): + + + self.assertEqual(self.dut.MSK_Init.txrxinit.rdl_name, "Tx/Rx Init Enable") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.MSK_Init.txinit'): + + + self.assertEqual(self.dut.MSK_Init.txinit.rdl_name, "Tx Init Enable") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.MSK_Init.rxinit'): + + + self.assertEqual(self.dut.MSK_Init.rxinit.rdl_name, "Rx Init Enable") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.MSK_Control.ptt'): + + + self.assertEqual(self.dut.MSK_Control.ptt.rdl_name, "Push-to-Talk Enable") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.MSK_Control.loopback_ena'): + + + self.assertEqual(self.dut.MSK_Control.loopback_ena.rdl_name, "Modem Digital Tx -\u003e Rx Loopback Enable") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.MSK_Control.rx_invert'): + + + self.assertEqual(self.dut.MSK_Control.rx_invert.rdl_name, "Rx Data Invert Enable") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.MSK_Control.clear_counts'): + + + self.assertEqual(self.dut.MSK_Control.clear_counts.rdl_name, "Clear Status Counters") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.MSK_Control.diff_encoder_loopback'): + + + self.assertEqual(self.dut.MSK_Control.diff_encoder_loopback.rdl_name, "Differential Encoder -\u003e Decoder Loopback Enable") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.MSK_Status.demod_sync_lock'): + + + self.assertEqual(self.dut.MSK_Status.demod_sync_lock.rdl_name, "Demodulator Sync Status") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.MSK_Status.tx_enable'): + + + self.assertEqual(self.dut.MSK_Status.tx_enable.rdl_name, "AD9363 DAC Interface Tx Enable Input Active") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.MSK_Status.rx_enable'): + + + self.assertEqual(self.dut.MSK_Status.rx_enable.rdl_name, "AD9363 ADC Interface Rx Enable Input Active") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.MSK_Status.tx_axis_valid'): + + + self.assertEqual(self.dut.MSK_Status.tx_axis_valid.rdl_name, "Tx S_AXIS_VALID") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Tx_Bit_Count.data'): + + + self.assertEqual(self.dut.Tx_Bit_Count.data.rdl_name, "Tx Bit Count") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Tx_Enable_Count.data'): + + + self.assertEqual(self.dut.Tx_Enable_Count.data.rdl_name, "Tx Enable Count") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Fb_FreqWord.config_data'): + + + self.assertEqual(self.dut.Fb_FreqWord.config_data.rdl_name, "Frequency Control Word") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.TX_F1_FreqWord.config_data'): + + + self.assertEqual(self.dut.TX_F1_FreqWord.config_data.rdl_name, "Frequency Control Word") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.TX_F2_FreqWord.config_data'): + + + self.assertEqual(self.dut.TX_F2_FreqWord.config_data.rdl_name, "Frequency Control Word") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.RX_F1_FreqWord.config_data'): + + + self.assertEqual(self.dut.RX_F1_FreqWord.config_data.rdl_name, "Frequency Control Word") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.RX_F2_FreqWord.config_data'): + + + self.assertEqual(self.dut.RX_F2_FreqWord.config_data.rdl_name, "Frequency Control Word") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.LPF_Config_0.lpf_freeze'): + + + self.assertEqual(self.dut.LPF_Config_0.lpf_freeze.rdl_name, "Freeze the accumulator\u0027s current value") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.LPF_Config_0.lpf_zero'): + + + self.assertEqual(self.dut.LPF_Config_0.lpf_zero.rdl_name, "Hold the PI Accumulator at zero") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.LPF_Config_0.prbs_reserved'): + + + self.assertEqual(self.dut.LPF_Config_0.prbs_reserved.rdl_name, "Reserved") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.LPF_Config_0.lpf_alpha'): + + + self.assertEqual(self.dut.LPF_Config_0.lpf_alpha.rdl_name, "Lowpass IIR filter alpha") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.LPF_Config_1.i_gain'): + + + self.assertEqual(self.dut.LPF_Config_1.i_gain.rdl_name, "Integral Gain Value") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.LPF_Config_1.i_shift'): + + + self.assertEqual(self.dut.LPF_Config_1.i_shift.rdl_name, "Integral Gain Bit Shift") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Tx_Data_Width.data_width'): + + + self.assertEqual(self.dut.Tx_Data_Width.data_width.rdl_name, "Modem input/output data width") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Rx_Data_Width.data_width'): + + + self.assertEqual(self.dut.Rx_Data_Width.data_width.rdl_name, "Modem input/output data width") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.PRBS_Control.prbs_sel'): + + + self.assertEqual(self.dut.PRBS_Control.prbs_sel.rdl_name, "PRBS Data Select") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.PRBS_Control.prbs_error_insert'): + + + self.assertEqual(self.dut.PRBS_Control.prbs_error_insert.rdl_name, "PRBS Error Insert") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.PRBS_Control.prbs_clear'): + + + self.assertEqual(self.dut.PRBS_Control.prbs_clear.rdl_name, "PRBS Clear Counters") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.PRBS_Control.prbs_manual_sync'): + + + self.assertEqual(self.dut.PRBS_Control.prbs_manual_sync.rdl_name, "PRBS Manual Sync") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.PRBS_Control.prbs_reserved'): + + + self.assertEqual(self.dut.PRBS_Control.prbs_reserved.rdl_name, "Reserved") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.PRBS_Control.prbs_sync_threshold'): + + + self.assertEqual(self.dut.PRBS_Control.prbs_sync_threshold.rdl_name, "PRBS Auto Sync Threshold") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.PRBS_Initial_State.config_data'): + + + self.assertEqual(self.dut.PRBS_Initial_State.config_data.rdl_name, "PRBS Seed") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.PRBS_Polynomial.config_data'): + + + self.assertEqual(self.dut.PRBS_Polynomial.config_data.rdl_name, "PRBS Polynomial") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.PRBS_Error_Mask.config_data'): + + + self.assertEqual(self.dut.PRBS_Error_Mask.config_data.rdl_name, "PRBS Error Mask") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.PRBS_Bit_Count.data'): + + + self.assertEqual(self.dut.PRBS_Bit_Count.data.rdl_name, "PRBS Bits Received") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.PRBS_Error_Count.data'): + + + self.assertEqual(self.dut.PRBS_Error_Count.data.rdl_name, "PRBS Bit Errors") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.LPF_Accum_F1.data'): + + + self.assertEqual(self.dut.LPF_Accum_F1.data.rdl_name, "PI Controller Accumulator Value") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.LPF_Accum_F2.data'): + + + self.assertEqual(self.dut.LPF_Accum_F2.data.rdl_name, "PI Controller Accumulator Value") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.axis_xfer_count.data'): + + + self.assertEqual(self.dut.axis_xfer_count.data.rdl_name, "S_AXIS Transfers") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Rx_Sample_Discard.rx_sample_discard'): + + + self.assertEqual(self.dut.Rx_Sample_Discard.rx_sample_discard.rdl_name, "Rx Sample Discard Value") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Rx_Sample_Discard.rx_nco_discard'): + + + self.assertEqual(self.dut.Rx_Sample_Discard.rx_nco_discard.rdl_name, "Rx NCO Sample Discard Value") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.LPF_Config_2.p_gain'): + + + self.assertEqual(self.dut.LPF_Config_2.p_gain.rdl_name, "Proportional Gain Value") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.LPF_Config_2.p_shift'): + + + self.assertEqual(self.dut.LPF_Config_2.p_shift.rdl_name, "Proportional Gain Bit Shift") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.f1_nco_adjust.data'): + + + self.assertIsNone(self.dut.f1_nco_adjust.data.rdl_name) # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.f2_nco_adjust.data'): + + + self.assertIsNone(self.dut.f2_nco_adjust.data.rdl_name) # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.f1_error.data'): + + + self.assertIsNone(self.dut.f1_error.data.rdl_name) # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.f2_error.data'): + + + self.assertIsNone(self.dut.f2_error.data.rdl_name) # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Tx_Sync_Ctrl.tx_sync_ena'): + + + self.assertEqual(self.dut.Tx_Sync_Ctrl.tx_sync_ena.rdl_name, "Tx Sync Enable") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Tx_Sync_Ctrl.tx_sync_force'): + + + self.assertEqual(self.dut.Tx_Sync_Ctrl.tx_sync_force.rdl_name, "Tx Sync Force") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Tx_Sync_Cnt.tx_sync_cnt'): + + + self.assertEqual(self.dut.Tx_Sync_Cnt.tx_sync_cnt.rdl_name, "Tx sync duration") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.lowpass_ema_alpha1.alpha'): + + + self.assertEqual(self.dut.lowpass_ema_alpha1.alpha.rdl_name, "EMA alpha") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.lowpass_ema_alpha2.alpha'): + + + self.assertEqual(self.dut.lowpass_ema_alpha2.alpha.rdl_name, "EMA alpha") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.rx_power.data'): + + + self.assertEqual(self.dut.rx_power.data.rdl_name, "Receive Power") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.tx_async_fifo_rd_wr_ptr.data'): + + + self.assertIsNone(self.dut.tx_async_fifo_rd_wr_ptr.data.rdl_name) # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.rx_async_fifo_rd_wr_ptr.data'): + + + self.assertIsNone(self.dut.rx_async_fifo_rd_wr_ptr.data.rdl_name) # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.rx_frame_sync_status.frame_sync_locked'): + + + self.assertEqual(self.dut.rx_frame_sync_status.frame_sync_locked.rdl_name, "Frame Sync Lock") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.rx_frame_sync_status.frame_buffer_overflow'): + + + self.assertEqual(self.dut.rx_frame_sync_status.frame_buffer_overflow.rdl_name, "Frame Buffer Overflow") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.rx_frame_sync_status.frames_received'): + + + self.assertEqual(self.dut.rx_frame_sync_status.frames_received.rdl_name, "Frames Received") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.rx_frame_sync_status.frame_sync_errors'): + + + self.assertEqual(self.dut.rx_frame_sync_status.frame_sync_errors.rdl_name, "Frames Sync Errors") # type: ignore[union-attr] + + + + + + def test_desc(self) -> None: + """ + Walk the address map and check the desc property has been correctly populated + """ + with self.subTest(msg='node: msk_top_regs.Hash_ID_Low'): + + + self.assertIsNone(self.dut.Hash_ID_Low.rdl_desc) # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Hash_ID_High'): + + + self.assertIsNone(self.dut.Hash_ID_High.rdl_desc) # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.MSK_Init'): + + + self.assertEqual(self.dut.MSK_Init.rdl_desc, "Synchronous initialization of MSK Modem functions, does not affect configuration registers.") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.MSK_Control'): + + + self.assertEqual(self.dut.MSK_Control.rdl_desc, "MSK Modem Configuration and Control") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.MSK_Status'): + + + self.assertEqual(self.dut.MSK_Status.rdl_desc, "Modem status bits") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Tx_Bit_Count'): + + + self.assertEqual(self.dut.Tx_Bit_Count.rdl_desc, "Modem status data") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Tx_Enable_Count'): + + + self.assertEqual(self.dut.Tx_Enable_Count.rdl_desc, "Modem status data") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Fb_FreqWord'): + + + self.assertEqual(self.dut.Fb_FreqWord.rdl_desc, "Set Modem Data Rate") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.TX_F1_FreqWord'): + + + self.assertEqual(self.dut.TX_F1_FreqWord.rdl_desc, "Set Modulator F1 Frequency") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.TX_F2_FreqWord'): + + + self.assertEqual(self.dut.TX_F2_FreqWord.rdl_desc, "Set Modulator F2 Frequency") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.RX_F1_FreqWord'): + + + self.assertEqual(self.dut.RX_F1_FreqWord.rdl_desc, "Set Demodulator F1 Frequency") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.RX_F2_FreqWord'): + + + self.assertEqual(self.dut.RX_F2_FreqWord.rdl_desc, "Set Demodulator F2 Frequency") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.LPF_Config_0'): + + + self.assertEqual(self.dut.LPF_Config_0.rdl_desc, "Configure PI controller and low-pass filter") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.LPF_Config_1'): + + + self.assertEqual(self.dut.LPF_Config_1.rdl_desc, "Configures PI Controller I-gain and divisor") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Tx_Data_Width'): + + + self.assertEqual(self.dut.Tx_Data_Width.rdl_desc, "Set the parallel data width of the parallel-to-serial converter") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Rx_Data_Width'): + + + self.assertEqual(self.dut.Rx_Data_Width.rdl_desc, "Set the parallel data width of the serial-to-parallel converter") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.PRBS_Control'): + + + self.assertEqual(self.dut.PRBS_Control.rdl_desc, "Configures operation of the PRBS Generator and Monitor") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.PRBS_Initial_State'): + + + self.assertEqual(self.dut.PRBS_Initial_State.rdl_desc, "PRBS Initial State") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.PRBS_Polynomial'): + + + self.assertEqual(self.dut.PRBS_Polynomial.rdl_desc, "PRBS Polynomial") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.PRBS_Error_Mask'): + + + self.assertEqual(self.dut.PRBS_Error_Mask.rdl_desc, "PRBS Error Mask") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.PRBS_Bit_Count'): + + + self.assertEqual(self.dut.PRBS_Bit_Count.rdl_desc, "PRBS Bits Received") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.PRBS_Error_Count'): + + + self.assertEqual(self.dut.PRBS_Error_Count.rdl_desc, "PRBS Bit Errors") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.LPF_Accum_F1'): + + + self.assertEqual(self.dut.LPF_Accum_F1.rdl_desc, "Value of the F1 PI Controller Accumulator") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.LPF_Accum_F2'): + + + self.assertEqual(self.dut.LPF_Accum_F2.rdl_desc, "Value of the F2 PI Controller Accumulator") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.axis_xfer_count'): + + + self.assertEqual(self.dut.axis_xfer_count.rdl_desc, "Modem status data") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Rx_Sample_Discard'): + + + self.assertEqual(self.dut.Rx_Sample_Discard.rdl_desc, "Configure samples discard operation for demodulator") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.LPF_Config_2'): + + + self.assertEqual(self.dut.LPF_Config_2.rdl_desc, "Configures PI Controller I-gain and divisor") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.f1_nco_adjust'): + + + self.assertEqual(self.dut.f1_nco_adjust.rdl_desc, "Status Register") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.f2_nco_adjust'): + + + self.assertEqual(self.dut.f2_nco_adjust.rdl_desc, "Status Register") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.f1_error'): + + + self.assertEqual(self.dut.f1_error.rdl_desc, "Status Register") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.f2_error'): + + + self.assertEqual(self.dut.f2_error.rdl_desc, "Status Register") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Tx_Sync_Ctrl'): + + + self.assertEqual(self.dut.Tx_Sync_Ctrl.rdl_desc, "Provides control bits for generation of transmitter synchronization patterns") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Tx_Sync_Cnt'): + + + self.assertEqual(self.dut.Tx_Sync_Cnt.rdl_desc, "Sets the duration of the synchronization tones when enabled") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.lowpass_ema_alpha1'): + + + self.assertEqual(self.dut.lowpass_ema_alpha1.rdl_desc, "Sets the alpha for the EMA") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.lowpass_ema_alpha2'): + + + self.assertEqual(self.dut.lowpass_ema_alpha2.rdl_desc, "Sets the alpha for the EMA") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.rx_power'): + + + self.assertEqual(self.dut.rx_power.rdl_desc, "Receive power computed from I/Q samples") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.tx_async_fifo_rd_wr_ptr'): + + + self.assertEqual(self.dut.tx_async_fifo_rd_wr_ptr.rdl_desc, "Tx async FIFO read and write pointers") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.rx_async_fifo_rd_wr_ptr'): + + + self.assertEqual(self.dut.rx_async_fifo_rd_wr_ptr.rdl_desc, "Rx async FIFO read and write pointers") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.rx_frame_sync_status'): + + + self.assertIsNone(self.dut.rx_frame_sync_status.rdl_desc) # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Hash_ID_Low.hash_id_lo'): + + + self.assertEqual(self.dut.Hash_ID_Low.hash_id_lo.rdl_desc, "Lower 32-bits of Pluto MSK FPGA Hash ID") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Hash_ID_High.hash_id_hi'): + + + self.assertEqual(self.dut.Hash_ID_High.hash_id_hi.rdl_desc, "Upper 32-bits of Pluto MSK FPGA Hash ID") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.MSK_Init.txrxinit'): + + + self.assertEqual(self.dut.MSK_Init.txrxinit.rdl_desc, "0 -\u003e Normal modem operation \n\n1 -\u003e Initialize Tx and Rx") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.MSK_Init.txinit'): + + + self.assertEqual(self.dut.MSK_Init.txinit.rdl_desc, "0 -\u003e Normal Tx operation\n\n1 -\u003e Initialize Tx") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.MSK_Init.rxinit'): + + + self.assertEqual(self.dut.MSK_Init.rxinit.rdl_desc, "0 -\u003e Normal Rx operation \n\n1 -\u003e Initialize Rx") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.MSK_Control.ptt'): + + + self.assertEqual(self.dut.MSK_Control.ptt.rdl_desc, "0 -\u003e PTT Disabled\n1 -\u003e PTT Enabled") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.MSK_Control.loopback_ena'): + + + self.assertEqual(self.dut.MSK_Control.loopback_ena.rdl_desc, "0 -\u003e Modem loopback disabled\n\n1 -\u003e Modem loopback enabled") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.MSK_Control.rx_invert'): + + + self.assertEqual(self.dut.MSK_Control.rx_invert.rdl_desc, "0 -\u003e Rx data normal\n1 -\u003e Rx data inverted") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.MSK_Control.clear_counts'): + + + self.assertEqual(self.dut.MSK_Control.clear_counts.rdl_desc, "Clear Tx Bit Counter and Tx Enable Counter") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.MSK_Control.diff_encoder_loopback'): + + + self.assertEqual(self.dut.MSK_Control.diff_encoder_loopback.rdl_desc, "0 -\u003e Differential Encoder -\u003e Decoder loopback disabled\n\n1 -\u003e Differential Encoder -\u003e Decoder loopback enabled") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.MSK_Status.demod_sync_lock'): + + + self.assertEqual(self.dut.MSK_Status.demod_sync_lock.rdl_desc, "Demodulator Sync Status - not currently implemented") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.MSK_Status.tx_enable'): + + + self.assertEqual(self.dut.MSK_Status.tx_enable.rdl_desc, "1 -\u003e Data to DAC Enabled\n\n0 -\u003e Data to DAC Disabled") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.MSK_Status.rx_enable'): + + + self.assertEqual(self.dut.MSK_Status.rx_enable.rdl_desc, "1 -\u003e Data from ADC Enabled\n\n0 -\u003e Data from ADC Disabled") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.MSK_Status.tx_axis_valid'): + + + self.assertEqual(self.dut.MSK_Status.tx_axis_valid.rdl_desc, "1 -\u003e S_AXIS_VALID Enabled\n\n0 -\u003e S_AXIS_VALID Disabled") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Tx_Bit_Count.data'): + + + self.assertEqual(self.dut.Tx_Bit_Count.data.rdl_desc, "Count of data requests made by modem\n\nThis register is write-to-capture.\n\nTo read data the following steps are required:\n\n1 - Write any value to this register to capture read data\n\n2 - Read the register") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Tx_Enable_Count.data'): + + + self.assertEqual(self.dut.Tx_Enable_Count.data.rdl_desc, "Number of clocks on which Tx Enable is active\n\nThis register is write-to-capture.\n\nTo read data the following steps are required:\n\n1 - Write any value to this register to capture read data\n\n2 - Read the register") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Fb_FreqWord.config_data'): + + + self.assertEqual(self.dut.Fb_FreqWord.config_data.rdl_desc, "Sets the center frequency of the NCO as FW = Fn * 2^32/Fs, \nwhere Fn is the desired NCO frequency, and Fs is the NCO sample rate") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.TX_F1_FreqWord.config_data'): + + + self.assertEqual(self.dut.TX_F1_FreqWord.config_data.rdl_desc, "Sets the center frequency of the NCO as FW = Fn * 2^32/Fs, \nwhere Fn is the desired NCO frequency, and Fs is the NCO sample rate") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.TX_F2_FreqWord.config_data'): + + + self.assertEqual(self.dut.TX_F2_FreqWord.config_data.rdl_desc, "Sets the center frequency of the NCO as FW = Fn * 2^32/Fs, \nwhere Fn is the desired NCO frequency, and Fs is the NCO sample rate") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.RX_F1_FreqWord.config_data'): + + + self.assertEqual(self.dut.RX_F1_FreqWord.config_data.rdl_desc, "Sets the center frequency of the NCO as FW = Fn * 2^32/Fs, \nwhere Fn is the desired NCO frequency, and Fs is the NCO sample rate") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.RX_F2_FreqWord.config_data'): + + + self.assertEqual(self.dut.RX_F2_FreqWord.config_data.rdl_desc, "Sets the center frequency of the NCO as FW = Fn * 2^32/Fs, \nwhere Fn is the desired NCO frequency, and Fs is the NCO sample rate") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.LPF_Config_0.lpf_freeze'): + + + self.assertEqual(self.dut.LPF_Config_0.lpf_freeze.rdl_desc, "0 -\u003e Normal operation\n\n1 -\u003e Freeze current value") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.LPF_Config_0.lpf_zero'): + + + self.assertEqual(self.dut.LPF_Config_0.lpf_zero.rdl_desc, "0 -\u003e Normal operation\n\n1 -\u003e Zero and hold accumulator") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.LPF_Config_0.prbs_reserved'): + + + self.assertIsNone(self.dut.LPF_Config_0.prbs_reserved.rdl_desc) # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.LPF_Config_0.lpf_alpha'): + + + self.assertEqual(self.dut.LPF_Config_0.lpf_alpha.rdl_desc, "Value controls the filter rolloff") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.LPF_Config_1.i_gain'): + + + self.assertEqual(self.dut.LPF_Config_1.i_gain.rdl_desc, "Value m of 0-16,777,215 sets the integral multiplier") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.LPF_Config_1.i_shift'): + + + self.assertEqual(self.dut.LPF_Config_1.i_shift.rdl_desc, "Value n of 0-32 sets the integral divisor as 2^-n") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Tx_Data_Width.data_width'): + + + self.assertEqual(self.dut.Tx_Data_Width.data_width.rdl_desc, "Set the data width of the modem input/output") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Rx_Data_Width.data_width'): + + + self.assertEqual(self.dut.Rx_Data_Width.data_width.rdl_desc, "Set the data width of the modem input/output") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.PRBS_Control.prbs_sel'): + + + self.assertEqual(self.dut.PRBS_Control.prbs_sel.rdl_desc, "0 -\u003e Select Normal Tx Data\n1 -\u003e Select PRBS Tx Data") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.PRBS_Control.prbs_error_insert'): + + + self.assertEqual(self.dut.PRBS_Control.prbs_error_insert.rdl_desc, "0 -\u003e 1 : Insert bit error in Tx data (both Normal and PRBS)\n\n1 -\u003e 0 : Insert bit error in Tx data (both Normal and PRBS)") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.PRBS_Control.prbs_clear'): + + + self.assertEqual(self.dut.PRBS_Control.prbs_clear.rdl_desc, "0 -\u003e 1 : Clear PRBS Counters\n\n1 -\u003e 0 : Clear PRBS Counters") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.PRBS_Control.prbs_manual_sync'): + + + self.assertEqual(self.dut.PRBS_Control.prbs_manual_sync.rdl_desc, "0 -\u003e 1 : Synchronize PRBS monitor\n\n1 -\u003e 0 : Synchronize PRBS monitor") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.PRBS_Control.prbs_reserved'): + + + self.assertIsNone(self.dut.PRBS_Control.prbs_reserved.rdl_desc) # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.PRBS_Control.prbs_sync_threshold'): + + + self.assertEqual(self.dut.PRBS_Control.prbs_sync_threshold.rdl_desc, "0 : Auto Sync Disabled\n\nN \u003e 0 : Auto sync after N errors") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.PRBS_Initial_State.config_data'): + + + self.assertEqual(self.dut.PRBS_Initial_State.config_data.rdl_desc, "Sets the starting value of the PRBS generator") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.PRBS_Polynomial.config_data'): + + + self.assertEqual(self.dut.PRBS_Polynomial.config_data.rdl_desc, "Bit positions set to \u00271\u0027 indicate polynomial feedback positions") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.PRBS_Error_Mask.config_data'): + + + self.assertEqual(self.dut.PRBS_Error_Mask.config_data.rdl_desc, "Bit positions set to \u00271\u0027 indicate bits that are inverted when a bit error is inserted") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.PRBS_Bit_Count.data'): + + + self.assertEqual(self.dut.PRBS_Bit_Count.data.rdl_desc, "Number of bits received by the PRBS monitor since last\nBER can be calculated as the ratio of received bits to errored-bits\n\nThis register is write-to-capture.\n\nTo read data the following steps are required:\n\n1 - Write any value to this register to capture read data\n\n2 - Read the register") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.PRBS_Error_Count.data'): + + + self.assertEqual(self.dut.PRBS_Error_Count.data.rdl_desc, "Number of errored-bits received by the PRBS monitor since last sync\nBER can be calculated as the ratio of received bits to errored-bits\n\nThis register is write-to-capture.\n\nTo read data the following steps are required:\n\n1 - Write any value to this register to capture read data\n\n2 - Read the register") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.LPF_Accum_F1.data'): + + + self.assertEqual(self.dut.LPF_Accum_F1.data.rdl_desc, "PI Controller Accumulator Value\n\nThis register is write-to-capture.\n\nTo read data the following steps are required:\n\n1 - Write any value to this register to capture read data\n\n2 - Read the register") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.LPF_Accum_F2.data'): + + + self.assertEqual(self.dut.LPF_Accum_F2.data.rdl_desc, "PI Controller Accumulator Value\n\nThis register is write-to-capture.\n\nTo read data the following steps are required:\n\n1 - Write any value to this register to capture read data\n\n2 - Read the register") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.axis_xfer_count.data'): + + + self.assertEqual(self.dut.axis_xfer_count.data.rdl_desc, "Number completed S_AXIS transfers\n\nThis register is write-to-capture.\n\nTo read data the following steps are required:\n\n1 - Write any value to this register to capture read data\n\n2 - Read the register") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Rx_Sample_Discard.rx_sample_discard'): + + + self.assertEqual(self.dut.Rx_Sample_Discard.rx_sample_discard.rdl_desc, "Number of Rx samples to discard") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Rx_Sample_Discard.rx_nco_discard'): + + + self.assertEqual(self.dut.Rx_Sample_Discard.rx_nco_discard.rdl_desc, "Number of NCO samples to discard") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.LPF_Config_2.p_gain'): + + + self.assertEqual(self.dut.LPF_Config_2.p_gain.rdl_desc, "Value m of 0-16,777,215 sets the proportional multiplier") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.LPF_Config_2.p_shift'): + + + self.assertEqual(self.dut.LPF_Config_2.p_shift.rdl_desc, "Value n of 0-32 sets the proportional divisor as 2^-n") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.f1_nco_adjust.data'): + + + self.assertEqual(self.dut.f1_nco_adjust.data.rdl_desc, "Frequency offet applied to the F1 NCO\n\nThis register is write-to-capture.\n\nTo read data the following steps are required:\n\n1 - Write any value to this register to capture read data\n\n2 - Read the register") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.f2_nco_adjust.data'): + + + self.assertEqual(self.dut.f2_nco_adjust.data.rdl_desc, "Frequency offet applied to the F2 NCO\n\nThis register is write-to-capture.\n\nTo read data the following steps are required:\n\n1 - Write any value to this register to capture read data\n\n2 - Read the register") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.f1_error.data'): + + + self.assertEqual(self.dut.f1_error.data.rdl_desc, "Error value of the F1 Costas loop after each active bit period\n\nThis register is write-to-capture.\n\nTo read data the following steps are required:\n\n1 - Write any value to this register to capture read data\n\n2 - Read the register") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.f2_error.data'): + + + self.assertEqual(self.dut.f2_error.data.rdl_desc, "Error value of the F2 Costas loop after each active bit period\n\nThis register is write-to-capture.\n\nTo read data the following steps are required:\n\n1 - Write any value to this register to capture read data\n\n2 - Read the register") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Tx_Sync_Ctrl.tx_sync_ena'): + + + self.assertEqual(self.dut.Tx_Sync_Ctrl.tx_sync_ena.rdl_desc, "0 : Disable sync transmission\n\n1 : Enable sync transmission when PTT is asserted") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Tx_Sync_Ctrl.tx_sync_force'): + + + self.assertEqual(self.dut.Tx_Sync_Ctrl.tx_sync_force.rdl_desc, "0 : Normal operation\n\n1 : Continuously transmit synchronization pattern") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.Tx_Sync_Cnt.tx_sync_cnt'): + + + self.assertEqual(self.dut.Tx_Sync_Cnt.tx_sync_cnt.rdl_desc, "Value from 0x00_0000 to 0xFF_FFFF. \n\nThis value represents the number bit-times the synchronization signal should be sent after PTT is asserted.") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.lowpass_ema_alpha1.alpha'): + + + self.assertEqual(self.dut.lowpass_ema_alpha1.alpha.rdl_desc, "Value from 0x0_0000 to 0x3_FFFF represent the EMA alpha") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.lowpass_ema_alpha2.alpha'): + + + self.assertEqual(self.dut.lowpass_ema_alpha2.alpha.rdl_desc, "Value from 0x0_0000 to 0x3_FFFF represent the EMA alpha") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.rx_power.data'): + + + self.assertEqual(self.dut.rx_power.data.rdl_desc, "Value that represent the RMS power of the incoming signal (I-channel)\n\nThis register is write-to-capture. To read data the following steps are required:\n[list=1]\n[*] Write any value to this register to capture read data\n[*] Read the register\n[/list]") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.tx_async_fifo_rd_wr_ptr.data'): + + + self.assertEqual(self.dut.tx_async_fifo_rd_wr_ptr.data.rdl_desc, "Read and Write Pointers\n\n[code]\nBits 31:16 - write pointer (12-bits)\nBits 15:00 - read pointer (12-bits)\n[/code]\n\nThis register is write-to-capture. To read data the following steps are required:\n[list=1]\n[*] Write any value to this register to capture read data\n[*] Read the register\n[/list]") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.rx_async_fifo_rd_wr_ptr.data'): + + + self.assertEqual(self.dut.rx_async_fifo_rd_wr_ptr.data.rdl_desc, "Read and Write Pointers\n\n[code]\nBits 31:16 - write pointer (12-bits)\nBits 15:00 - read pointer (12-bits)\n[/code]\n\nThis register is write-to-capture. To read data the following steps are required:\n[list=1]\n[*] Write any value to this register to capture read data\n[*] Read the register\n[/list]") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.rx_frame_sync_status.frame_sync_locked'): + + + self.assertEqual(self.dut.rx_frame_sync_status.frame_sync_locked.rdl_desc, "0 - Frame sync not locked\n1 - Frame sync locked") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.rx_frame_sync_status.frame_buffer_overflow'): + + + self.assertEqual(self.dut.rx_frame_sync_status.frame_buffer_overflow.rdl_desc, "0 - Normal operation\n1 - Buffer overflow") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.rx_frame_sync_status.frames_received'): + + + self.assertEqual(self.dut.rx_frame_sync_status.frames_received.rdl_desc, "Count of frames received since last read. Value is 0x00_0000 to 0xFF_FFFF") # type: ignore[union-attr] + + + + with self.subTest(msg='node: msk_top_regs.rx_frame_sync_status.frame_sync_errors'): + + + self.assertEqual(self.dut.rx_frame_sync_status.frame_sync_errors.rdl_desc, "Count of frame sync errors since last read. Value is 0 to 63. This field will saturate at 63 if more than 63 occur.") # type: ignore[union-attr] + + + + + + def test_sizes(self) -> None: + """ + Check that the sizes all match + """ + with self.subTest(msg='node: msk_top_regs.Hash_ID_Low'): + self.assertEqual(self.dut.Hash_ID_Low.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.Hash_ID_High'): + self.assertEqual(self.dut.Hash_ID_High.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.MSK_Init'): + self.assertEqual(self.dut.MSK_Init.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.MSK_Control'): + self.assertEqual(self.dut.MSK_Control.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.MSK_Status'): + self.assertEqual(self.dut.MSK_Status.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.Tx_Bit_Count'): + self.assertEqual(self.dut.Tx_Bit_Count.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.Tx_Enable_Count'): + self.assertEqual(self.dut.Tx_Enable_Count.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.Fb_FreqWord'): + self.assertEqual(self.dut.Fb_FreqWord.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.TX_F1_FreqWord'): + self.assertEqual(self.dut.TX_F1_FreqWord.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.TX_F2_FreqWord'): + self.assertEqual(self.dut.TX_F2_FreqWord.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.RX_F1_FreqWord'): + self.assertEqual(self.dut.RX_F1_FreqWord.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.RX_F2_FreqWord'): + self.assertEqual(self.dut.RX_F2_FreqWord.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.LPF_Config_0'): + self.assertEqual(self.dut.LPF_Config_0.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.LPF_Config_1'): + self.assertEqual(self.dut.LPF_Config_1.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.Tx_Data_Width'): + self.assertEqual(self.dut.Tx_Data_Width.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.Rx_Data_Width'): + self.assertEqual(self.dut.Rx_Data_Width.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Control'): + self.assertEqual(self.dut.PRBS_Control.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Initial_State'): + self.assertEqual(self.dut.PRBS_Initial_State.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Polynomial'): + self.assertEqual(self.dut.PRBS_Polynomial.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Error_Mask'): + self.assertEqual(self.dut.PRBS_Error_Mask.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Bit_Count'): + self.assertEqual(self.dut.PRBS_Bit_Count.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Error_Count'): + self.assertEqual(self.dut.PRBS_Error_Count.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.LPF_Accum_F1'): + self.assertEqual(self.dut.LPF_Accum_F1.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.LPF_Accum_F2'): + self.assertEqual(self.dut.LPF_Accum_F2.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.axis_xfer_count'): + self.assertEqual(self.dut.axis_xfer_count.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.Rx_Sample_Discard'): + self.assertEqual(self.dut.Rx_Sample_Discard.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.LPF_Config_2'): + self.assertEqual(self.dut.LPF_Config_2.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.f1_nco_adjust'): + self.assertEqual(self.dut.f1_nco_adjust.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.f2_nco_adjust'): + self.assertEqual(self.dut.f2_nco_adjust.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.f1_error'): + self.assertEqual(self.dut.f1_error.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.f2_error'): + self.assertEqual(self.dut.f2_error.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.Tx_Sync_Ctrl'): + self.assertEqual(self.dut.Tx_Sync_Ctrl.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.Tx_Sync_Cnt'): + self.assertEqual(self.dut.Tx_Sync_Cnt.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.lowpass_ema_alpha1'): + self.assertEqual(self.dut.lowpass_ema_alpha1.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.lowpass_ema_alpha2'): + self.assertEqual(self.dut.lowpass_ema_alpha2.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.rx_power'): + self.assertEqual(self.dut.rx_power.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.tx_async_fifo_rd_wr_ptr'): + self.assertEqual(self.dut.tx_async_fifo_rd_wr_ptr.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.rx_async_fifo_rd_wr_ptr'): + self.assertEqual(self.dut.rx_async_fifo_rd_wr_ptr.size, 4) # type: ignore[union-attr] + with self.subTest(msg='node: msk_top_regs.rx_frame_sync_status'): + self.assertEqual(self.dut.rx_frame_sync_status.size, 4) # type: ignore[union-attr] + + + # check the size of the address map itself + + with self.subTest(msg='node: msk_top_regs'): + self.assertEqual(self.dut.size, 156) # type: ignore[union-attr] + + + + def test_register_properties(self) -> None: + """ + Walk the address map and check the address, size and accesswidth of every register is + correct + """ + with self.subTest(msg='register: msk_top_regs.Hash_ID_Low'): + self.assertEqual(self.dut.Hash_ID_Low.address, 0) # type: ignore[union-attr] + self.assertEqual(self.dut.Hash_ID_Low.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.Hash_ID_Low.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.Hash_ID_Low.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.Hash_ID_High'): + self.assertEqual(self.dut.Hash_ID_High.address, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.Hash_ID_High.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.Hash_ID_High.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.Hash_ID_High.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.MSK_Init'): + self.assertEqual(self.dut.MSK_Init.address, 8) # type: ignore[union-attr] + self.assertEqual(self.dut.MSK_Init.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.MSK_Init.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.MSK_Init.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.MSK_Control'): + self.assertEqual(self.dut.MSK_Control.address, 12) # type: ignore[union-attr] + self.assertEqual(self.dut.MSK_Control.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.MSK_Control.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.MSK_Control.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.MSK_Status'): + self.assertEqual(self.dut.MSK_Status.address, 16) # type: ignore[union-attr] + self.assertEqual(self.dut.MSK_Status.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.MSK_Status.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.MSK_Status.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.Tx_Bit_Count'): + self.assertEqual(self.dut.Tx_Bit_Count.address, 20) # type: ignore[union-attr] + self.assertEqual(self.dut.Tx_Bit_Count.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.Tx_Bit_Count.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.Tx_Bit_Count.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.Tx_Enable_Count'): + self.assertEqual(self.dut.Tx_Enable_Count.address, 24) # type: ignore[union-attr] + self.assertEqual(self.dut.Tx_Enable_Count.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.Tx_Enable_Count.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.Tx_Enable_Count.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.Fb_FreqWord'): + self.assertEqual(self.dut.Fb_FreqWord.address, 28) # type: ignore[union-attr] + self.assertEqual(self.dut.Fb_FreqWord.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.Fb_FreqWord.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.Fb_FreqWord.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.TX_F1_FreqWord'): + self.assertEqual(self.dut.TX_F1_FreqWord.address, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.TX_F1_FreqWord.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.TX_F1_FreqWord.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.TX_F1_FreqWord.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.TX_F2_FreqWord'): + self.assertEqual(self.dut.TX_F2_FreqWord.address, 36) # type: ignore[union-attr] + self.assertEqual(self.dut.TX_F2_FreqWord.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.TX_F2_FreqWord.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.TX_F2_FreqWord.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.RX_F1_FreqWord'): + self.assertEqual(self.dut.RX_F1_FreqWord.address, 40) # type: ignore[union-attr] + self.assertEqual(self.dut.RX_F1_FreqWord.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.RX_F1_FreqWord.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.RX_F1_FreqWord.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.RX_F2_FreqWord'): + self.assertEqual(self.dut.RX_F2_FreqWord.address, 44) # type: ignore[union-attr] + self.assertEqual(self.dut.RX_F2_FreqWord.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.RX_F2_FreqWord.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.RX_F2_FreqWord.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.LPF_Config_0'): + self.assertEqual(self.dut.LPF_Config_0.address, 48) # type: ignore[union-attr] + self.assertEqual(self.dut.LPF_Config_0.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.LPF_Config_0.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.LPF_Config_0.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.LPF_Config_1'): + self.assertEqual(self.dut.LPF_Config_1.address, 52) # type: ignore[union-attr] + self.assertEqual(self.dut.LPF_Config_1.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.LPF_Config_1.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.LPF_Config_1.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.Tx_Data_Width'): + self.assertEqual(self.dut.Tx_Data_Width.address, 56) # type: ignore[union-attr] + self.assertEqual(self.dut.Tx_Data_Width.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.Tx_Data_Width.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.Tx_Data_Width.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.Rx_Data_Width'): + self.assertEqual(self.dut.Rx_Data_Width.address, 60) # type: ignore[union-attr] + self.assertEqual(self.dut.Rx_Data_Width.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.Rx_Data_Width.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.Rx_Data_Width.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.PRBS_Control'): + self.assertEqual(self.dut.PRBS_Control.address, 64) # type: ignore[union-attr] + self.assertEqual(self.dut.PRBS_Control.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.PRBS_Control.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.PRBS_Control.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.PRBS_Initial_State'): + self.assertEqual(self.dut.PRBS_Initial_State.address, 68) # type: ignore[union-attr] + self.assertEqual(self.dut.PRBS_Initial_State.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.PRBS_Initial_State.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.PRBS_Initial_State.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.PRBS_Polynomial'): + self.assertEqual(self.dut.PRBS_Polynomial.address, 72) # type: ignore[union-attr] + self.assertEqual(self.dut.PRBS_Polynomial.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.PRBS_Polynomial.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.PRBS_Polynomial.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.PRBS_Error_Mask'): + self.assertEqual(self.dut.PRBS_Error_Mask.address, 76) # type: ignore[union-attr] + self.assertEqual(self.dut.PRBS_Error_Mask.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.PRBS_Error_Mask.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.PRBS_Error_Mask.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.PRBS_Bit_Count'): + self.assertEqual(self.dut.PRBS_Bit_Count.address, 80) # type: ignore[union-attr] + self.assertEqual(self.dut.PRBS_Bit_Count.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.PRBS_Bit_Count.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.PRBS_Bit_Count.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.PRBS_Error_Count'): + self.assertEqual(self.dut.PRBS_Error_Count.address, 84) # type: ignore[union-attr] + self.assertEqual(self.dut.PRBS_Error_Count.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.PRBS_Error_Count.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.PRBS_Error_Count.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.LPF_Accum_F1'): + self.assertEqual(self.dut.LPF_Accum_F1.address, 88) # type: ignore[union-attr] + self.assertEqual(self.dut.LPF_Accum_F1.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.LPF_Accum_F1.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.LPF_Accum_F1.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.LPF_Accum_F2'): + self.assertEqual(self.dut.LPF_Accum_F2.address, 92) # type: ignore[union-attr] + self.assertEqual(self.dut.LPF_Accum_F2.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.LPF_Accum_F2.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.LPF_Accum_F2.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.axis_xfer_count'): + self.assertEqual(self.dut.axis_xfer_count.address, 96) # type: ignore[union-attr] + self.assertEqual(self.dut.axis_xfer_count.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.axis_xfer_count.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.axis_xfer_count.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.Rx_Sample_Discard'): + self.assertEqual(self.dut.Rx_Sample_Discard.address, 100) # type: ignore[union-attr] + self.assertEqual(self.dut.Rx_Sample_Discard.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.Rx_Sample_Discard.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.Rx_Sample_Discard.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.LPF_Config_2'): + self.assertEqual(self.dut.LPF_Config_2.address, 104) # type: ignore[union-attr] + self.assertEqual(self.dut.LPF_Config_2.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.LPF_Config_2.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.LPF_Config_2.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.f1_nco_adjust'): + self.assertEqual(self.dut.f1_nco_adjust.address, 108) # type: ignore[union-attr] + self.assertEqual(self.dut.f1_nco_adjust.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.f1_nco_adjust.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.f1_nco_adjust.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.f2_nco_adjust'): + self.assertEqual(self.dut.f2_nco_adjust.address, 112) # type: ignore[union-attr] + self.assertEqual(self.dut.f2_nco_adjust.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.f2_nco_adjust.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.f2_nco_adjust.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.f1_error'): + self.assertEqual(self.dut.f1_error.address, 116) # type: ignore[union-attr] + self.assertEqual(self.dut.f1_error.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.f1_error.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.f1_error.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.f2_error'): + self.assertEqual(self.dut.f2_error.address, 120) # type: ignore[union-attr] + self.assertEqual(self.dut.f2_error.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.f2_error.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.f2_error.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.Tx_Sync_Ctrl'): + self.assertEqual(self.dut.Tx_Sync_Ctrl.address, 124) # type: ignore[union-attr] + self.assertEqual(self.dut.Tx_Sync_Ctrl.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.Tx_Sync_Ctrl.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.Tx_Sync_Ctrl.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.Tx_Sync_Cnt'): + self.assertEqual(self.dut.Tx_Sync_Cnt.address, 128) # type: ignore[union-attr] + self.assertEqual(self.dut.Tx_Sync_Cnt.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.Tx_Sync_Cnt.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.Tx_Sync_Cnt.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.lowpass_ema_alpha1'): + self.assertEqual(self.dut.lowpass_ema_alpha1.address, 132) # type: ignore[union-attr] + self.assertEqual(self.dut.lowpass_ema_alpha1.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.lowpass_ema_alpha1.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.lowpass_ema_alpha1.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.lowpass_ema_alpha2'): + self.assertEqual(self.dut.lowpass_ema_alpha2.address, 136) # type: ignore[union-attr] + self.assertEqual(self.dut.lowpass_ema_alpha2.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.lowpass_ema_alpha2.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.lowpass_ema_alpha2.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.rx_power'): + self.assertEqual(self.dut.rx_power.address, 140) # type: ignore[union-attr] + self.assertEqual(self.dut.rx_power.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.rx_power.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.rx_power.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.tx_async_fifo_rd_wr_ptr'): + self.assertEqual(self.dut.tx_async_fifo_rd_wr_ptr.address, 144) # type: ignore[union-attr] + self.assertEqual(self.dut.tx_async_fifo_rd_wr_ptr.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.tx_async_fifo_rd_wr_ptr.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.tx_async_fifo_rd_wr_ptr.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.rx_async_fifo_rd_wr_ptr'): + self.assertEqual(self.dut.rx_async_fifo_rd_wr_ptr.address, 148) # type: ignore[union-attr] + self.assertEqual(self.dut.rx_async_fifo_rd_wr_ptr.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.rx_async_fifo_rd_wr_ptr.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.rx_async_fifo_rd_wr_ptr.accesswidth, 32) # type: ignore[union-attr] + with self.subTest(msg='register: msk_top_regs.rx_frame_sync_status'): + self.assertEqual(self.dut.rx_frame_sync_status.address, 152) # type: ignore[union-attr] + self.assertEqual(self.dut.rx_frame_sync_status.width, 32) # type: ignore[union-attr] + self.assertEqual(self.dut.rx_frame_sync_status.size, 4) # type: ignore[union-attr] + self.assertEqual(self.dut.rx_frame_sync_status.accesswidth, 32) # type: ignore[union-attr] + + + def test_memory_properties(self) -> None: + """ + Walk the address map and check the address, size and accesswidth of every memory is + correct + """ + mut: AsyncMemory + + + def test_field_properties(self) -> None: + """ + walk the address map and check: + - that the lsb and msb of every field is correct + - that where default values are provided they are applied correctly + """ + fut:Field + with self.subTest(msg='field: msk_top_regs.Hash_ID_Low.hash_id_lo'): + # test properties of field: msk_top_regs.Hash_ID_Low.hash_id_lo + fut = self.dut.Hash_ID_Low.hash_id_lo # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,31) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,31) + self.assertEqual(fut.bitmask,0xFFFFFFFF) + self.assertEqual(fut.inverse_bitmask,0x0) + self.assertEqual(fut.max_value,0xFFFFFFFF) + + self.assertEqual(fut.default,2863289685) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.Hash_ID_High.hash_id_hi'): + # test properties of field: msk_top_regs.Hash_ID_High.hash_id_hi + fut = self.dut.Hash_ID_High.hash_id_hi # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,31) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,31) + self.assertEqual(fut.bitmask,0xFFFFFFFF) + self.assertEqual(fut.inverse_bitmask,0x0) + self.assertEqual(fut.max_value,0xFFFFFFFF) + + self.assertEqual(fut.default,1431677610) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.MSK_Init.txrxinit'): + # test properties of field: msk_top_regs.MSK_Init.txrxinit + fut = self.dut.MSK_Init.txrxinit # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,0) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,0) + self.assertEqual(fut.bitmask,0x1) + self.assertEqual(fut.inverse_bitmask,0xFFFFFFFE) + self.assertEqual(fut.max_value,0x1) + + self.assertEqual(fut.default,1) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.MSK_Init.txinit'): + # test properties of field: msk_top_regs.MSK_Init.txinit + fut = self.dut.MSK_Init.txinit # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,1) + self.assertEqual(fut.msb,1) + self.assertEqual(fut.low,1) + self.assertEqual(fut.high,1) + self.assertEqual(fut.bitmask,0x2) + self.assertEqual(fut.inverse_bitmask,0xFFFFFFFD) + self.assertEqual(fut.max_value,0x1) + + self.assertEqual(fut.default,1) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.MSK_Init.rxinit'): + # test properties of field: msk_top_regs.MSK_Init.rxinit + fut = self.dut.MSK_Init.rxinit # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,2) + self.assertEqual(fut.msb,2) + self.assertEqual(fut.low,2) + self.assertEqual(fut.high,2) + self.assertEqual(fut.bitmask,0x4) + self.assertEqual(fut.inverse_bitmask,0xFFFFFFFB) + self.assertEqual(fut.max_value,0x1) + + self.assertEqual(fut.default,1) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.MSK_Control.ptt'): + # test properties of field: msk_top_regs.MSK_Control.ptt + fut = self.dut.MSK_Control.ptt # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,0) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,0) + self.assertEqual(fut.bitmask,0x1) + self.assertEqual(fut.inverse_bitmask,0xFFFFFFFE) + self.assertEqual(fut.max_value,0x1) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.MSK_Control.loopback_ena'): + # test properties of field: msk_top_regs.MSK_Control.loopback_ena + fut = self.dut.MSK_Control.loopback_ena # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,1) + self.assertEqual(fut.msb,1) + self.assertEqual(fut.low,1) + self.assertEqual(fut.high,1) + self.assertEqual(fut.bitmask,0x2) + self.assertEqual(fut.inverse_bitmask,0xFFFFFFFD) + self.assertEqual(fut.max_value,0x1) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.MSK_Control.rx_invert'): + # test properties of field: msk_top_regs.MSK_Control.rx_invert + fut = self.dut.MSK_Control.rx_invert # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,2) + self.assertEqual(fut.msb,2) + self.assertEqual(fut.low,2) + self.assertEqual(fut.high,2) + self.assertEqual(fut.bitmask,0x4) + self.assertEqual(fut.inverse_bitmask,0xFFFFFFFB) + self.assertEqual(fut.max_value,0x1) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.MSK_Control.clear_counts'): + # test properties of field: msk_top_regs.MSK_Control.clear_counts + fut = self.dut.MSK_Control.clear_counts # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,3) + self.assertEqual(fut.msb,3) + self.assertEqual(fut.low,3) + self.assertEqual(fut.high,3) + self.assertEqual(fut.bitmask,0x8) + self.assertEqual(fut.inverse_bitmask,0xFFFFFFF7) + self.assertEqual(fut.max_value,0x1) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.MSK_Control.diff_encoder_loopback'): + # test properties of field: msk_top_regs.MSK_Control.diff_encoder_loopback + fut = self.dut.MSK_Control.diff_encoder_loopback # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,4) + self.assertEqual(fut.msb,4) + self.assertEqual(fut.low,4) + self.assertEqual(fut.high,4) + self.assertEqual(fut.bitmask,0x10) + self.assertEqual(fut.inverse_bitmask,0xFFFFFFEF) + self.assertEqual(fut.max_value,0x1) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.MSK_Status.demod_sync_lock'): + # test properties of field: msk_top_regs.MSK_Status.demod_sync_lock + fut = self.dut.MSK_Status.demod_sync_lock # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,0) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,0) + self.assertEqual(fut.bitmask,0x1) + self.assertEqual(fut.inverse_bitmask,0xFFFFFFFE) + self.assertEqual(fut.max_value,0x1) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,True) + with self.subTest(msg='field: msk_top_regs.MSK_Status.tx_enable'): + # test properties of field: msk_top_regs.MSK_Status.tx_enable + fut = self.dut.MSK_Status.tx_enable # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,1) + self.assertEqual(fut.msb,1) + self.assertEqual(fut.low,1) + self.assertEqual(fut.high,1) + self.assertEqual(fut.bitmask,0x2) + self.assertEqual(fut.inverse_bitmask,0xFFFFFFFD) + self.assertEqual(fut.max_value,0x1) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,True) + with self.subTest(msg='field: msk_top_regs.MSK_Status.rx_enable'): + # test properties of field: msk_top_regs.MSK_Status.rx_enable + fut = self.dut.MSK_Status.rx_enable # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,2) + self.assertEqual(fut.msb,2) + self.assertEqual(fut.low,2) + self.assertEqual(fut.high,2) + self.assertEqual(fut.bitmask,0x4) + self.assertEqual(fut.inverse_bitmask,0xFFFFFFFB) + self.assertEqual(fut.max_value,0x1) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,True) + with self.subTest(msg='field: msk_top_regs.MSK_Status.tx_axis_valid'): + # test properties of field: msk_top_regs.MSK_Status.tx_axis_valid + fut = self.dut.MSK_Status.tx_axis_valid # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,3) + self.assertEqual(fut.msb,3) + self.assertEqual(fut.low,3) + self.assertEqual(fut.high,3) + self.assertEqual(fut.bitmask,0x8) + self.assertEqual(fut.inverse_bitmask,0xFFFFFFF7) + self.assertEqual(fut.max_value,0x1) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,True) + with self.subTest(msg='field: msk_top_regs.Tx_Bit_Count.data'): + # test properties of field: msk_top_regs.Tx_Bit_Count.data + fut = self.dut.Tx_Bit_Count.data # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,31) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,31) + self.assertEqual(fut.bitmask,0xFFFFFFFF) + self.assertEqual(fut.inverse_bitmask,0x0) + self.assertEqual(fut.max_value,0xFFFFFFFF) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,True) + with self.subTest(msg='field: msk_top_regs.Tx_Enable_Count.data'): + # test properties of field: msk_top_regs.Tx_Enable_Count.data + fut = self.dut.Tx_Enable_Count.data # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,31) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,31) + self.assertEqual(fut.bitmask,0xFFFFFFFF) + self.assertEqual(fut.inverse_bitmask,0x0) + self.assertEqual(fut.max_value,0xFFFFFFFF) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,True) + with self.subTest(msg='field: msk_top_regs.Fb_FreqWord.config_data'): + # test properties of field: msk_top_regs.Fb_FreqWord.config_data + fut = self.dut.Fb_FreqWord.config_data # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,31) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,31) + self.assertEqual(fut.bitmask,0xFFFFFFFF) + self.assertEqual(fut.inverse_bitmask,0x0) + self.assertEqual(fut.max_value,0xFFFFFFFF) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.TX_F1_FreqWord.config_data'): + # test properties of field: msk_top_regs.TX_F1_FreqWord.config_data + fut = self.dut.TX_F1_FreqWord.config_data # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,31) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,31) + self.assertEqual(fut.bitmask,0xFFFFFFFF) + self.assertEqual(fut.inverse_bitmask,0x0) + self.assertEqual(fut.max_value,0xFFFFFFFF) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.TX_F2_FreqWord.config_data'): + # test properties of field: msk_top_regs.TX_F2_FreqWord.config_data + fut = self.dut.TX_F2_FreqWord.config_data # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,31) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,31) + self.assertEqual(fut.bitmask,0xFFFFFFFF) + self.assertEqual(fut.inverse_bitmask,0x0) + self.assertEqual(fut.max_value,0xFFFFFFFF) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.RX_F1_FreqWord.config_data'): + # test properties of field: msk_top_regs.RX_F1_FreqWord.config_data + fut = self.dut.RX_F1_FreqWord.config_data # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,31) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,31) + self.assertEqual(fut.bitmask,0xFFFFFFFF) + self.assertEqual(fut.inverse_bitmask,0x0) + self.assertEqual(fut.max_value,0xFFFFFFFF) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.RX_F2_FreqWord.config_data'): + # test properties of field: msk_top_regs.RX_F2_FreqWord.config_data + fut = self.dut.RX_F2_FreqWord.config_data # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,31) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,31) + self.assertEqual(fut.bitmask,0xFFFFFFFF) + self.assertEqual(fut.inverse_bitmask,0x0) + self.assertEqual(fut.max_value,0xFFFFFFFF) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.LPF_Config_0.lpf_freeze'): + # test properties of field: msk_top_regs.LPF_Config_0.lpf_freeze + fut = self.dut.LPF_Config_0.lpf_freeze # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,0) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,0) + self.assertEqual(fut.bitmask,0x1) + self.assertEqual(fut.inverse_bitmask,0xFFFFFFFE) + self.assertEqual(fut.max_value,0x1) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.LPF_Config_0.lpf_zero'): + # test properties of field: msk_top_regs.LPF_Config_0.lpf_zero + fut = self.dut.LPF_Config_0.lpf_zero # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,1) + self.assertEqual(fut.msb,1) + self.assertEqual(fut.low,1) + self.assertEqual(fut.high,1) + self.assertEqual(fut.bitmask,0x2) + self.assertEqual(fut.inverse_bitmask,0xFFFFFFFD) + self.assertEqual(fut.max_value,0x1) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.LPF_Config_0.prbs_reserved'): + # test properties of field: msk_top_regs.LPF_Config_0.prbs_reserved + fut = self.dut.LPF_Config_0.prbs_reserved # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,2) + self.assertEqual(fut.msb,7) + self.assertEqual(fut.low,2) + self.assertEqual(fut.high,7) + self.assertEqual(fut.bitmask,0xFC) + self.assertEqual(fut.inverse_bitmask,0xFFFFFF03) + self.assertEqual(fut.max_value,0x3F) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.LPF_Config_0.lpf_alpha'): + # test properties of field: msk_top_regs.LPF_Config_0.lpf_alpha + fut = self.dut.LPF_Config_0.lpf_alpha # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,8) + self.assertEqual(fut.msb,31) + self.assertEqual(fut.low,8) + self.assertEqual(fut.high,31) + self.assertEqual(fut.bitmask,0xFFFFFF00) + self.assertEqual(fut.inverse_bitmask,0xFF) + self.assertEqual(fut.max_value,0xFFFFFF) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.LPF_Config_1.i_gain'): + # test properties of field: msk_top_regs.LPF_Config_1.i_gain + fut = self.dut.LPF_Config_1.i_gain # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,23) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,23) + self.assertEqual(fut.bitmask,0xFFFFFF) + self.assertEqual(fut.inverse_bitmask,0xFF000000) + self.assertEqual(fut.max_value,0xFFFFFF) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.LPF_Config_1.i_shift'): + # test properties of field: msk_top_regs.LPF_Config_1.i_shift + fut = self.dut.LPF_Config_1.i_shift # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,24) + self.assertEqual(fut.msb,31) + self.assertEqual(fut.low,24) + self.assertEqual(fut.high,31) + self.assertEqual(fut.bitmask,0xFF000000) + self.assertEqual(fut.inverse_bitmask,0xFFFFFF) + self.assertEqual(fut.max_value,0xFF) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.Tx_Data_Width.data_width'): + # test properties of field: msk_top_regs.Tx_Data_Width.data_width + fut = self.dut.Tx_Data_Width.data_width # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,7) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,7) + self.assertEqual(fut.bitmask,0xFF) + self.assertEqual(fut.inverse_bitmask,0xFFFFFF00) + self.assertEqual(fut.max_value,0xFF) + + self.assertEqual(fut.default,8) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.Rx_Data_Width.data_width'): + # test properties of field: msk_top_regs.Rx_Data_Width.data_width + fut = self.dut.Rx_Data_Width.data_width # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,7) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,7) + self.assertEqual(fut.bitmask,0xFF) + self.assertEqual(fut.inverse_bitmask,0xFFFFFF00) + self.assertEqual(fut.max_value,0xFF) + + self.assertEqual(fut.default,8) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.PRBS_Control.prbs_sel'): + # test properties of field: msk_top_regs.PRBS_Control.prbs_sel + fut = self.dut.PRBS_Control.prbs_sel # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,0) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,0) + self.assertEqual(fut.bitmask,0x1) + self.assertEqual(fut.inverse_bitmask,0xFFFFFFFE) + self.assertEqual(fut.max_value,0x1) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.PRBS_Control.prbs_error_insert'): + # test properties of field: msk_top_regs.PRBS_Control.prbs_error_insert + fut = self.dut.PRBS_Control.prbs_error_insert # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,1) + self.assertEqual(fut.msb,1) + self.assertEqual(fut.low,1) + self.assertEqual(fut.high,1) + self.assertEqual(fut.bitmask,0x2) + self.assertEqual(fut.inverse_bitmask,0xFFFFFFFD) + self.assertEqual(fut.max_value,0x1) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.PRBS_Control.prbs_clear'): + # test properties of field: msk_top_regs.PRBS_Control.prbs_clear + fut = self.dut.PRBS_Control.prbs_clear # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,2) + self.assertEqual(fut.msb,2) + self.assertEqual(fut.low,2) + self.assertEqual(fut.high,2) + self.assertEqual(fut.bitmask,0x4) + self.assertEqual(fut.inverse_bitmask,0xFFFFFFFB) + self.assertEqual(fut.max_value,0x1) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.PRBS_Control.prbs_manual_sync'): + # test properties of field: msk_top_regs.PRBS_Control.prbs_manual_sync + fut = self.dut.PRBS_Control.prbs_manual_sync # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,3) + self.assertEqual(fut.msb,3) + self.assertEqual(fut.low,3) + self.assertEqual(fut.high,3) + self.assertEqual(fut.bitmask,0x8) + self.assertEqual(fut.inverse_bitmask,0xFFFFFFF7) + self.assertEqual(fut.max_value,0x1) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.PRBS_Control.prbs_reserved'): + # test properties of field: msk_top_regs.PRBS_Control.prbs_reserved + fut = self.dut.PRBS_Control.prbs_reserved # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,4) + self.assertEqual(fut.msb,15) + self.assertEqual(fut.low,4) + self.assertEqual(fut.high,15) + self.assertEqual(fut.bitmask,0xFFF0) + self.assertEqual(fut.inverse_bitmask,0xFFFF000F) + self.assertEqual(fut.max_value,0xFFF) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.PRBS_Control.prbs_sync_threshold'): + # test properties of field: msk_top_regs.PRBS_Control.prbs_sync_threshold + fut = self.dut.PRBS_Control.prbs_sync_threshold # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,16) + self.assertEqual(fut.msb,31) + self.assertEqual(fut.low,16) + self.assertEqual(fut.high,31) + self.assertEqual(fut.bitmask,0xFFFF0000) + self.assertEqual(fut.inverse_bitmask,0xFFFF) + self.assertEqual(fut.max_value,0xFFFF) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.PRBS_Initial_State.config_data'): + # test properties of field: msk_top_regs.PRBS_Initial_State.config_data + fut = self.dut.PRBS_Initial_State.config_data # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,31) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,31) + self.assertEqual(fut.bitmask,0xFFFFFFFF) + self.assertEqual(fut.inverse_bitmask,0x0) + self.assertEqual(fut.max_value,0xFFFFFFFF) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.PRBS_Polynomial.config_data'): + # test properties of field: msk_top_regs.PRBS_Polynomial.config_data + fut = self.dut.PRBS_Polynomial.config_data # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,31) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,31) + self.assertEqual(fut.bitmask,0xFFFFFFFF) + self.assertEqual(fut.inverse_bitmask,0x0) + self.assertEqual(fut.max_value,0xFFFFFFFF) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.PRBS_Error_Mask.config_data'): + # test properties of field: msk_top_regs.PRBS_Error_Mask.config_data + fut = self.dut.PRBS_Error_Mask.config_data # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,31) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,31) + self.assertEqual(fut.bitmask,0xFFFFFFFF) + self.assertEqual(fut.inverse_bitmask,0x0) + self.assertEqual(fut.max_value,0xFFFFFFFF) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.PRBS_Bit_Count.data'): + # test properties of field: msk_top_regs.PRBS_Bit_Count.data + fut = self.dut.PRBS_Bit_Count.data # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,31) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,31) + self.assertEqual(fut.bitmask,0xFFFFFFFF) + self.assertEqual(fut.inverse_bitmask,0x0) + self.assertEqual(fut.max_value,0xFFFFFFFF) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,True) + with self.subTest(msg='field: msk_top_regs.PRBS_Error_Count.data'): + # test properties of field: msk_top_regs.PRBS_Error_Count.data + fut = self.dut.PRBS_Error_Count.data # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,31) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,31) + self.assertEqual(fut.bitmask,0xFFFFFFFF) + self.assertEqual(fut.inverse_bitmask,0x0) + self.assertEqual(fut.max_value,0xFFFFFFFF) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,True) + with self.subTest(msg='field: msk_top_regs.LPF_Accum_F1.data'): + # test properties of field: msk_top_regs.LPF_Accum_F1.data + fut = self.dut.LPF_Accum_F1.data # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,31) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,31) + self.assertEqual(fut.bitmask,0xFFFFFFFF) + self.assertEqual(fut.inverse_bitmask,0x0) + self.assertEqual(fut.max_value,0xFFFFFFFF) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,True) + with self.subTest(msg='field: msk_top_regs.LPF_Accum_F2.data'): + # test properties of field: msk_top_regs.LPF_Accum_F2.data + fut = self.dut.LPF_Accum_F2.data # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,31) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,31) + self.assertEqual(fut.bitmask,0xFFFFFFFF) + self.assertEqual(fut.inverse_bitmask,0x0) + self.assertEqual(fut.max_value,0xFFFFFFFF) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,True) + with self.subTest(msg='field: msk_top_regs.axis_xfer_count.data'): + # test properties of field: msk_top_regs.axis_xfer_count.data + fut = self.dut.axis_xfer_count.data # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,31) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,31) + self.assertEqual(fut.bitmask,0xFFFFFFFF) + self.assertEqual(fut.inverse_bitmask,0x0) + self.assertEqual(fut.max_value,0xFFFFFFFF) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,True) + with self.subTest(msg='field: msk_top_regs.Rx_Sample_Discard.rx_sample_discard'): + # test properties of field: msk_top_regs.Rx_Sample_Discard.rx_sample_discard + fut = self.dut.Rx_Sample_Discard.rx_sample_discard # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,7) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,7) + self.assertEqual(fut.bitmask,0xFF) + self.assertEqual(fut.inverse_bitmask,0xFFFFFF00) + self.assertEqual(fut.max_value,0xFF) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.Rx_Sample_Discard.rx_nco_discard'): + # test properties of field: msk_top_regs.Rx_Sample_Discard.rx_nco_discard + fut = self.dut.Rx_Sample_Discard.rx_nco_discard # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,8) + self.assertEqual(fut.msb,15) + self.assertEqual(fut.low,8) + self.assertEqual(fut.high,15) + self.assertEqual(fut.bitmask,0xFF00) + self.assertEqual(fut.inverse_bitmask,0xFFFF00FF) + self.assertEqual(fut.max_value,0xFF) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.LPF_Config_2.p_gain'): + # test properties of field: msk_top_regs.LPF_Config_2.p_gain + fut = self.dut.LPF_Config_2.p_gain # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,23) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,23) + self.assertEqual(fut.bitmask,0xFFFFFF) + self.assertEqual(fut.inverse_bitmask,0xFF000000) + self.assertEqual(fut.max_value,0xFFFFFF) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.LPF_Config_2.p_shift'): + # test properties of field: msk_top_regs.LPF_Config_2.p_shift + fut = self.dut.LPF_Config_2.p_shift # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,24) + self.assertEqual(fut.msb,31) + self.assertEqual(fut.low,24) + self.assertEqual(fut.high,31) + self.assertEqual(fut.bitmask,0xFF000000) + self.assertEqual(fut.inverse_bitmask,0xFFFFFF) + self.assertEqual(fut.max_value,0xFF) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.f1_nco_adjust.data'): + # test properties of field: msk_top_regs.f1_nco_adjust.data + fut = self.dut.f1_nco_adjust.data # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,31) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,31) + self.assertEqual(fut.bitmask,0xFFFFFFFF) + self.assertEqual(fut.inverse_bitmask,0x0) + self.assertEqual(fut.max_value,0xFFFFFFFF) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,True) + with self.subTest(msg='field: msk_top_regs.f2_nco_adjust.data'): + # test properties of field: msk_top_regs.f2_nco_adjust.data + fut = self.dut.f2_nco_adjust.data # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,31) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,31) + self.assertEqual(fut.bitmask,0xFFFFFFFF) + self.assertEqual(fut.inverse_bitmask,0x0) + self.assertEqual(fut.max_value,0xFFFFFFFF) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,True) + with self.subTest(msg='field: msk_top_regs.f1_error.data'): + # test properties of field: msk_top_regs.f1_error.data + fut = self.dut.f1_error.data # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,31) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,31) + self.assertEqual(fut.bitmask,0xFFFFFFFF) + self.assertEqual(fut.inverse_bitmask,0x0) + self.assertEqual(fut.max_value,0xFFFFFFFF) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,True) + with self.subTest(msg='field: msk_top_regs.f2_error.data'): + # test properties of field: msk_top_regs.f2_error.data + fut = self.dut.f2_error.data # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,31) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,31) + self.assertEqual(fut.bitmask,0xFFFFFFFF) + self.assertEqual(fut.inverse_bitmask,0x0) + self.assertEqual(fut.max_value,0xFFFFFFFF) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,True) + with self.subTest(msg='field: msk_top_regs.Tx_Sync_Ctrl.tx_sync_ena'): + # test properties of field: msk_top_regs.Tx_Sync_Ctrl.tx_sync_ena + fut = self.dut.Tx_Sync_Ctrl.tx_sync_ena # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,0) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,0) + self.assertEqual(fut.bitmask,0x1) + self.assertEqual(fut.inverse_bitmask,0xFFFFFFFE) + self.assertEqual(fut.max_value,0x1) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.Tx_Sync_Ctrl.tx_sync_force'): + # test properties of field: msk_top_regs.Tx_Sync_Ctrl.tx_sync_force + fut = self.dut.Tx_Sync_Ctrl.tx_sync_force # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,1) + self.assertEqual(fut.msb,1) + self.assertEqual(fut.low,1) + self.assertEqual(fut.high,1) + self.assertEqual(fut.bitmask,0x2) + self.assertEqual(fut.inverse_bitmask,0xFFFFFFFD) + self.assertEqual(fut.max_value,0x1) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.Tx_Sync_Cnt.tx_sync_cnt'): + # test properties of field: msk_top_regs.Tx_Sync_Cnt.tx_sync_cnt + fut = self.dut.Tx_Sync_Cnt.tx_sync_cnt # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,23) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,23) + self.assertEqual(fut.bitmask,0xFFFFFF) + self.assertEqual(fut.inverse_bitmask,0xFF000000) + self.assertEqual(fut.max_value,0xFFFFFF) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.lowpass_ema_alpha1.alpha'): + # test properties of field: msk_top_regs.lowpass_ema_alpha1.alpha + fut = self.dut.lowpass_ema_alpha1.alpha # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,17) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,17) + self.assertEqual(fut.bitmask,0x3FFFF) + self.assertEqual(fut.inverse_bitmask,0xFFFC0000) + self.assertEqual(fut.max_value,0x3FFFF) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.lowpass_ema_alpha2.alpha'): + # test properties of field: msk_top_regs.lowpass_ema_alpha2.alpha + fut = self.dut.lowpass_ema_alpha2.alpha # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,17) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,17) + self.assertEqual(fut.bitmask,0x3FFFF) + self.assertEqual(fut.inverse_bitmask,0xFFFC0000) + self.assertEqual(fut.max_value,0x3FFFF) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,False) + with self.subTest(msg='field: msk_top_regs.rx_power.data'): + # test properties of field: msk_top_regs.rx_power.data + fut = self.dut.rx_power.data # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,22) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,22) + self.assertEqual(fut.bitmask,0x7FFFFF) + self.assertEqual(fut.inverse_bitmask,0xFF800000) + self.assertEqual(fut.max_value,0x7FFFFF) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,True) + with self.subTest(msg='field: msk_top_regs.tx_async_fifo_rd_wr_ptr.data'): + # test properties of field: msk_top_regs.tx_async_fifo_rd_wr_ptr.data + fut = self.dut.tx_async_fifo_rd_wr_ptr.data # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,31) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,31) + self.assertEqual(fut.bitmask,0xFFFFFFFF) + self.assertEqual(fut.inverse_bitmask,0x0) + self.assertEqual(fut.max_value,0xFFFFFFFF) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,True) + with self.subTest(msg='field: msk_top_regs.rx_async_fifo_rd_wr_ptr.data'): + # test properties of field: msk_top_regs.rx_async_fifo_rd_wr_ptr.data + fut = self.dut.rx_async_fifo_rd_wr_ptr.data # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,31) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,31) + self.assertEqual(fut.bitmask,0xFFFFFFFF) + self.assertEqual(fut.inverse_bitmask,0x0) + self.assertEqual(fut.max_value,0xFFFFFFFF) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,True) + with self.subTest(msg='field: msk_top_regs.rx_frame_sync_status.frame_sync_locked'): + # test properties of field: msk_top_regs.rx_frame_sync_status.frame_sync_locked + fut = self.dut.rx_frame_sync_status.frame_sync_locked # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,0) + self.assertEqual(fut.msb,0) + self.assertEqual(fut.low,0) + self.assertEqual(fut.high,0) + self.assertEqual(fut.bitmask,0x1) + self.assertEqual(fut.inverse_bitmask,0xFFFFFFFE) + self.assertEqual(fut.max_value,0x1) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,True) + with self.subTest(msg='field: msk_top_regs.rx_frame_sync_status.frame_buffer_overflow'): + # test properties of field: msk_top_regs.rx_frame_sync_status.frame_buffer_overflow + fut = self.dut.rx_frame_sync_status.frame_buffer_overflow # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,1) + self.assertEqual(fut.msb,1) + self.assertEqual(fut.low,1) + self.assertEqual(fut.high,1) + self.assertEqual(fut.bitmask,0x2) + self.assertEqual(fut.inverse_bitmask,0xFFFFFFFD) + self.assertEqual(fut.max_value,0x1) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,True) + with self.subTest(msg='field: msk_top_regs.rx_frame_sync_status.frames_received'): + # test properties of field: msk_top_regs.rx_frame_sync_status.frames_received + fut = self.dut.rx_frame_sync_status.frames_received # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,2) + self.assertEqual(fut.msb,25) + self.assertEqual(fut.low,2) + self.assertEqual(fut.high,25) + self.assertEqual(fut.bitmask,0x3FFFFFC) + self.assertEqual(fut.inverse_bitmask,0xFC000003) + self.assertEqual(fut.max_value,0xFFFFFF) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,True) + with self.subTest(msg='field: msk_top_regs.rx_frame_sync_status.frame_sync_errors'): + # test properties of field: msk_top_regs.rx_frame_sync_status.frame_sync_errors + fut = self.dut.rx_frame_sync_status.frame_sync_errors # type: ignore[union-attr] + if not isinstance(fut, Field): + raise TypeError('This test relies on node being of type Field') + self.assertEqual(fut.lsb,26) + self.assertEqual(fut.msb,31) + self.assertEqual(fut.low,26) + self.assertEqual(fut.high,31) + self.assertEqual(fut.bitmask,0xFC000000) + self.assertEqual(fut.inverse_bitmask,0x3FFFFFF) + self.assertEqual(fut.max_value,0x3F) + + self.assertEqual(fut.default,0) + + self.assertEqual(fut.is_volatile,True) + + + def test_field_encoding_properties(self) -> None: + """ + Check that enumeration has the name and desc meta data from the systemRDL + """ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + def test_user_defined_properties(self) -> None: + """ + Walk the address map and check user defined properties are correctly pulled up + """ + with self.subTest(msg='register: msk_top_regs.Hash_ID_Low'): + + self.assertDictEqual(self.dut.Hash_ID_Low.udp,{}) + + with self.subTest(msg='register: msk_top_regs.Hash_ID_High'): + + self.assertDictEqual(self.dut.Hash_ID_High.udp,{}) + + with self.subTest(msg='register: msk_top_regs.MSK_Init'): + + self.assertDictEqual(self.dut.MSK_Init.udp,{}) + + with self.subTest(msg='register: msk_top_regs.MSK_Control'): + + self.assertDictEqual(self.dut.MSK_Control.udp,{}) + + with self.subTest(msg='register: msk_top_regs.MSK_Status'): + + self.assertDictEqual(self.dut.MSK_Status.udp,{}) + + with self.subTest(msg='register: msk_top_regs.Tx_Bit_Count'): + + self.assertDictEqual(self.dut.Tx_Bit_Count.udp,{}) + + with self.subTest(msg='register: msk_top_regs.Tx_Enable_Count'): + + self.assertDictEqual(self.dut.Tx_Enable_Count.udp,{}) + + with self.subTest(msg='register: msk_top_regs.Fb_FreqWord'): + + self.assertDictEqual(self.dut.Fb_FreqWord.udp,{}) + + with self.subTest(msg='register: msk_top_regs.TX_F1_FreqWord'): + + self.assertDictEqual(self.dut.TX_F1_FreqWord.udp,{}) + + with self.subTest(msg='register: msk_top_regs.TX_F2_FreqWord'): + + self.assertDictEqual(self.dut.TX_F2_FreqWord.udp,{}) + + with self.subTest(msg='register: msk_top_regs.RX_F1_FreqWord'): + + self.assertDictEqual(self.dut.RX_F1_FreqWord.udp,{}) + + with self.subTest(msg='register: msk_top_regs.RX_F2_FreqWord'): + + self.assertDictEqual(self.dut.RX_F2_FreqWord.udp,{}) + + with self.subTest(msg='register: msk_top_regs.LPF_Config_0'): + + self.assertDictEqual(self.dut.LPF_Config_0.udp,{}) + + with self.subTest(msg='register: msk_top_regs.LPF_Config_1'): + + self.assertDictEqual(self.dut.LPF_Config_1.udp,{}) + + with self.subTest(msg='register: msk_top_regs.Tx_Data_Width'): + + self.assertDictEqual(self.dut.Tx_Data_Width.udp,{}) + + with self.subTest(msg='register: msk_top_regs.Rx_Data_Width'): + + self.assertDictEqual(self.dut.Rx_Data_Width.udp,{}) + + with self.subTest(msg='register: msk_top_regs.PRBS_Control'): + + self.assertDictEqual(self.dut.PRBS_Control.udp,{}) + + with self.subTest(msg='register: msk_top_regs.PRBS_Initial_State'): + + self.assertDictEqual(self.dut.PRBS_Initial_State.udp,{}) + + with self.subTest(msg='register: msk_top_regs.PRBS_Polynomial'): + + self.assertDictEqual(self.dut.PRBS_Polynomial.udp,{}) + + with self.subTest(msg='register: msk_top_regs.PRBS_Error_Mask'): + + self.assertDictEqual(self.dut.PRBS_Error_Mask.udp,{}) + + with self.subTest(msg='register: msk_top_regs.PRBS_Bit_Count'): + + self.assertDictEqual(self.dut.PRBS_Bit_Count.udp,{}) + + with self.subTest(msg='register: msk_top_regs.PRBS_Error_Count'): + + self.assertDictEqual(self.dut.PRBS_Error_Count.udp,{}) + + with self.subTest(msg='register: msk_top_regs.LPF_Accum_F1'): + + self.assertDictEqual(self.dut.LPF_Accum_F1.udp,{}) + + with self.subTest(msg='register: msk_top_regs.LPF_Accum_F2'): + + self.assertDictEqual(self.dut.LPF_Accum_F2.udp,{}) + + with self.subTest(msg='register: msk_top_regs.axis_xfer_count'): + + self.assertDictEqual(self.dut.axis_xfer_count.udp,{}) + + with self.subTest(msg='register: msk_top_regs.Rx_Sample_Discard'): + + self.assertDictEqual(self.dut.Rx_Sample_Discard.udp,{}) + + with self.subTest(msg='register: msk_top_regs.LPF_Config_2'): + + self.assertDictEqual(self.dut.LPF_Config_2.udp,{}) + + with self.subTest(msg='register: msk_top_regs.f1_nco_adjust'): + + self.assertDictEqual(self.dut.f1_nco_adjust.udp,{}) + + with self.subTest(msg='register: msk_top_regs.f2_nco_adjust'): + + self.assertDictEqual(self.dut.f2_nco_adjust.udp,{}) + + with self.subTest(msg='register: msk_top_regs.f1_error'): + + self.assertDictEqual(self.dut.f1_error.udp,{}) + + with self.subTest(msg='register: msk_top_regs.f2_error'): + + self.assertDictEqual(self.dut.f2_error.udp,{}) + + with self.subTest(msg='register: msk_top_regs.Tx_Sync_Ctrl'): + + self.assertDictEqual(self.dut.Tx_Sync_Ctrl.udp,{}) + + with self.subTest(msg='register: msk_top_regs.Tx_Sync_Cnt'): + + self.assertDictEqual(self.dut.Tx_Sync_Cnt.udp,{}) + + with self.subTest(msg='register: msk_top_regs.lowpass_ema_alpha1'): + + self.assertDictEqual(self.dut.lowpass_ema_alpha1.udp,{}) + + with self.subTest(msg='register: msk_top_regs.lowpass_ema_alpha2'): + + self.assertDictEqual(self.dut.lowpass_ema_alpha2.udp,{}) + + with self.subTest(msg='register: msk_top_regs.rx_power'): + + self.assertDictEqual(self.dut.rx_power.udp,{}) + + with self.subTest(msg='register: msk_top_regs.tx_async_fifo_rd_wr_ptr'): + + self.assertDictEqual(self.dut.tx_async_fifo_rd_wr_ptr.udp,{}) + + with self.subTest(msg='register: msk_top_regs.rx_async_fifo_rd_wr_ptr'): + + self.assertDictEqual(self.dut.rx_async_fifo_rd_wr_ptr.udp,{}) + + with self.subTest(msg='register: msk_top_regs.rx_frame_sync_status'): + + self.assertDictEqual(self.dut.rx_frame_sync_status.udp,{}) + + with self.subTest(msg='register: msk_top_regs.Hash_ID_Low.hash_id_lo'): + + self.assertDictEqual(self.dut.Hash_ID_Low.hash_id_lo.udp,{}) + + with self.subTest(msg='register: msk_top_regs.Hash_ID_High.hash_id_hi'): + + self.assertDictEqual(self.dut.Hash_ID_High.hash_id_hi.udp,{}) + + with self.subTest(msg='register: msk_top_regs.MSK_Init.txrxinit'): + + self.assertDictEqual(self.dut.MSK_Init.txrxinit.udp,{}) + + with self.subTest(msg='register: msk_top_regs.MSK_Init.txinit'): + + self.assertDictEqual(self.dut.MSK_Init.txinit.udp,{}) + + with self.subTest(msg='register: msk_top_regs.MSK_Init.rxinit'): + + self.assertDictEqual(self.dut.MSK_Init.rxinit.udp,{}) + + with self.subTest(msg='register: msk_top_regs.MSK_Control.ptt'): + + self.assertDictEqual(self.dut.MSK_Control.ptt.udp,{}) + + with self.subTest(msg='register: msk_top_regs.MSK_Control.loopback_ena'): + + self.assertDictEqual(self.dut.MSK_Control.loopback_ena.udp,{}) + + with self.subTest(msg='register: msk_top_regs.MSK_Control.rx_invert'): + + self.assertDictEqual(self.dut.MSK_Control.rx_invert.udp,{}) + + with self.subTest(msg='register: msk_top_regs.MSK_Control.clear_counts'): + + self.assertDictEqual(self.dut.MSK_Control.clear_counts.udp,{}) + + with self.subTest(msg='register: msk_top_regs.MSK_Control.diff_encoder_loopback'): + + self.assertDictEqual(self.dut.MSK_Control.diff_encoder_loopback.udp,{}) + + with self.subTest(msg='register: msk_top_regs.MSK_Status.demod_sync_lock'): + + self.assertDictEqual(self.dut.MSK_Status.demod_sync_lock.udp,{}) + + with self.subTest(msg='register: msk_top_regs.MSK_Status.tx_enable'): + + self.assertDictEqual(self.dut.MSK_Status.tx_enable.udp,{}) + + with self.subTest(msg='register: msk_top_regs.MSK_Status.rx_enable'): + + self.assertDictEqual(self.dut.MSK_Status.rx_enable.udp,{}) + + with self.subTest(msg='register: msk_top_regs.MSK_Status.tx_axis_valid'): + + self.assertDictEqual(self.dut.MSK_Status.tx_axis_valid.udp,{}) + + with self.subTest(msg='register: msk_top_regs.Tx_Bit_Count.data'): + + self.assertDictEqual(self.dut.Tx_Bit_Count.data.udp,{}) + + with self.subTest(msg='register: msk_top_regs.Tx_Enable_Count.data'): + + self.assertDictEqual(self.dut.Tx_Enable_Count.data.udp,{}) + + with self.subTest(msg='register: msk_top_regs.Fb_FreqWord.config_data'): + + self.assertDictEqual(self.dut.Fb_FreqWord.config_data.udp,{}) + + with self.subTest(msg='register: msk_top_regs.TX_F1_FreqWord.config_data'): + + self.assertDictEqual(self.dut.TX_F1_FreqWord.config_data.udp,{}) + + with self.subTest(msg='register: msk_top_regs.TX_F2_FreqWord.config_data'): + + self.assertDictEqual(self.dut.TX_F2_FreqWord.config_data.udp,{}) + + with self.subTest(msg='register: msk_top_regs.RX_F1_FreqWord.config_data'): + + self.assertDictEqual(self.dut.RX_F1_FreqWord.config_data.udp,{}) + + with self.subTest(msg='register: msk_top_regs.RX_F2_FreqWord.config_data'): + + self.assertDictEqual(self.dut.RX_F2_FreqWord.config_data.udp,{}) + + with self.subTest(msg='register: msk_top_regs.LPF_Config_0.lpf_freeze'): + + self.assertDictEqual(self.dut.LPF_Config_0.lpf_freeze.udp,{}) + + with self.subTest(msg='register: msk_top_regs.LPF_Config_0.lpf_zero'): + + self.assertDictEqual(self.dut.LPF_Config_0.lpf_zero.udp,{}) + + with self.subTest(msg='register: msk_top_regs.LPF_Config_0.prbs_reserved'): + + self.assertDictEqual(self.dut.LPF_Config_0.prbs_reserved.udp,{}) + + with self.subTest(msg='register: msk_top_regs.LPF_Config_0.lpf_alpha'): + + self.assertDictEqual(self.dut.LPF_Config_0.lpf_alpha.udp,{}) + + with self.subTest(msg='register: msk_top_regs.LPF_Config_1.i_gain'): + + self.assertDictEqual(self.dut.LPF_Config_1.i_gain.udp,{}) + + with self.subTest(msg='register: msk_top_regs.LPF_Config_1.i_shift'): + + self.assertDictEqual(self.dut.LPF_Config_1.i_shift.udp,{}) + + with self.subTest(msg='register: msk_top_regs.Tx_Data_Width.data_width'): + + self.assertDictEqual(self.dut.Tx_Data_Width.data_width.udp,{}) + + with self.subTest(msg='register: msk_top_regs.Rx_Data_Width.data_width'): + + self.assertDictEqual(self.dut.Rx_Data_Width.data_width.udp,{}) + + with self.subTest(msg='register: msk_top_regs.PRBS_Control.prbs_sel'): + + self.assertDictEqual(self.dut.PRBS_Control.prbs_sel.udp,{}) + + with self.subTest(msg='register: msk_top_regs.PRBS_Control.prbs_error_insert'): + + self.assertDictEqual(self.dut.PRBS_Control.prbs_error_insert.udp,{}) + + with self.subTest(msg='register: msk_top_regs.PRBS_Control.prbs_clear'): + + self.assertDictEqual(self.dut.PRBS_Control.prbs_clear.udp,{}) + + with self.subTest(msg='register: msk_top_regs.PRBS_Control.prbs_manual_sync'): + + self.assertDictEqual(self.dut.PRBS_Control.prbs_manual_sync.udp,{}) + + with self.subTest(msg='register: msk_top_regs.PRBS_Control.prbs_reserved'): + + self.assertDictEqual(self.dut.PRBS_Control.prbs_reserved.udp,{}) + + with self.subTest(msg='register: msk_top_regs.PRBS_Control.prbs_sync_threshold'): + + self.assertDictEqual(self.dut.PRBS_Control.prbs_sync_threshold.udp,{}) + + with self.subTest(msg='register: msk_top_regs.PRBS_Initial_State.config_data'): + + self.assertDictEqual(self.dut.PRBS_Initial_State.config_data.udp,{}) + + with self.subTest(msg='register: msk_top_regs.PRBS_Polynomial.config_data'): + + self.assertDictEqual(self.dut.PRBS_Polynomial.config_data.udp,{}) + + with self.subTest(msg='register: msk_top_regs.PRBS_Error_Mask.config_data'): + + self.assertDictEqual(self.dut.PRBS_Error_Mask.config_data.udp,{}) + + with self.subTest(msg='register: msk_top_regs.PRBS_Bit_Count.data'): + + self.assertDictEqual(self.dut.PRBS_Bit_Count.data.udp,{}) + + with self.subTest(msg='register: msk_top_regs.PRBS_Error_Count.data'): + + self.assertDictEqual(self.dut.PRBS_Error_Count.data.udp,{}) + + with self.subTest(msg='register: msk_top_regs.LPF_Accum_F1.data'): + + self.assertDictEqual(self.dut.LPF_Accum_F1.data.udp,{}) + + with self.subTest(msg='register: msk_top_regs.LPF_Accum_F2.data'): + + self.assertDictEqual(self.dut.LPF_Accum_F2.data.udp,{}) + + with self.subTest(msg='register: msk_top_regs.axis_xfer_count.data'): + + self.assertDictEqual(self.dut.axis_xfer_count.data.udp,{}) + + with self.subTest(msg='register: msk_top_regs.Rx_Sample_Discard.rx_sample_discard'): + + self.assertDictEqual(self.dut.Rx_Sample_Discard.rx_sample_discard.udp,{}) + + with self.subTest(msg='register: msk_top_regs.Rx_Sample_Discard.rx_nco_discard'): + + self.assertDictEqual(self.dut.Rx_Sample_Discard.rx_nco_discard.udp,{}) + + with self.subTest(msg='register: msk_top_regs.LPF_Config_2.p_gain'): + + self.assertDictEqual(self.dut.LPF_Config_2.p_gain.udp,{}) + + with self.subTest(msg='register: msk_top_regs.LPF_Config_2.p_shift'): + + self.assertDictEqual(self.dut.LPF_Config_2.p_shift.udp,{}) + + with self.subTest(msg='register: msk_top_regs.f1_nco_adjust.data'): + + self.assertDictEqual(self.dut.f1_nco_adjust.data.udp,{}) + + with self.subTest(msg='register: msk_top_regs.f2_nco_adjust.data'): + + self.assertDictEqual(self.dut.f2_nco_adjust.data.udp,{}) + + with self.subTest(msg='register: msk_top_regs.f1_error.data'): + + self.assertDictEqual(self.dut.f1_error.data.udp,{}) + + with self.subTest(msg='register: msk_top_regs.f2_error.data'): + + self.assertDictEqual(self.dut.f2_error.data.udp,{}) + + with self.subTest(msg='register: msk_top_regs.Tx_Sync_Ctrl.tx_sync_ena'): + + self.assertDictEqual(self.dut.Tx_Sync_Ctrl.tx_sync_ena.udp,{}) + + with self.subTest(msg='register: msk_top_regs.Tx_Sync_Ctrl.tx_sync_force'): + + self.assertDictEqual(self.dut.Tx_Sync_Ctrl.tx_sync_force.udp,{}) + + with self.subTest(msg='register: msk_top_regs.Tx_Sync_Cnt.tx_sync_cnt'): + + self.assertDictEqual(self.dut.Tx_Sync_Cnt.tx_sync_cnt.udp,{}) + + with self.subTest(msg='register: msk_top_regs.lowpass_ema_alpha1.alpha'): + + self.assertDictEqual(self.dut.lowpass_ema_alpha1.alpha.udp,{}) + + with self.subTest(msg='register: msk_top_regs.lowpass_ema_alpha2.alpha'): + + self.assertDictEqual(self.dut.lowpass_ema_alpha2.alpha.udp,{}) + + with self.subTest(msg='register: msk_top_regs.rx_power.data'): + + self.assertDictEqual(self.dut.rx_power.data.udp,{}) + + with self.subTest(msg='register: msk_top_regs.tx_async_fifo_rd_wr_ptr.data'): + + self.assertDictEqual(self.dut.tx_async_fifo_rd_wr_ptr.data.udp,{}) + + with self.subTest(msg='register: msk_top_regs.rx_async_fifo_rd_wr_ptr.data'): + + self.assertDictEqual(self.dut.rx_async_fifo_rd_wr_ptr.data.udp,{}) + + with self.subTest(msg='register: msk_top_regs.rx_frame_sync_status.frame_sync_locked'): + + self.assertDictEqual(self.dut.rx_frame_sync_status.frame_sync_locked.udp,{}) + + with self.subTest(msg='register: msk_top_regs.rx_frame_sync_status.frame_buffer_overflow'): + + self.assertDictEqual(self.dut.rx_frame_sync_status.frame_buffer_overflow.udp,{}) + + with self.subTest(msg='register: msk_top_regs.rx_frame_sync_status.frames_received'): + + self.assertDictEqual(self.dut.rx_frame_sync_status.frames_received.udp,{}) + + with self.subTest(msg='register: msk_top_regs.rx_frame_sync_status.frame_sync_errors'): + + self.assertDictEqual(self.dut.rx_frame_sync_status.frame_sync_errors.udp,{}) + + + + async def test_register_read_and_write(self) -> None: + """ + Walk the register map and check every register can be read and written to correctly + """ + rut: Reg + # test access operations (read and/or write) to register: + # msk_top_regs.Hash_ID_Low + with self.subTest(msg='register: msk_top_regs.Hash_ID_Low'): + rut=self.dut.Hash_ID_Low # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=0, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=0, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=0, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=0, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + # test that a non-writable register has no write method and attempting one generates and error + with self.assertRaises(AttributeError): + await rut.write(0) # type: ignore[attr-defined] + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.Hash_ID_High + with self.subTest(msg='register: msk_top_regs.Hash_ID_High'): + rut=self.dut.Hash_ID_High # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=4, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=4, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=4, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=4, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + # test that a non-writable register has no write method and attempting one generates and error + with self.assertRaises(AttributeError): + await rut.write(0) # type: ignore[attr-defined] + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.MSK_Init + with self.subTest(msg='register: msk_top_regs.MSK_Init'): + rut=self.dut.MSK_Init # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=8, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=8, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=8, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=8, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + if not isinstance(rut, (RegAsyncWriteOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Writeable Async Type') + + # test the write with high value + await rut.write(0xFFFFFFFF) + write_callback_mock.assert_called_once_with( + addr=8, + width=32, + accesswidth=rut.accesswidth, + data=0xFFFFFFFF) + write_callback_mock.reset_mock() + + # test the write of a low value + await rut.write(0) + write_callback_mock.assert_called_once_with( + addr=8, + width=32, + accesswidth=rut.accesswidth, + data=0) + write_callback_mock.reset_mock() + + # test the write of a random + random_value = random.randrange(0, 0xFFFFFFFF+1) + await rut.write(random_value) # type: ignore[union-attr] + write_callback_mock.assert_called_once_with( + addr=8, + width=32, + accesswidth=rut.accesswidth, + data=random_value) + write_callback_mock.reset_mock() + + # test writing a value beyond the register range is blocked with an exception being raised + with self.assertRaises(ValueError): + await rut.write(-1) + + with self.assertRaises(ValueError): + await rut.write(0xFFFFFFFF+1) + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.MSK_Control + with self.subTest(msg='register: msk_top_regs.MSK_Control'): + rut=self.dut.MSK_Control # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=12, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=12, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=12, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=12, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + if not isinstance(rut, (RegAsyncWriteOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Writeable Async Type') + + # test the write with high value + await rut.write(0xFFFFFFFF) + write_callback_mock.assert_called_once_with( + addr=12, + width=32, + accesswidth=rut.accesswidth, + data=0xFFFFFFFF) + write_callback_mock.reset_mock() + + # test the write of a low value + await rut.write(0) + write_callback_mock.assert_called_once_with( + addr=12, + width=32, + accesswidth=rut.accesswidth, + data=0) + write_callback_mock.reset_mock() + + # test the write of a random + random_value = random.randrange(0, 0xFFFFFFFF+1) + await rut.write(random_value) # type: ignore[union-attr] + write_callback_mock.assert_called_once_with( + addr=12, + width=32, + accesswidth=rut.accesswidth, + data=random_value) + write_callback_mock.reset_mock() + + # test writing a value beyond the register range is blocked with an exception being raised + with self.assertRaises(ValueError): + await rut.write(-1) + + with self.assertRaises(ValueError): + await rut.write(0xFFFFFFFF+1) + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.MSK_Status + with self.subTest(msg='register: msk_top_regs.MSK_Status'): + rut=self.dut.MSK_Status # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=16, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=16, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=16, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=16, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + # test that a non-writable register has no write method and attempting one generates and error + with self.assertRaises(AttributeError): + await rut.write(0) # type: ignore[attr-defined] + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.Tx_Bit_Count + with self.subTest(msg='register: msk_top_regs.Tx_Bit_Count'): + rut=self.dut.Tx_Bit_Count # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=20, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=20, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=20, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=20, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + if not isinstance(rut, (RegAsyncWriteOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Writeable Async Type') + + # test the write with high value + await rut.write(0xFFFFFFFF) + write_callback_mock.assert_called_once_with( + addr=20, + width=32, + accesswidth=rut.accesswidth, + data=0xFFFFFFFF) + write_callback_mock.reset_mock() + + # test the write of a low value + await rut.write(0) + write_callback_mock.assert_called_once_with( + addr=20, + width=32, + accesswidth=rut.accesswidth, + data=0) + write_callback_mock.reset_mock() + + # test the write of a random + random_value = random.randrange(0, 0xFFFFFFFF+1) + await rut.write(random_value) # type: ignore[union-attr] + write_callback_mock.assert_called_once_with( + addr=20, + width=32, + accesswidth=rut.accesswidth, + data=random_value) + write_callback_mock.reset_mock() + + # test writing a value beyond the register range is blocked with an exception being raised + with self.assertRaises(ValueError): + await rut.write(-1) + + with self.assertRaises(ValueError): + await rut.write(0xFFFFFFFF+1) + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.Tx_Enable_Count + with self.subTest(msg='register: msk_top_regs.Tx_Enable_Count'): + rut=self.dut.Tx_Enable_Count # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=24, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=24, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=24, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=24, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + if not isinstance(rut, (RegAsyncWriteOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Writeable Async Type') + + # test the write with high value + await rut.write(0xFFFFFFFF) + write_callback_mock.assert_called_once_with( + addr=24, + width=32, + accesswidth=rut.accesswidth, + data=0xFFFFFFFF) + write_callback_mock.reset_mock() + + # test the write of a low value + await rut.write(0) + write_callback_mock.assert_called_once_with( + addr=24, + width=32, + accesswidth=rut.accesswidth, + data=0) + write_callback_mock.reset_mock() + + # test the write of a random + random_value = random.randrange(0, 0xFFFFFFFF+1) + await rut.write(random_value) # type: ignore[union-attr] + write_callback_mock.assert_called_once_with( + addr=24, + width=32, + accesswidth=rut.accesswidth, + data=random_value) + write_callback_mock.reset_mock() + + # test writing a value beyond the register range is blocked with an exception being raised + with self.assertRaises(ValueError): + await rut.write(-1) + + with self.assertRaises(ValueError): + await rut.write(0xFFFFFFFF+1) + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.Fb_FreqWord + with self.subTest(msg='register: msk_top_regs.Fb_FreqWord'): + rut=self.dut.Fb_FreqWord # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=28, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=28, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=28, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=28, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + if not isinstance(rut, (RegAsyncWriteOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Writeable Async Type') + + # test the write with high value + await rut.write(0xFFFFFFFF) + write_callback_mock.assert_called_once_with( + addr=28, + width=32, + accesswidth=rut.accesswidth, + data=0xFFFFFFFF) + write_callback_mock.reset_mock() + + # test the write of a low value + await rut.write(0) + write_callback_mock.assert_called_once_with( + addr=28, + width=32, + accesswidth=rut.accesswidth, + data=0) + write_callback_mock.reset_mock() + + # test the write of a random + random_value = random.randrange(0, 0xFFFFFFFF+1) + await rut.write(random_value) # type: ignore[union-attr] + write_callback_mock.assert_called_once_with( + addr=28, + width=32, + accesswidth=rut.accesswidth, + data=random_value) + write_callback_mock.reset_mock() + + # test writing a value beyond the register range is blocked with an exception being raised + with self.assertRaises(ValueError): + await rut.write(-1) + + with self.assertRaises(ValueError): + await rut.write(0xFFFFFFFF+1) + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.TX_F1_FreqWord + with self.subTest(msg='register: msk_top_regs.TX_F1_FreqWord'): + rut=self.dut.TX_F1_FreqWord # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=32, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=32, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=32, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=32, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + if not isinstance(rut, (RegAsyncWriteOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Writeable Async Type') + + # test the write with high value + await rut.write(0xFFFFFFFF) + write_callback_mock.assert_called_once_with( + addr=32, + width=32, + accesswidth=rut.accesswidth, + data=0xFFFFFFFF) + write_callback_mock.reset_mock() + + # test the write of a low value + await rut.write(0) + write_callback_mock.assert_called_once_with( + addr=32, + width=32, + accesswidth=rut.accesswidth, + data=0) + write_callback_mock.reset_mock() + + # test the write of a random + random_value = random.randrange(0, 0xFFFFFFFF+1) + await rut.write(random_value) # type: ignore[union-attr] + write_callback_mock.assert_called_once_with( + addr=32, + width=32, + accesswidth=rut.accesswidth, + data=random_value) + write_callback_mock.reset_mock() + + # test writing a value beyond the register range is blocked with an exception being raised + with self.assertRaises(ValueError): + await rut.write(-1) + + with self.assertRaises(ValueError): + await rut.write(0xFFFFFFFF+1) + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.TX_F2_FreqWord + with self.subTest(msg='register: msk_top_regs.TX_F2_FreqWord'): + rut=self.dut.TX_F2_FreqWord # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=36, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=36, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=36, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=36, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + if not isinstance(rut, (RegAsyncWriteOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Writeable Async Type') + + # test the write with high value + await rut.write(0xFFFFFFFF) + write_callback_mock.assert_called_once_with( + addr=36, + width=32, + accesswidth=rut.accesswidth, + data=0xFFFFFFFF) + write_callback_mock.reset_mock() + + # test the write of a low value + await rut.write(0) + write_callback_mock.assert_called_once_with( + addr=36, + width=32, + accesswidth=rut.accesswidth, + data=0) + write_callback_mock.reset_mock() + + # test the write of a random + random_value = random.randrange(0, 0xFFFFFFFF+1) + await rut.write(random_value) # type: ignore[union-attr] + write_callback_mock.assert_called_once_with( + addr=36, + width=32, + accesswidth=rut.accesswidth, + data=random_value) + write_callback_mock.reset_mock() + + # test writing a value beyond the register range is blocked with an exception being raised + with self.assertRaises(ValueError): + await rut.write(-1) + + with self.assertRaises(ValueError): + await rut.write(0xFFFFFFFF+1) + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.RX_F1_FreqWord + with self.subTest(msg='register: msk_top_regs.RX_F1_FreqWord'): + rut=self.dut.RX_F1_FreqWord # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=40, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=40, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=40, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=40, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + if not isinstance(rut, (RegAsyncWriteOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Writeable Async Type') + + # test the write with high value + await rut.write(0xFFFFFFFF) + write_callback_mock.assert_called_once_with( + addr=40, + width=32, + accesswidth=rut.accesswidth, + data=0xFFFFFFFF) + write_callback_mock.reset_mock() + + # test the write of a low value + await rut.write(0) + write_callback_mock.assert_called_once_with( + addr=40, + width=32, + accesswidth=rut.accesswidth, + data=0) + write_callback_mock.reset_mock() + + # test the write of a random + random_value = random.randrange(0, 0xFFFFFFFF+1) + await rut.write(random_value) # type: ignore[union-attr] + write_callback_mock.assert_called_once_with( + addr=40, + width=32, + accesswidth=rut.accesswidth, + data=random_value) + write_callback_mock.reset_mock() + + # test writing a value beyond the register range is blocked with an exception being raised + with self.assertRaises(ValueError): + await rut.write(-1) + + with self.assertRaises(ValueError): + await rut.write(0xFFFFFFFF+1) + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.RX_F2_FreqWord + with self.subTest(msg='register: msk_top_regs.RX_F2_FreqWord'): + rut=self.dut.RX_F2_FreqWord # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=44, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=44, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=44, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=44, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + if not isinstance(rut, (RegAsyncWriteOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Writeable Async Type') + + # test the write with high value + await rut.write(0xFFFFFFFF) + write_callback_mock.assert_called_once_with( + addr=44, + width=32, + accesswidth=rut.accesswidth, + data=0xFFFFFFFF) + write_callback_mock.reset_mock() + + # test the write of a low value + await rut.write(0) + write_callback_mock.assert_called_once_with( + addr=44, + width=32, + accesswidth=rut.accesswidth, + data=0) + write_callback_mock.reset_mock() + + # test the write of a random + random_value = random.randrange(0, 0xFFFFFFFF+1) + await rut.write(random_value) # type: ignore[union-attr] + write_callback_mock.assert_called_once_with( + addr=44, + width=32, + accesswidth=rut.accesswidth, + data=random_value) + write_callback_mock.reset_mock() + + # test writing a value beyond the register range is blocked with an exception being raised + with self.assertRaises(ValueError): + await rut.write(-1) + + with self.assertRaises(ValueError): + await rut.write(0xFFFFFFFF+1) + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.LPF_Config_0 + with self.subTest(msg='register: msk_top_regs.LPF_Config_0'): + rut=self.dut.LPF_Config_0 # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=48, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=48, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=48, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=48, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + if not isinstance(rut, (RegAsyncWriteOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Writeable Async Type') + + # test the write with high value + await rut.write(0xFFFFFFFF) + write_callback_mock.assert_called_once_with( + addr=48, + width=32, + accesswidth=rut.accesswidth, + data=0xFFFFFFFF) + write_callback_mock.reset_mock() + + # test the write of a low value + await rut.write(0) + write_callback_mock.assert_called_once_with( + addr=48, + width=32, + accesswidth=rut.accesswidth, + data=0) + write_callback_mock.reset_mock() + + # test the write of a random + random_value = random.randrange(0, 0xFFFFFFFF+1) + await rut.write(random_value) # type: ignore[union-attr] + write_callback_mock.assert_called_once_with( + addr=48, + width=32, + accesswidth=rut.accesswidth, + data=random_value) + write_callback_mock.reset_mock() + + # test writing a value beyond the register range is blocked with an exception being raised + with self.assertRaises(ValueError): + await rut.write(-1) + + with self.assertRaises(ValueError): + await rut.write(0xFFFFFFFF+1) + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.LPF_Config_1 + with self.subTest(msg='register: msk_top_regs.LPF_Config_1'): + rut=self.dut.LPF_Config_1 # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=52, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=52, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=52, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=52, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + if not isinstance(rut, (RegAsyncWriteOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Writeable Async Type') + + # test the write with high value + await rut.write(0xFFFFFFFF) + write_callback_mock.assert_called_once_with( + addr=52, + width=32, + accesswidth=rut.accesswidth, + data=0xFFFFFFFF) + write_callback_mock.reset_mock() + + # test the write of a low value + await rut.write(0) + write_callback_mock.assert_called_once_with( + addr=52, + width=32, + accesswidth=rut.accesswidth, + data=0) + write_callback_mock.reset_mock() + + # test the write of a random + random_value = random.randrange(0, 0xFFFFFFFF+1) + await rut.write(random_value) # type: ignore[union-attr] + write_callback_mock.assert_called_once_with( + addr=52, + width=32, + accesswidth=rut.accesswidth, + data=random_value) + write_callback_mock.reset_mock() + + # test writing a value beyond the register range is blocked with an exception being raised + with self.assertRaises(ValueError): + await rut.write(-1) + + with self.assertRaises(ValueError): + await rut.write(0xFFFFFFFF+1) + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.Tx_Data_Width + with self.subTest(msg='register: msk_top_regs.Tx_Data_Width'): + rut=self.dut.Tx_Data_Width # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=56, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=56, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=56, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=56, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + if not isinstance(rut, (RegAsyncWriteOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Writeable Async Type') + + # test the write with high value + await rut.write(0xFFFFFFFF) + write_callback_mock.assert_called_once_with( + addr=56, + width=32, + accesswidth=rut.accesswidth, + data=0xFFFFFFFF) + write_callback_mock.reset_mock() + + # test the write of a low value + await rut.write(0) + write_callback_mock.assert_called_once_with( + addr=56, + width=32, + accesswidth=rut.accesswidth, + data=0) + write_callback_mock.reset_mock() + + # test the write of a random + random_value = random.randrange(0, 0xFFFFFFFF+1) + await rut.write(random_value) # type: ignore[union-attr] + write_callback_mock.assert_called_once_with( + addr=56, + width=32, + accesswidth=rut.accesswidth, + data=random_value) + write_callback_mock.reset_mock() + + # test writing a value beyond the register range is blocked with an exception being raised + with self.assertRaises(ValueError): + await rut.write(-1) + + with self.assertRaises(ValueError): + await rut.write(0xFFFFFFFF+1) + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.Rx_Data_Width + with self.subTest(msg='register: msk_top_regs.Rx_Data_Width'): + rut=self.dut.Rx_Data_Width # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=60, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=60, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=60, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=60, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + if not isinstance(rut, (RegAsyncWriteOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Writeable Async Type') + + # test the write with high value + await rut.write(0xFFFFFFFF) + write_callback_mock.assert_called_once_with( + addr=60, + width=32, + accesswidth=rut.accesswidth, + data=0xFFFFFFFF) + write_callback_mock.reset_mock() + + # test the write of a low value + await rut.write(0) + write_callback_mock.assert_called_once_with( + addr=60, + width=32, + accesswidth=rut.accesswidth, + data=0) + write_callback_mock.reset_mock() + + # test the write of a random + random_value = random.randrange(0, 0xFFFFFFFF+1) + await rut.write(random_value) # type: ignore[union-attr] + write_callback_mock.assert_called_once_with( + addr=60, + width=32, + accesswidth=rut.accesswidth, + data=random_value) + write_callback_mock.reset_mock() + + # test writing a value beyond the register range is blocked with an exception being raised + with self.assertRaises(ValueError): + await rut.write(-1) + + with self.assertRaises(ValueError): + await rut.write(0xFFFFFFFF+1) + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.PRBS_Control + with self.subTest(msg='register: msk_top_regs.PRBS_Control'): + rut=self.dut.PRBS_Control # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=64, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=64, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=64, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=64, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + if not isinstance(rut, (RegAsyncWriteOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Writeable Async Type') + + # test the write with high value + await rut.write(0xFFFFFFFF) + write_callback_mock.assert_called_once_with( + addr=64, + width=32, + accesswidth=rut.accesswidth, + data=0xFFFFFFFF) + write_callback_mock.reset_mock() + + # test the write of a low value + await rut.write(0) + write_callback_mock.assert_called_once_with( + addr=64, + width=32, + accesswidth=rut.accesswidth, + data=0) + write_callback_mock.reset_mock() + + # test the write of a random + random_value = random.randrange(0, 0xFFFFFFFF+1) + await rut.write(random_value) # type: ignore[union-attr] + write_callback_mock.assert_called_once_with( + addr=64, + width=32, + accesswidth=rut.accesswidth, + data=random_value) + write_callback_mock.reset_mock() + + # test writing a value beyond the register range is blocked with an exception being raised + with self.assertRaises(ValueError): + await rut.write(-1) + + with self.assertRaises(ValueError): + await rut.write(0xFFFFFFFF+1) + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.PRBS_Initial_State + with self.subTest(msg='register: msk_top_regs.PRBS_Initial_State'): + rut=self.dut.PRBS_Initial_State # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=68, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=68, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=68, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=68, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + if not isinstance(rut, (RegAsyncWriteOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Writeable Async Type') + + # test the write with high value + await rut.write(0xFFFFFFFF) + write_callback_mock.assert_called_once_with( + addr=68, + width=32, + accesswidth=rut.accesswidth, + data=0xFFFFFFFF) + write_callback_mock.reset_mock() + + # test the write of a low value + await rut.write(0) + write_callback_mock.assert_called_once_with( + addr=68, + width=32, + accesswidth=rut.accesswidth, + data=0) + write_callback_mock.reset_mock() + + # test the write of a random + random_value = random.randrange(0, 0xFFFFFFFF+1) + await rut.write(random_value) # type: ignore[union-attr] + write_callback_mock.assert_called_once_with( + addr=68, + width=32, + accesswidth=rut.accesswidth, + data=random_value) + write_callback_mock.reset_mock() + + # test writing a value beyond the register range is blocked with an exception being raised + with self.assertRaises(ValueError): + await rut.write(-1) + + with self.assertRaises(ValueError): + await rut.write(0xFFFFFFFF+1) + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.PRBS_Polynomial + with self.subTest(msg='register: msk_top_regs.PRBS_Polynomial'): + rut=self.dut.PRBS_Polynomial # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=72, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=72, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=72, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=72, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + if not isinstance(rut, (RegAsyncWriteOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Writeable Async Type') + + # test the write with high value + await rut.write(0xFFFFFFFF) + write_callback_mock.assert_called_once_with( + addr=72, + width=32, + accesswidth=rut.accesswidth, + data=0xFFFFFFFF) + write_callback_mock.reset_mock() + + # test the write of a low value + await rut.write(0) + write_callback_mock.assert_called_once_with( + addr=72, + width=32, + accesswidth=rut.accesswidth, + data=0) + write_callback_mock.reset_mock() + + # test the write of a random + random_value = random.randrange(0, 0xFFFFFFFF+1) + await rut.write(random_value) # type: ignore[union-attr] + write_callback_mock.assert_called_once_with( + addr=72, + width=32, + accesswidth=rut.accesswidth, + data=random_value) + write_callback_mock.reset_mock() + + # test writing a value beyond the register range is blocked with an exception being raised + with self.assertRaises(ValueError): + await rut.write(-1) + + with self.assertRaises(ValueError): + await rut.write(0xFFFFFFFF+1) + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.PRBS_Error_Mask + with self.subTest(msg='register: msk_top_regs.PRBS_Error_Mask'): + rut=self.dut.PRBS_Error_Mask # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=76, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=76, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=76, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=76, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + if not isinstance(rut, (RegAsyncWriteOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Writeable Async Type') + + # test the write with high value + await rut.write(0xFFFFFFFF) + write_callback_mock.assert_called_once_with( + addr=76, + width=32, + accesswidth=rut.accesswidth, + data=0xFFFFFFFF) + write_callback_mock.reset_mock() + + # test the write of a low value + await rut.write(0) + write_callback_mock.assert_called_once_with( + addr=76, + width=32, + accesswidth=rut.accesswidth, + data=0) + write_callback_mock.reset_mock() + + # test the write of a random + random_value = random.randrange(0, 0xFFFFFFFF+1) + await rut.write(random_value) # type: ignore[union-attr] + write_callback_mock.assert_called_once_with( + addr=76, + width=32, + accesswidth=rut.accesswidth, + data=random_value) + write_callback_mock.reset_mock() + + # test writing a value beyond the register range is blocked with an exception being raised + with self.assertRaises(ValueError): + await rut.write(-1) + + with self.assertRaises(ValueError): + await rut.write(0xFFFFFFFF+1) + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.PRBS_Bit_Count + with self.subTest(msg='register: msk_top_regs.PRBS_Bit_Count'): + rut=self.dut.PRBS_Bit_Count # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=80, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=80, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=80, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=80, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + if not isinstance(rut, (RegAsyncWriteOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Writeable Async Type') + + # test the write with high value + await rut.write(0xFFFFFFFF) + write_callback_mock.assert_called_once_with( + addr=80, + width=32, + accesswidth=rut.accesswidth, + data=0xFFFFFFFF) + write_callback_mock.reset_mock() + + # test the write of a low value + await rut.write(0) + write_callback_mock.assert_called_once_with( + addr=80, + width=32, + accesswidth=rut.accesswidth, + data=0) + write_callback_mock.reset_mock() + + # test the write of a random + random_value = random.randrange(0, 0xFFFFFFFF+1) + await rut.write(random_value) # type: ignore[union-attr] + write_callback_mock.assert_called_once_with( + addr=80, + width=32, + accesswidth=rut.accesswidth, + data=random_value) + write_callback_mock.reset_mock() + + # test writing a value beyond the register range is blocked with an exception being raised + with self.assertRaises(ValueError): + await rut.write(-1) + + with self.assertRaises(ValueError): + await rut.write(0xFFFFFFFF+1) + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.PRBS_Error_Count + with self.subTest(msg='register: msk_top_regs.PRBS_Error_Count'): + rut=self.dut.PRBS_Error_Count # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=84, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=84, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=84, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=84, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + if not isinstance(rut, (RegAsyncWriteOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Writeable Async Type') + + # test the write with high value + await rut.write(0xFFFFFFFF) + write_callback_mock.assert_called_once_with( + addr=84, + width=32, + accesswidth=rut.accesswidth, + data=0xFFFFFFFF) + write_callback_mock.reset_mock() + + # test the write of a low value + await rut.write(0) + write_callback_mock.assert_called_once_with( + addr=84, + width=32, + accesswidth=rut.accesswidth, + data=0) + write_callback_mock.reset_mock() + + # test the write of a random + random_value = random.randrange(0, 0xFFFFFFFF+1) + await rut.write(random_value) # type: ignore[union-attr] + write_callback_mock.assert_called_once_with( + addr=84, + width=32, + accesswidth=rut.accesswidth, + data=random_value) + write_callback_mock.reset_mock() + + # test writing a value beyond the register range is blocked with an exception being raised + with self.assertRaises(ValueError): + await rut.write(-1) + + with self.assertRaises(ValueError): + await rut.write(0xFFFFFFFF+1) + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.LPF_Accum_F1 + with self.subTest(msg='register: msk_top_regs.LPF_Accum_F1'): + rut=self.dut.LPF_Accum_F1 # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=88, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=88, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=88, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=88, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + if not isinstance(rut, (RegAsyncWriteOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Writeable Async Type') + + # test the write with high value + await rut.write(0xFFFFFFFF) + write_callback_mock.assert_called_once_with( + addr=88, + width=32, + accesswidth=rut.accesswidth, + data=0xFFFFFFFF) + write_callback_mock.reset_mock() + + # test the write of a low value + await rut.write(0) + write_callback_mock.assert_called_once_with( + addr=88, + width=32, + accesswidth=rut.accesswidth, + data=0) + write_callback_mock.reset_mock() + + # test the write of a random + random_value = random.randrange(0, 0xFFFFFFFF+1) + await rut.write(random_value) # type: ignore[union-attr] + write_callback_mock.assert_called_once_with( + addr=88, + width=32, + accesswidth=rut.accesswidth, + data=random_value) + write_callback_mock.reset_mock() + + # test writing a value beyond the register range is blocked with an exception being raised + with self.assertRaises(ValueError): + await rut.write(-1) + + with self.assertRaises(ValueError): + await rut.write(0xFFFFFFFF+1) + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.LPF_Accum_F2 + with self.subTest(msg='register: msk_top_regs.LPF_Accum_F2'): + rut=self.dut.LPF_Accum_F2 # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=92, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=92, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=92, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=92, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + if not isinstance(rut, (RegAsyncWriteOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Writeable Async Type') + + # test the write with high value + await rut.write(0xFFFFFFFF) + write_callback_mock.assert_called_once_with( + addr=92, + width=32, + accesswidth=rut.accesswidth, + data=0xFFFFFFFF) + write_callback_mock.reset_mock() + + # test the write of a low value + await rut.write(0) + write_callback_mock.assert_called_once_with( + addr=92, + width=32, + accesswidth=rut.accesswidth, + data=0) + write_callback_mock.reset_mock() + + # test the write of a random + random_value = random.randrange(0, 0xFFFFFFFF+1) + await rut.write(random_value) # type: ignore[union-attr] + write_callback_mock.assert_called_once_with( + addr=92, + width=32, + accesswidth=rut.accesswidth, + data=random_value) + write_callback_mock.reset_mock() + + # test writing a value beyond the register range is blocked with an exception being raised + with self.assertRaises(ValueError): + await rut.write(-1) + + with self.assertRaises(ValueError): + await rut.write(0xFFFFFFFF+1) + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.axis_xfer_count + with self.subTest(msg='register: msk_top_regs.axis_xfer_count'): + rut=self.dut.axis_xfer_count # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=96, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=96, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=96, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=96, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + if not isinstance(rut, (RegAsyncWriteOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Writeable Async Type') + + # test the write with high value + await rut.write(0xFFFFFFFF) + write_callback_mock.assert_called_once_with( + addr=96, + width=32, + accesswidth=rut.accesswidth, + data=0xFFFFFFFF) + write_callback_mock.reset_mock() + + # test the write of a low value + await rut.write(0) + write_callback_mock.assert_called_once_with( + addr=96, + width=32, + accesswidth=rut.accesswidth, + data=0) + write_callback_mock.reset_mock() + + # test the write of a random + random_value = random.randrange(0, 0xFFFFFFFF+1) + await rut.write(random_value) # type: ignore[union-attr] + write_callback_mock.assert_called_once_with( + addr=96, + width=32, + accesswidth=rut.accesswidth, + data=random_value) + write_callback_mock.reset_mock() + + # test writing a value beyond the register range is blocked with an exception being raised + with self.assertRaises(ValueError): + await rut.write(-1) + + with self.assertRaises(ValueError): + await rut.write(0xFFFFFFFF+1) + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.Rx_Sample_Discard + with self.subTest(msg='register: msk_top_regs.Rx_Sample_Discard'): + rut=self.dut.Rx_Sample_Discard # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=100, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=100, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=100, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=100, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + if not isinstance(rut, (RegAsyncWriteOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Writeable Async Type') + + # test the write with high value + await rut.write(0xFFFFFFFF) + write_callback_mock.assert_called_once_with( + addr=100, + width=32, + accesswidth=rut.accesswidth, + data=0xFFFFFFFF) + write_callback_mock.reset_mock() + + # test the write of a low value + await rut.write(0) + write_callback_mock.assert_called_once_with( + addr=100, + width=32, + accesswidth=rut.accesswidth, + data=0) + write_callback_mock.reset_mock() + + # test the write of a random + random_value = random.randrange(0, 0xFFFFFFFF+1) + await rut.write(random_value) # type: ignore[union-attr] + write_callback_mock.assert_called_once_with( + addr=100, + width=32, + accesswidth=rut.accesswidth, + data=random_value) + write_callback_mock.reset_mock() + + # test writing a value beyond the register range is blocked with an exception being raised + with self.assertRaises(ValueError): + await rut.write(-1) + + with self.assertRaises(ValueError): + await rut.write(0xFFFFFFFF+1) + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.LPF_Config_2 + with self.subTest(msg='register: msk_top_regs.LPF_Config_2'): + rut=self.dut.LPF_Config_2 # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=104, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=104, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=104, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=104, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + if not isinstance(rut, (RegAsyncWriteOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Writeable Async Type') + + # test the write with high value + await rut.write(0xFFFFFFFF) + write_callback_mock.assert_called_once_with( + addr=104, + width=32, + accesswidth=rut.accesswidth, + data=0xFFFFFFFF) + write_callback_mock.reset_mock() + + # test the write of a low value + await rut.write(0) + write_callback_mock.assert_called_once_with( + addr=104, + width=32, + accesswidth=rut.accesswidth, + data=0) + write_callback_mock.reset_mock() + + # test the write of a random + random_value = random.randrange(0, 0xFFFFFFFF+1) + await rut.write(random_value) # type: ignore[union-attr] + write_callback_mock.assert_called_once_with( + addr=104, + width=32, + accesswidth=rut.accesswidth, + data=random_value) + write_callback_mock.reset_mock() + + # test writing a value beyond the register range is blocked with an exception being raised + with self.assertRaises(ValueError): + await rut.write(-1) + + with self.assertRaises(ValueError): + await rut.write(0xFFFFFFFF+1) + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.f1_nco_adjust + with self.subTest(msg='register: msk_top_regs.f1_nco_adjust'): + rut=self.dut.f1_nco_adjust # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=108, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=108, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=108, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=108, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + if not isinstance(rut, (RegAsyncWriteOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Writeable Async Type') + + # test the write with high value + await rut.write(0xFFFFFFFF) + write_callback_mock.assert_called_once_with( + addr=108, + width=32, + accesswidth=rut.accesswidth, + data=0xFFFFFFFF) + write_callback_mock.reset_mock() + + # test the write of a low value + await rut.write(0) + write_callback_mock.assert_called_once_with( + addr=108, + width=32, + accesswidth=rut.accesswidth, + data=0) + write_callback_mock.reset_mock() + + # test the write of a random + random_value = random.randrange(0, 0xFFFFFFFF+1) + await rut.write(random_value) # type: ignore[union-attr] + write_callback_mock.assert_called_once_with( + addr=108, + width=32, + accesswidth=rut.accesswidth, + data=random_value) + write_callback_mock.reset_mock() + + # test writing a value beyond the register range is blocked with an exception being raised + with self.assertRaises(ValueError): + await rut.write(-1) + + with self.assertRaises(ValueError): + await rut.write(0xFFFFFFFF+1) + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.f2_nco_adjust + with self.subTest(msg='register: msk_top_regs.f2_nco_adjust'): + rut=self.dut.f2_nco_adjust # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=112, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=112, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=112, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=112, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + if not isinstance(rut, (RegAsyncWriteOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Writeable Async Type') + + # test the write with high value + await rut.write(0xFFFFFFFF) + write_callback_mock.assert_called_once_with( + addr=112, + width=32, + accesswidth=rut.accesswidth, + data=0xFFFFFFFF) + write_callback_mock.reset_mock() + + # test the write of a low value + await rut.write(0) + write_callback_mock.assert_called_once_with( + addr=112, + width=32, + accesswidth=rut.accesswidth, + data=0) + write_callback_mock.reset_mock() + + # test the write of a random + random_value = random.randrange(0, 0xFFFFFFFF+1) + await rut.write(random_value) # type: ignore[union-attr] + write_callback_mock.assert_called_once_with( + addr=112, + width=32, + accesswidth=rut.accesswidth, + data=random_value) + write_callback_mock.reset_mock() + + # test writing a value beyond the register range is blocked with an exception being raised + with self.assertRaises(ValueError): + await rut.write(-1) + + with self.assertRaises(ValueError): + await rut.write(0xFFFFFFFF+1) + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.f1_error + with self.subTest(msg='register: msk_top_regs.f1_error'): + rut=self.dut.f1_error # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=116, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=116, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=116, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=116, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + if not isinstance(rut, (RegAsyncWriteOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Writeable Async Type') + + # test the write with high value + await rut.write(0xFFFFFFFF) + write_callback_mock.assert_called_once_with( + addr=116, + width=32, + accesswidth=rut.accesswidth, + data=0xFFFFFFFF) + write_callback_mock.reset_mock() + + # test the write of a low value + await rut.write(0) + write_callback_mock.assert_called_once_with( + addr=116, + width=32, + accesswidth=rut.accesswidth, + data=0) + write_callback_mock.reset_mock() + + # test the write of a random + random_value = random.randrange(0, 0xFFFFFFFF+1) + await rut.write(random_value) # type: ignore[union-attr] + write_callback_mock.assert_called_once_with( + addr=116, + width=32, + accesswidth=rut.accesswidth, + data=random_value) + write_callback_mock.reset_mock() + + # test writing a value beyond the register range is blocked with an exception being raised + with self.assertRaises(ValueError): + await rut.write(-1) + + with self.assertRaises(ValueError): + await rut.write(0xFFFFFFFF+1) + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.f2_error + with self.subTest(msg='register: msk_top_regs.f2_error'): + rut=self.dut.f2_error # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=120, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=120, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=120, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=120, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + if not isinstance(rut, (RegAsyncWriteOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Writeable Async Type') + + # test the write with high value + await rut.write(0xFFFFFFFF) + write_callback_mock.assert_called_once_with( + addr=120, + width=32, + accesswidth=rut.accesswidth, + data=0xFFFFFFFF) + write_callback_mock.reset_mock() + + # test the write of a low value + await rut.write(0) + write_callback_mock.assert_called_once_with( + addr=120, + width=32, + accesswidth=rut.accesswidth, + data=0) + write_callback_mock.reset_mock() + + # test the write of a random + random_value = random.randrange(0, 0xFFFFFFFF+1) + await rut.write(random_value) # type: ignore[union-attr] + write_callback_mock.assert_called_once_with( + addr=120, + width=32, + accesswidth=rut.accesswidth, + data=random_value) + write_callback_mock.reset_mock() + + # test writing a value beyond the register range is blocked with an exception being raised + with self.assertRaises(ValueError): + await rut.write(-1) + + with self.assertRaises(ValueError): + await rut.write(0xFFFFFFFF+1) + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.Tx_Sync_Ctrl + with self.subTest(msg='register: msk_top_regs.Tx_Sync_Ctrl'): + rut=self.dut.Tx_Sync_Ctrl # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=124, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=124, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=124, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=124, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + if not isinstance(rut, (RegAsyncWriteOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Writeable Async Type') + + # test the write with high value + await rut.write(0xFFFFFFFF) + write_callback_mock.assert_called_once_with( + addr=124, + width=32, + accesswidth=rut.accesswidth, + data=0xFFFFFFFF) + write_callback_mock.reset_mock() + + # test the write of a low value + await rut.write(0) + write_callback_mock.assert_called_once_with( + addr=124, + width=32, + accesswidth=rut.accesswidth, + data=0) + write_callback_mock.reset_mock() + + # test the write of a random + random_value = random.randrange(0, 0xFFFFFFFF+1) + await rut.write(random_value) # type: ignore[union-attr] + write_callback_mock.assert_called_once_with( + addr=124, + width=32, + accesswidth=rut.accesswidth, + data=random_value) + write_callback_mock.reset_mock() + + # test writing a value beyond the register range is blocked with an exception being raised + with self.assertRaises(ValueError): + await rut.write(-1) + + with self.assertRaises(ValueError): + await rut.write(0xFFFFFFFF+1) + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.Tx_Sync_Cnt + with self.subTest(msg='register: msk_top_regs.Tx_Sync_Cnt'): + rut=self.dut.Tx_Sync_Cnt # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=128, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=128, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=128, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=128, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + if not isinstance(rut, (RegAsyncWriteOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Writeable Async Type') + + # test the write with high value + await rut.write(0xFFFFFFFF) + write_callback_mock.assert_called_once_with( + addr=128, + width=32, + accesswidth=rut.accesswidth, + data=0xFFFFFFFF) + write_callback_mock.reset_mock() + + # test the write of a low value + await rut.write(0) + write_callback_mock.assert_called_once_with( + addr=128, + width=32, + accesswidth=rut.accesswidth, + data=0) + write_callback_mock.reset_mock() + + # test the write of a random + random_value = random.randrange(0, 0xFFFFFFFF+1) + await rut.write(random_value) # type: ignore[union-attr] + write_callback_mock.assert_called_once_with( + addr=128, + width=32, + accesswidth=rut.accesswidth, + data=random_value) + write_callback_mock.reset_mock() + + # test writing a value beyond the register range is blocked with an exception being raised + with self.assertRaises(ValueError): + await rut.write(-1) + + with self.assertRaises(ValueError): + await rut.write(0xFFFFFFFF+1) + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.lowpass_ema_alpha1 + with self.subTest(msg='register: msk_top_regs.lowpass_ema_alpha1'): + rut=self.dut.lowpass_ema_alpha1 # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=132, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=132, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=132, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=132, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + if not isinstance(rut, (RegAsyncWriteOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Writeable Async Type') + + # test the write with high value + await rut.write(0xFFFFFFFF) + write_callback_mock.assert_called_once_with( + addr=132, + width=32, + accesswidth=rut.accesswidth, + data=0xFFFFFFFF) + write_callback_mock.reset_mock() + + # test the write of a low value + await rut.write(0) + write_callback_mock.assert_called_once_with( + addr=132, + width=32, + accesswidth=rut.accesswidth, + data=0) + write_callback_mock.reset_mock() + + # test the write of a random + random_value = random.randrange(0, 0xFFFFFFFF+1) + await rut.write(random_value) # type: ignore[union-attr] + write_callback_mock.assert_called_once_with( + addr=132, + width=32, + accesswidth=rut.accesswidth, + data=random_value) + write_callback_mock.reset_mock() + + # test writing a value beyond the register range is blocked with an exception being raised + with self.assertRaises(ValueError): + await rut.write(-1) + + with self.assertRaises(ValueError): + await rut.write(0xFFFFFFFF+1) + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.lowpass_ema_alpha2 + with self.subTest(msg='register: msk_top_regs.lowpass_ema_alpha2'): + rut=self.dut.lowpass_ema_alpha2 # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=136, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=136, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=136, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=136, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + if not isinstance(rut, (RegAsyncWriteOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Writeable Async Type') + + # test the write with high value + await rut.write(0xFFFFFFFF) + write_callback_mock.assert_called_once_with( + addr=136, + width=32, + accesswidth=rut.accesswidth, + data=0xFFFFFFFF) + write_callback_mock.reset_mock() + + # test the write of a low value + await rut.write(0) + write_callback_mock.assert_called_once_with( + addr=136, + width=32, + accesswidth=rut.accesswidth, + data=0) + write_callback_mock.reset_mock() + + # test the write of a random + random_value = random.randrange(0, 0xFFFFFFFF+1) + await rut.write(random_value) # type: ignore[union-attr] + write_callback_mock.assert_called_once_with( + addr=136, + width=32, + accesswidth=rut.accesswidth, + data=random_value) + write_callback_mock.reset_mock() + + # test writing a value beyond the register range is blocked with an exception being raised + with self.assertRaises(ValueError): + await rut.write(-1) + + with self.assertRaises(ValueError): + await rut.write(0xFFFFFFFF+1) + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.rx_power + with self.subTest(msg='register: msk_top_regs.rx_power'): + rut=self.dut.rx_power # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=140, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=140, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=140, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=140, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + if not isinstance(rut, (RegAsyncWriteOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Writeable Async Type') + + # test the write with high value + await rut.write(0xFFFFFFFF) + write_callback_mock.assert_called_once_with( + addr=140, + width=32, + accesswidth=rut.accesswidth, + data=0xFFFFFFFF) + write_callback_mock.reset_mock() + + # test the write of a low value + await rut.write(0) + write_callback_mock.assert_called_once_with( + addr=140, + width=32, + accesswidth=rut.accesswidth, + data=0) + write_callback_mock.reset_mock() + + # test the write of a random + random_value = random.randrange(0, 0xFFFFFFFF+1) + await rut.write(random_value) # type: ignore[union-attr] + write_callback_mock.assert_called_once_with( + addr=140, + width=32, + accesswidth=rut.accesswidth, + data=random_value) + write_callback_mock.reset_mock() + + # test writing a value beyond the register range is blocked with an exception being raised + with self.assertRaises(ValueError): + await rut.write(-1) + + with self.assertRaises(ValueError): + await rut.write(0xFFFFFFFF+1) + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.tx_async_fifo_rd_wr_ptr + with self.subTest(msg='register: msk_top_regs.tx_async_fifo_rd_wr_ptr'): + rut=self.dut.tx_async_fifo_rd_wr_ptr # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=144, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=144, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=144, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=144, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + if not isinstance(rut, (RegAsyncWriteOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Writeable Async Type') + + # test the write with high value + await rut.write(0xFFFFFFFF) + write_callback_mock.assert_called_once_with( + addr=144, + width=32, + accesswidth=rut.accesswidth, + data=0xFFFFFFFF) + write_callback_mock.reset_mock() + + # test the write of a low value + await rut.write(0) + write_callback_mock.assert_called_once_with( + addr=144, + width=32, + accesswidth=rut.accesswidth, + data=0) + write_callback_mock.reset_mock() + + # test the write of a random + random_value = random.randrange(0, 0xFFFFFFFF+1) + await rut.write(random_value) # type: ignore[union-attr] + write_callback_mock.assert_called_once_with( + addr=144, + width=32, + accesswidth=rut.accesswidth, + data=random_value) + write_callback_mock.reset_mock() + + # test writing a value beyond the register range is blocked with an exception being raised + with self.assertRaises(ValueError): + await rut.write(-1) + + with self.assertRaises(ValueError): + await rut.write(0xFFFFFFFF+1) + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.rx_async_fifo_rd_wr_ptr + with self.subTest(msg='register: msk_top_regs.rx_async_fifo_rd_wr_ptr'): + rut=self.dut.rx_async_fifo_rd_wr_ptr # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=148, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=148, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=148, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=148, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + if not isinstance(rut, (RegAsyncWriteOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Writeable Async Type') + + # test the write with high value + await rut.write(0xFFFFFFFF) + write_callback_mock.assert_called_once_with( + addr=148, + width=32, + accesswidth=rut.accesswidth, + data=0xFFFFFFFF) + write_callback_mock.reset_mock() + + # test the write of a low value + await rut.write(0) + write_callback_mock.assert_called_once_with( + addr=148, + width=32, + accesswidth=rut.accesswidth, + data=0) + write_callback_mock.reset_mock() + + # test the write of a random + random_value = random.randrange(0, 0xFFFFFFFF+1) + await rut.write(random_value) # type: ignore[union-attr] + write_callback_mock.assert_called_once_with( + addr=148, + width=32, + accesswidth=rut.accesswidth, + data=random_value) + write_callback_mock.reset_mock() + + # test writing a value beyond the register range is blocked with an exception being raised + with self.assertRaises(ValueError): + await rut.write(-1) + + with self.assertRaises(ValueError): + await rut.write(0xFFFFFFFF+1) + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + # test access operations (read and/or write) to register: + # msk_top_regs.rx_frame_sync_status + with self.subTest(msg='register: msk_top_regs.rx_frame_sync_status'): + rut=self.dut.rx_frame_sync_status # type: ignore[union-attr,assignment] + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=1) as read_callback_mock: + + + if not isinstance(rut, (RegAsyncReadOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Readable Async Type') + + # test reading back 1 (the unpatched version returns 0 so this confirms the patch works) + self.assertEqual(await rut.read(), 1) + read_callback_mock.assert_called_once_with( + addr=152, + width=32, + accesswidth=rut.accesswidth) + + # test the read check with high value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await rut.read(), 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=152, + width=32, + accesswidth=rut.accesswidth) + + # test the read of the low value + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0 + self.assertEqual(await rut.read(), 0x0) + read_callback_mock.assert_called_once_with( + addr=152, + width=32, + accesswidth=rut.accesswidth) + + # test the read of a random value + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.reset_mock() + read_callback_mock.return_value = random_value + self.assertEqual(await rut.read(), random_value) + read_callback_mock.assert_called_once_with( + addr=152, + width=32, + accesswidth=rut.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + + + if not isinstance(rut, (RegAsyncWriteOnly, RegAsyncReadWrite)): + raise TypeError('Register is not a Writeable Async Type') + + # test the write with high value + await rut.write(0xFFFFFFFF) + write_callback_mock.assert_called_once_with( + addr=152, + width=32, + accesswidth=rut.accesswidth, + data=0xFFFFFFFF) + write_callback_mock.reset_mock() + + # test the write of a low value + await rut.write(0) + write_callback_mock.assert_called_once_with( + addr=152, + width=32, + accesswidth=rut.accesswidth, + data=0) + write_callback_mock.reset_mock() + + # test the write of a random + random_value = random.randrange(0, 0xFFFFFFFF+1) + await rut.write(random_value) # type: ignore[union-attr] + write_callback_mock.assert_called_once_with( + addr=152, + width=32, + accesswidth=rut.accesswidth, + data=random_value) + write_callback_mock.reset_mock() + + # test writing a value beyond the register range is blocked with an exception being raised + with self.assertRaises(ValueError): + await rut.write(-1) + + with self.assertRaises(ValueError): + await rut.write(0xFFFFFFFF+1) + + # check the read has not been called in the write test + read_callback_mock.assert_not_called() + + + async def test_int_field_read_and_write(self) -> None: + """ + Check the ability to read and write to integer (non-eumn) fields + """ + fut:Field + + + # test access operations (read and/or write) to field: + # msk_top_regs.Hash_ID_Low.hash_id_lo + with self.subTest(msg='field: msk_top_regs.Hash_ID_Low.hash_id_lo'): + fut = self.dut.Hash_ID_Low.hash_id_lo # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0x0 + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=0, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await fut.read(), + 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=0, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=0, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + # test access operations (read and/or write) to field: + # msk_top_regs.Hash_ID_High.hash_id_hi + with self.subTest(msg='field: msk_top_regs.Hash_ID_High.hash_id_hi'): + fut = self.dut.Hash_ID_High.hash_id_hi # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0x0 + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=4, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await fut.read(), + 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=4, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=4, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + # test access operations (read and/or write) to field: + # msk_top_regs.MSK_Init.txrxinit + with self.subTest(msg='field: msk_top_regs.MSK_Init.txrxinit'): + fut = self.dut.MSK_Init.txrxinit # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0xFFFFFFFE + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=8, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0x1 + self.assertEqual(await fut.read(), + 0x1) + read_callback_mock.assert_called_once_with( + addr=8, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0x1) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=8, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0x1 + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0x1, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.MSK_Init.txrxinit.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_called_once_with( + addr=8, + width=32, + accesswidth=fut.parent_register.accesswidth) + + write_callback_mock.assert_called_once_with( + addr=8, + width=32, + accesswidth=self.dut.MSK_Init.txrxinit.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0xFFFFFFFE) | \ + (0x1 & (field_value << 0))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0x1 + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.MSK_Init.txinit + with self.subTest(msg='field: msk_top_regs.MSK_Init.txinit'): + fut = self.dut.MSK_Init.txinit # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0xFFFFFFFD + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=8, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0x2 + self.assertEqual(await fut.read(), + 0x1) + read_callback_mock.assert_called_once_with( + addr=8, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0x2) >> 1 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=8, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0x1 + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0x1, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.MSK_Init.txinit.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_called_once_with( + addr=8, + width=32, + accesswidth=fut.parent_register.accesswidth) + + write_callback_mock.assert_called_once_with( + addr=8, + width=32, + accesswidth=self.dut.MSK_Init.txinit.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0xFFFFFFFD) | \ + (0x2 & (field_value << 1))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0x1 + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.MSK_Init.rxinit + with self.subTest(msg='field: msk_top_regs.MSK_Init.rxinit'): + fut = self.dut.MSK_Init.rxinit # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0xFFFFFFFB + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=8, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0x4 + self.assertEqual(await fut.read(), + 0x1) + read_callback_mock.assert_called_once_with( + addr=8, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0x4) >> 2 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=8, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0x1 + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0x1, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.MSK_Init.rxinit.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_called_once_with( + addr=8, + width=32, + accesswidth=fut.parent_register.accesswidth) + + write_callback_mock.assert_called_once_with( + addr=8, + width=32, + accesswidth=self.dut.MSK_Init.rxinit.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0xFFFFFFFB) | \ + (0x4 & (field_value << 2))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0x1 + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.MSK_Control.ptt + with self.subTest(msg='field: msk_top_regs.MSK_Control.ptt'): + fut = self.dut.MSK_Control.ptt # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0xFFFFFFFE + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=12, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0x1 + self.assertEqual(await fut.read(), + 0x1) + read_callback_mock.assert_called_once_with( + addr=12, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0x1) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=12, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0x1 + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0x1, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.MSK_Control.ptt.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_called_once_with( + addr=12, + width=32, + accesswidth=fut.parent_register.accesswidth) + + write_callback_mock.assert_called_once_with( + addr=12, + width=32, + accesswidth=self.dut.MSK_Control.ptt.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0xFFFFFFFE) | \ + (0x1 & (field_value << 0))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0x1 + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.MSK_Control.loopback_ena + with self.subTest(msg='field: msk_top_regs.MSK_Control.loopback_ena'): + fut = self.dut.MSK_Control.loopback_ena # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0xFFFFFFFD + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=12, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0x2 + self.assertEqual(await fut.read(), + 0x1) + read_callback_mock.assert_called_once_with( + addr=12, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0x2) >> 1 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=12, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0x1 + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0x1, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.MSK_Control.loopback_ena.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_called_once_with( + addr=12, + width=32, + accesswidth=fut.parent_register.accesswidth) + + write_callback_mock.assert_called_once_with( + addr=12, + width=32, + accesswidth=self.dut.MSK_Control.loopback_ena.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0xFFFFFFFD) | \ + (0x2 & (field_value << 1))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0x1 + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.MSK_Control.rx_invert + with self.subTest(msg='field: msk_top_regs.MSK_Control.rx_invert'): + fut = self.dut.MSK_Control.rx_invert # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0xFFFFFFFB + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=12, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0x4 + self.assertEqual(await fut.read(), + 0x1) + read_callback_mock.assert_called_once_with( + addr=12, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0x4) >> 2 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=12, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0x1 + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0x1, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.MSK_Control.rx_invert.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_called_once_with( + addr=12, + width=32, + accesswidth=fut.parent_register.accesswidth) + + write_callback_mock.assert_called_once_with( + addr=12, + width=32, + accesswidth=self.dut.MSK_Control.rx_invert.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0xFFFFFFFB) | \ + (0x4 & (field_value << 2))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0x1 + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.MSK_Control.clear_counts + with self.subTest(msg='field: msk_top_regs.MSK_Control.clear_counts'): + fut = self.dut.MSK_Control.clear_counts # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0xFFFFFFF7 + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=12, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0x8 + self.assertEqual(await fut.read(), + 0x1) + read_callback_mock.assert_called_once_with( + addr=12, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0x8) >> 3 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=12, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0x1 + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0x1, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.MSK_Control.clear_counts.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_called_once_with( + addr=12, + width=32, + accesswidth=fut.parent_register.accesswidth) + + write_callback_mock.assert_called_once_with( + addr=12, + width=32, + accesswidth=self.dut.MSK_Control.clear_counts.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0xFFFFFFF7) | \ + (0x8 & (field_value << 3))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0x1 + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.MSK_Control.diff_encoder_loopback + with self.subTest(msg='field: msk_top_regs.MSK_Control.diff_encoder_loopback'): + fut = self.dut.MSK_Control.diff_encoder_loopback # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0xFFFFFFEF + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=12, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0x10 + self.assertEqual(await fut.read(), + 0x1) + read_callback_mock.assert_called_once_with( + addr=12, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0x10) >> 4 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=12, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0x1 + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0x1, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.MSK_Control.diff_encoder_loopback.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_called_once_with( + addr=12, + width=32, + accesswidth=fut.parent_register.accesswidth) + + write_callback_mock.assert_called_once_with( + addr=12, + width=32, + accesswidth=self.dut.MSK_Control.diff_encoder_loopback.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0xFFFFFFEF) | \ + (0x10 & (field_value << 4))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0x1 + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.MSK_Status.demod_sync_lock + with self.subTest(msg='field: msk_top_regs.MSK_Status.demod_sync_lock'): + fut = self.dut.MSK_Status.demod_sync_lock # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0xFFFFFFFE + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=16, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0x1 + self.assertEqual(await fut.read(), + 0x1) + read_callback_mock.assert_called_once_with( + addr=16, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0x1) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=16, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + # test access operations (read and/or write) to field: + # msk_top_regs.MSK_Status.tx_enable + with self.subTest(msg='field: msk_top_regs.MSK_Status.tx_enable'): + fut = self.dut.MSK_Status.tx_enable # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0xFFFFFFFD + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=16, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0x2 + self.assertEqual(await fut.read(), + 0x1) + read_callback_mock.assert_called_once_with( + addr=16, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0x2) >> 1 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=16, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + # test access operations (read and/or write) to field: + # msk_top_regs.MSK_Status.rx_enable + with self.subTest(msg='field: msk_top_regs.MSK_Status.rx_enable'): + fut = self.dut.MSK_Status.rx_enable # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0xFFFFFFFB + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=16, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0x4 + self.assertEqual(await fut.read(), + 0x1) + read_callback_mock.assert_called_once_with( + addr=16, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0x4) >> 2 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=16, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + # test access operations (read and/or write) to field: + # msk_top_regs.MSK_Status.tx_axis_valid + with self.subTest(msg='field: msk_top_regs.MSK_Status.tx_axis_valid'): + fut = self.dut.MSK_Status.tx_axis_valid # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0xFFFFFFF7 + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=16, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0x8 + self.assertEqual(await fut.read(), + 0x1) + read_callback_mock.assert_called_once_with( + addr=16, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0x8) >> 3 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=16, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + # test access operations (read and/or write) to field: + # msk_top_regs.Tx_Bit_Count.data + with self.subTest(msg='field: msk_top_regs.Tx_Bit_Count.data'): + fut = self.dut.Tx_Bit_Count.data # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0x0 + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=20, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await fut.read(), + 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=20, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=20, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0xFFFFFFFF + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0xFFFFFFFF, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.Tx_Bit_Count.data.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_not_called() + write_callback_mock.assert_called_once_with( + addr=20, + width=32, + accesswidth=self.dut.Tx_Bit_Count.data.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0x0) | \ + (0xFFFFFFFF & (field_value << 0))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0xFFFFFFFF + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.Tx_Enable_Count.data + with self.subTest(msg='field: msk_top_regs.Tx_Enable_Count.data'): + fut = self.dut.Tx_Enable_Count.data # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0x0 + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=24, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await fut.read(), + 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=24, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=24, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0xFFFFFFFF + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0xFFFFFFFF, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.Tx_Enable_Count.data.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_not_called() + write_callback_mock.assert_called_once_with( + addr=24, + width=32, + accesswidth=self.dut.Tx_Enable_Count.data.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0x0) | \ + (0xFFFFFFFF & (field_value << 0))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0xFFFFFFFF + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.Fb_FreqWord.config_data + with self.subTest(msg='field: msk_top_regs.Fb_FreqWord.config_data'): + fut = self.dut.Fb_FreqWord.config_data # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0x0 + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=28, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await fut.read(), + 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=28, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=28, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0xFFFFFFFF + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0xFFFFFFFF, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.Fb_FreqWord.config_data.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_not_called() + write_callback_mock.assert_called_once_with( + addr=28, + width=32, + accesswidth=self.dut.Fb_FreqWord.config_data.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0x0) | \ + (0xFFFFFFFF & (field_value << 0))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0xFFFFFFFF + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.TX_F1_FreqWord.config_data + with self.subTest(msg='field: msk_top_regs.TX_F1_FreqWord.config_data'): + fut = self.dut.TX_F1_FreqWord.config_data # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0x0 + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=32, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await fut.read(), + 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=32, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=32, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0xFFFFFFFF + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0xFFFFFFFF, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.TX_F1_FreqWord.config_data.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_not_called() + write_callback_mock.assert_called_once_with( + addr=32, + width=32, + accesswidth=self.dut.TX_F1_FreqWord.config_data.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0x0) | \ + (0xFFFFFFFF & (field_value << 0))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0xFFFFFFFF + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.TX_F2_FreqWord.config_data + with self.subTest(msg='field: msk_top_regs.TX_F2_FreqWord.config_data'): + fut = self.dut.TX_F2_FreqWord.config_data # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0x0 + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=36, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await fut.read(), + 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=36, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=36, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0xFFFFFFFF + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0xFFFFFFFF, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.TX_F2_FreqWord.config_data.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_not_called() + write_callback_mock.assert_called_once_with( + addr=36, + width=32, + accesswidth=self.dut.TX_F2_FreqWord.config_data.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0x0) | \ + (0xFFFFFFFF & (field_value << 0))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0xFFFFFFFF + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.RX_F1_FreqWord.config_data + with self.subTest(msg='field: msk_top_regs.RX_F1_FreqWord.config_data'): + fut = self.dut.RX_F1_FreqWord.config_data # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0x0 + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=40, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await fut.read(), + 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=40, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=40, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0xFFFFFFFF + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0xFFFFFFFF, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.RX_F1_FreqWord.config_data.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_not_called() + write_callback_mock.assert_called_once_with( + addr=40, + width=32, + accesswidth=self.dut.RX_F1_FreqWord.config_data.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0x0) | \ + (0xFFFFFFFF & (field_value << 0))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0xFFFFFFFF + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.RX_F2_FreqWord.config_data + with self.subTest(msg='field: msk_top_regs.RX_F2_FreqWord.config_data'): + fut = self.dut.RX_F2_FreqWord.config_data # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0x0 + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=44, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await fut.read(), + 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=44, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=44, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0xFFFFFFFF + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0xFFFFFFFF, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.RX_F2_FreqWord.config_data.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_not_called() + write_callback_mock.assert_called_once_with( + addr=44, + width=32, + accesswidth=self.dut.RX_F2_FreqWord.config_data.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0x0) | \ + (0xFFFFFFFF & (field_value << 0))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0xFFFFFFFF + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.LPF_Config_0.lpf_freeze + with self.subTest(msg='field: msk_top_regs.LPF_Config_0.lpf_freeze'): + fut = self.dut.LPF_Config_0.lpf_freeze # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0xFFFFFFFE + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=48, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0x1 + self.assertEqual(await fut.read(), + 0x1) + read_callback_mock.assert_called_once_with( + addr=48, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0x1) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=48, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0x1 + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0x1, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.LPF_Config_0.lpf_freeze.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_called_once_with( + addr=48, + width=32, + accesswidth=fut.parent_register.accesswidth) + + write_callback_mock.assert_called_once_with( + addr=48, + width=32, + accesswidth=self.dut.LPF_Config_0.lpf_freeze.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0xFFFFFFFE) | \ + (0x1 & (field_value << 0))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0x1 + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.LPF_Config_0.lpf_zero + with self.subTest(msg='field: msk_top_regs.LPF_Config_0.lpf_zero'): + fut = self.dut.LPF_Config_0.lpf_zero # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0xFFFFFFFD + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=48, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0x2 + self.assertEqual(await fut.read(), + 0x1) + read_callback_mock.assert_called_once_with( + addr=48, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0x2) >> 1 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=48, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0x1 + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0x1, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.LPF_Config_0.lpf_zero.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_called_once_with( + addr=48, + width=32, + accesswidth=fut.parent_register.accesswidth) + + write_callback_mock.assert_called_once_with( + addr=48, + width=32, + accesswidth=self.dut.LPF_Config_0.lpf_zero.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0xFFFFFFFD) | \ + (0x2 & (field_value << 1))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0x1 + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.LPF_Config_0.prbs_reserved + with self.subTest(msg='field: msk_top_regs.LPF_Config_0.prbs_reserved'): + fut = self.dut.LPF_Config_0.prbs_reserved # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0xFFFFFF03 + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=48, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFC + self.assertEqual(await fut.read(), + 0x3F) + read_callback_mock.assert_called_once_with( + addr=48, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0xFC) >> 2 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=48, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0x3F + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0x3F, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.LPF_Config_0.prbs_reserved.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_called_once_with( + addr=48, + width=32, + accesswidth=fut.parent_register.accesswidth) + + write_callback_mock.assert_called_once_with( + addr=48, + width=32, + accesswidth=self.dut.LPF_Config_0.prbs_reserved.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0xFFFFFF03) | \ + (0xFC & (field_value << 2))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0x3F + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.LPF_Config_0.lpf_alpha + with self.subTest(msg='field: msk_top_regs.LPF_Config_0.lpf_alpha'): + fut = self.dut.LPF_Config_0.lpf_alpha # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0xFF + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=48, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFF00 + self.assertEqual(await fut.read(), + 0xFFFFFF) + read_callback_mock.assert_called_once_with( + addr=48, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0xFFFFFF00) >> 8 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=48, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0xFFFFFF + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0xFFFFFF, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.LPF_Config_0.lpf_alpha.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_called_once_with( + addr=48, + width=32, + accesswidth=fut.parent_register.accesswidth) + + write_callback_mock.assert_called_once_with( + addr=48, + width=32, + accesswidth=self.dut.LPF_Config_0.lpf_alpha.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0xFF) | \ + (0xFFFFFF00 & (field_value << 8))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0xFFFFFF + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.LPF_Config_1.i_gain + with self.subTest(msg='field: msk_top_regs.LPF_Config_1.i_gain'): + fut = self.dut.LPF_Config_1.i_gain # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0xFF000000 + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=52, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFF + self.assertEqual(await fut.read(), + 0xFFFFFF) + read_callback_mock.assert_called_once_with( + addr=52, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0xFFFFFF) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=52, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0xFFFFFF + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0xFFFFFF, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.LPF_Config_1.i_gain.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_called_once_with( + addr=52, + width=32, + accesswidth=fut.parent_register.accesswidth) + + write_callback_mock.assert_called_once_with( + addr=52, + width=32, + accesswidth=self.dut.LPF_Config_1.i_gain.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0xFF000000) | \ + (0xFFFFFF & (field_value << 0))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0xFFFFFF + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.LPF_Config_1.i_shift + with self.subTest(msg='field: msk_top_regs.LPF_Config_1.i_shift'): + fut = self.dut.LPF_Config_1.i_shift # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0xFFFFFF + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=52, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFF000000 + self.assertEqual(await fut.read(), + 0xFF) + read_callback_mock.assert_called_once_with( + addr=52, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0xFF000000) >> 24 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=52, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0xFF + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0xFF, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.LPF_Config_1.i_shift.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_called_once_with( + addr=52, + width=32, + accesswidth=fut.parent_register.accesswidth) + + write_callback_mock.assert_called_once_with( + addr=52, + width=32, + accesswidth=self.dut.LPF_Config_1.i_shift.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0xFFFFFF) | \ + (0xFF000000 & (field_value << 24))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0xFF + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.Tx_Data_Width.data_width + with self.subTest(msg='field: msk_top_regs.Tx_Data_Width.data_width'): + fut = self.dut.Tx_Data_Width.data_width # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0xFFFFFF00 + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=56, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFF + self.assertEqual(await fut.read(), + 0xFF) + read_callback_mock.assert_called_once_with( + addr=56, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0xFF) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=56, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0xFF + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0xFF, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.Tx_Data_Width.data_width.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_called_once_with( + addr=56, + width=32, + accesswidth=fut.parent_register.accesswidth) + + write_callback_mock.assert_called_once_with( + addr=56, + width=32, + accesswidth=self.dut.Tx_Data_Width.data_width.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0xFFFFFF00) | \ + (0xFF & (field_value << 0))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0xFF + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.Rx_Data_Width.data_width + with self.subTest(msg='field: msk_top_regs.Rx_Data_Width.data_width'): + fut = self.dut.Rx_Data_Width.data_width # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0xFFFFFF00 + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=60, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFF + self.assertEqual(await fut.read(), + 0xFF) + read_callback_mock.assert_called_once_with( + addr=60, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0xFF) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=60, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0xFF + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0xFF, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.Rx_Data_Width.data_width.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_called_once_with( + addr=60, + width=32, + accesswidth=fut.parent_register.accesswidth) + + write_callback_mock.assert_called_once_with( + addr=60, + width=32, + accesswidth=self.dut.Rx_Data_Width.data_width.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0xFFFFFF00) | \ + (0xFF & (field_value << 0))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0xFF + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.PRBS_Control.prbs_sel + with self.subTest(msg='field: msk_top_regs.PRBS_Control.prbs_sel'): + fut = self.dut.PRBS_Control.prbs_sel # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0xFFFFFFFE + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=64, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0x1 + self.assertEqual(await fut.read(), + 0x1) + read_callback_mock.assert_called_once_with( + addr=64, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0x1) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=64, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0x1 + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0x1, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.PRBS_Control.prbs_sel.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_called_once_with( + addr=64, + width=32, + accesswidth=fut.parent_register.accesswidth) + + write_callback_mock.assert_called_once_with( + addr=64, + width=32, + accesswidth=self.dut.PRBS_Control.prbs_sel.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0xFFFFFFFE) | \ + (0x1 & (field_value << 0))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0x1 + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.PRBS_Control.prbs_error_insert + with self.subTest(msg='field: msk_top_regs.PRBS_Control.prbs_error_insert'): + fut = self.dut.PRBS_Control.prbs_error_insert # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0x1 + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0x1, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.PRBS_Control.prbs_error_insert.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_called_once_with( + addr=64, + width=32, + accesswidth=fut.parent_register.accesswidth) + + write_callback_mock.assert_called_once_with( + addr=64, + width=32, + accesswidth=self.dut.PRBS_Control.prbs_error_insert.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0xFFFFFFFD) | \ + (0x2 & (field_value << 1))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0x1 + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.PRBS_Control.prbs_clear + with self.subTest(msg='field: msk_top_regs.PRBS_Control.prbs_clear'): + fut = self.dut.PRBS_Control.prbs_clear # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0x1 + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0x1, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.PRBS_Control.prbs_clear.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_called_once_with( + addr=64, + width=32, + accesswidth=fut.parent_register.accesswidth) + + write_callback_mock.assert_called_once_with( + addr=64, + width=32, + accesswidth=self.dut.PRBS_Control.prbs_clear.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0xFFFFFFFB) | \ + (0x4 & (field_value << 2))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0x1 + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.PRBS_Control.prbs_manual_sync + with self.subTest(msg='field: msk_top_regs.PRBS_Control.prbs_manual_sync'): + fut = self.dut.PRBS_Control.prbs_manual_sync # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0x1 + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0x1, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.PRBS_Control.prbs_manual_sync.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_called_once_with( + addr=64, + width=32, + accesswidth=fut.parent_register.accesswidth) + + write_callback_mock.assert_called_once_with( + addr=64, + width=32, + accesswidth=self.dut.PRBS_Control.prbs_manual_sync.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0xFFFFFFF7) | \ + (0x8 & (field_value << 3))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0x1 + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.PRBS_Control.prbs_reserved + with self.subTest(msg='field: msk_top_regs.PRBS_Control.prbs_reserved'): + fut = self.dut.PRBS_Control.prbs_reserved # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0xFFFF000F + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=64, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFF0 + self.assertEqual(await fut.read(), + 0xFFF) + read_callback_mock.assert_called_once_with( + addr=64, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0xFFF0) >> 4 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=64, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0xFFF + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0xFFF, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.PRBS_Control.prbs_reserved.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_called_once_with( + addr=64, + width=32, + accesswidth=fut.parent_register.accesswidth) + + write_callback_mock.assert_called_once_with( + addr=64, + width=32, + accesswidth=self.dut.PRBS_Control.prbs_reserved.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0xFFFF000F) | \ + (0xFFF0 & (field_value << 4))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0xFFF + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.PRBS_Control.prbs_sync_threshold + with self.subTest(msg='field: msk_top_regs.PRBS_Control.prbs_sync_threshold'): + fut = self.dut.PRBS_Control.prbs_sync_threshold # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0xFFFF + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=64, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFF0000 + self.assertEqual(await fut.read(), + 0xFFFF) + read_callback_mock.assert_called_once_with( + addr=64, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0xFFFF0000) >> 16 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=64, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0xFFFF + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0xFFFF, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.PRBS_Control.prbs_sync_threshold.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_called_once_with( + addr=64, + width=32, + accesswidth=fut.parent_register.accesswidth) + + write_callback_mock.assert_called_once_with( + addr=64, + width=32, + accesswidth=self.dut.PRBS_Control.prbs_sync_threshold.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0xFFFF) | \ + (0xFFFF0000 & (field_value << 16))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0xFFFF + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.PRBS_Initial_State.config_data + with self.subTest(msg='field: msk_top_regs.PRBS_Initial_State.config_data'): + fut = self.dut.PRBS_Initial_State.config_data # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0x0 + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=68, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await fut.read(), + 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=68, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=68, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0xFFFFFFFF + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0xFFFFFFFF, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.PRBS_Initial_State.config_data.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_not_called() + write_callback_mock.assert_called_once_with( + addr=68, + width=32, + accesswidth=self.dut.PRBS_Initial_State.config_data.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0x0) | \ + (0xFFFFFFFF & (field_value << 0))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0xFFFFFFFF + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.PRBS_Polynomial.config_data + with self.subTest(msg='field: msk_top_regs.PRBS_Polynomial.config_data'): + fut = self.dut.PRBS_Polynomial.config_data # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0x0 + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=72, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await fut.read(), + 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=72, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=72, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0xFFFFFFFF + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0xFFFFFFFF, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.PRBS_Polynomial.config_data.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_not_called() + write_callback_mock.assert_called_once_with( + addr=72, + width=32, + accesswidth=self.dut.PRBS_Polynomial.config_data.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0x0) | \ + (0xFFFFFFFF & (field_value << 0))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0xFFFFFFFF + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.PRBS_Error_Mask.config_data + with self.subTest(msg='field: msk_top_regs.PRBS_Error_Mask.config_data'): + fut = self.dut.PRBS_Error_Mask.config_data # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0x0 + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=76, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await fut.read(), + 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=76, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=76, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0xFFFFFFFF + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0xFFFFFFFF, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.PRBS_Error_Mask.config_data.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_not_called() + write_callback_mock.assert_called_once_with( + addr=76, + width=32, + accesswidth=self.dut.PRBS_Error_Mask.config_data.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0x0) | \ + (0xFFFFFFFF & (field_value << 0))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0xFFFFFFFF + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.PRBS_Bit_Count.data + with self.subTest(msg='field: msk_top_regs.PRBS_Bit_Count.data'): + fut = self.dut.PRBS_Bit_Count.data # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0x0 + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=80, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await fut.read(), + 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=80, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=80, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0xFFFFFFFF + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0xFFFFFFFF, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.PRBS_Bit_Count.data.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_not_called() + write_callback_mock.assert_called_once_with( + addr=80, + width=32, + accesswidth=self.dut.PRBS_Bit_Count.data.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0x0) | \ + (0xFFFFFFFF & (field_value << 0))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0xFFFFFFFF + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.PRBS_Error_Count.data + with self.subTest(msg='field: msk_top_regs.PRBS_Error_Count.data'): + fut = self.dut.PRBS_Error_Count.data # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0x0 + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=84, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await fut.read(), + 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=84, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=84, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0xFFFFFFFF + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0xFFFFFFFF, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.PRBS_Error_Count.data.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_not_called() + write_callback_mock.assert_called_once_with( + addr=84, + width=32, + accesswidth=self.dut.PRBS_Error_Count.data.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0x0) | \ + (0xFFFFFFFF & (field_value << 0))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0xFFFFFFFF + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.LPF_Accum_F1.data + with self.subTest(msg='field: msk_top_regs.LPF_Accum_F1.data'): + fut = self.dut.LPF_Accum_F1.data # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0x0 + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=88, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await fut.read(), + 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=88, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=88, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0xFFFFFFFF + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0xFFFFFFFF, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.LPF_Accum_F1.data.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_not_called() + write_callback_mock.assert_called_once_with( + addr=88, + width=32, + accesswidth=self.dut.LPF_Accum_F1.data.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0x0) | \ + (0xFFFFFFFF & (field_value << 0))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0xFFFFFFFF + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.LPF_Accum_F2.data + with self.subTest(msg='field: msk_top_regs.LPF_Accum_F2.data'): + fut = self.dut.LPF_Accum_F2.data # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0x0 + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=92, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await fut.read(), + 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=92, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=92, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0xFFFFFFFF + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0xFFFFFFFF, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.LPF_Accum_F2.data.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_not_called() + write_callback_mock.assert_called_once_with( + addr=92, + width=32, + accesswidth=self.dut.LPF_Accum_F2.data.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0x0) | \ + (0xFFFFFFFF & (field_value << 0))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0xFFFFFFFF + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.axis_xfer_count.data + with self.subTest(msg='field: msk_top_regs.axis_xfer_count.data'): + fut = self.dut.axis_xfer_count.data # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0x0 + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=96, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await fut.read(), + 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=96, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=96, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0xFFFFFFFF + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0xFFFFFFFF, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.axis_xfer_count.data.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_not_called() + write_callback_mock.assert_called_once_with( + addr=96, + width=32, + accesswidth=self.dut.axis_xfer_count.data.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0x0) | \ + (0xFFFFFFFF & (field_value << 0))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0xFFFFFFFF + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.Rx_Sample_Discard.rx_sample_discard + with self.subTest(msg='field: msk_top_regs.Rx_Sample_Discard.rx_sample_discard'): + fut = self.dut.Rx_Sample_Discard.rx_sample_discard # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0xFFFFFF00 + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=100, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFF + self.assertEqual(await fut.read(), + 0xFF) + read_callback_mock.assert_called_once_with( + addr=100, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0xFF) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=100, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0xFF + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0xFF, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.Rx_Sample_Discard.rx_sample_discard.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_called_once_with( + addr=100, + width=32, + accesswidth=fut.parent_register.accesswidth) + + write_callback_mock.assert_called_once_with( + addr=100, + width=32, + accesswidth=self.dut.Rx_Sample_Discard.rx_sample_discard.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0xFFFFFF00) | \ + (0xFF & (field_value << 0))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0xFF + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.Rx_Sample_Discard.rx_nco_discard + with self.subTest(msg='field: msk_top_regs.Rx_Sample_Discard.rx_nco_discard'): + fut = self.dut.Rx_Sample_Discard.rx_nco_discard # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0xFFFF00FF + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=100, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFF00 + self.assertEqual(await fut.read(), + 0xFF) + read_callback_mock.assert_called_once_with( + addr=100, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0xFF00) >> 8 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=100, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0xFF + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0xFF, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.Rx_Sample_Discard.rx_nco_discard.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_called_once_with( + addr=100, + width=32, + accesswidth=fut.parent_register.accesswidth) + + write_callback_mock.assert_called_once_with( + addr=100, + width=32, + accesswidth=self.dut.Rx_Sample_Discard.rx_nco_discard.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0xFFFF00FF) | \ + (0xFF00 & (field_value << 8))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0xFF + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.LPF_Config_2.p_gain + with self.subTest(msg='field: msk_top_regs.LPF_Config_2.p_gain'): + fut = self.dut.LPF_Config_2.p_gain # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0xFF000000 + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=104, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFF + self.assertEqual(await fut.read(), + 0xFFFFFF) + read_callback_mock.assert_called_once_with( + addr=104, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0xFFFFFF) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=104, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0xFFFFFF + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0xFFFFFF, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.LPF_Config_2.p_gain.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_called_once_with( + addr=104, + width=32, + accesswidth=fut.parent_register.accesswidth) + + write_callback_mock.assert_called_once_with( + addr=104, + width=32, + accesswidth=self.dut.LPF_Config_2.p_gain.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0xFF000000) | \ + (0xFFFFFF & (field_value << 0))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0xFFFFFF + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.LPF_Config_2.p_shift + with self.subTest(msg='field: msk_top_regs.LPF_Config_2.p_shift'): + fut = self.dut.LPF_Config_2.p_shift # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0xFFFFFF + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=104, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFF000000 + self.assertEqual(await fut.read(), + 0xFF) + read_callback_mock.assert_called_once_with( + addr=104, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0xFF000000) >> 24 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=104, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0xFF + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0xFF, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.LPF_Config_2.p_shift.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_called_once_with( + addr=104, + width=32, + accesswidth=fut.parent_register.accesswidth) + + write_callback_mock.assert_called_once_with( + addr=104, + width=32, + accesswidth=self.dut.LPF_Config_2.p_shift.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0xFFFFFF) | \ + (0xFF000000 & (field_value << 24))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0xFF + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.f1_nco_adjust.data + with self.subTest(msg='field: msk_top_regs.f1_nco_adjust.data'): + fut = self.dut.f1_nco_adjust.data # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0x0 + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=108, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await fut.read(), + 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=108, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=108, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0xFFFFFFFF + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0xFFFFFFFF, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.f1_nco_adjust.data.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_not_called() + write_callback_mock.assert_called_once_with( + addr=108, + width=32, + accesswidth=self.dut.f1_nco_adjust.data.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0x0) | \ + (0xFFFFFFFF & (field_value << 0))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0xFFFFFFFF + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.f2_nco_adjust.data + with self.subTest(msg='field: msk_top_regs.f2_nco_adjust.data'): + fut = self.dut.f2_nco_adjust.data # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0x0 + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=112, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await fut.read(), + 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=112, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=112, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0xFFFFFFFF + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0xFFFFFFFF, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.f2_nco_adjust.data.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_not_called() + write_callback_mock.assert_called_once_with( + addr=112, + width=32, + accesswidth=self.dut.f2_nco_adjust.data.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0x0) | \ + (0xFFFFFFFF & (field_value << 0))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0xFFFFFFFF + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.f1_error.data + with self.subTest(msg='field: msk_top_regs.f1_error.data'): + fut = self.dut.f1_error.data # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0x0 + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=116, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await fut.read(), + 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=116, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=116, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0xFFFFFFFF + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0xFFFFFFFF, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.f1_error.data.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_not_called() + write_callback_mock.assert_called_once_with( + addr=116, + width=32, + accesswidth=self.dut.f1_error.data.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0x0) | \ + (0xFFFFFFFF & (field_value << 0))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0xFFFFFFFF + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.f2_error.data + with self.subTest(msg='field: msk_top_regs.f2_error.data'): + fut = self.dut.f2_error.data # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0x0 + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=120, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await fut.read(), + 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=120, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=120, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0xFFFFFFFF + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0xFFFFFFFF, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.f2_error.data.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_not_called() + write_callback_mock.assert_called_once_with( + addr=120, + width=32, + accesswidth=self.dut.f2_error.data.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0x0) | \ + (0xFFFFFFFF & (field_value << 0))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0xFFFFFFFF + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.Tx_Sync_Ctrl.tx_sync_ena + with self.subTest(msg='field: msk_top_regs.Tx_Sync_Ctrl.tx_sync_ena'): + fut = self.dut.Tx_Sync_Ctrl.tx_sync_ena # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0xFFFFFFFE + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=124, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0x1 + self.assertEqual(await fut.read(), + 0x1) + read_callback_mock.assert_called_once_with( + addr=124, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0x1) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=124, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0x1 + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0x1, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.Tx_Sync_Ctrl.tx_sync_ena.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_called_once_with( + addr=124, + width=32, + accesswidth=fut.parent_register.accesswidth) + + write_callback_mock.assert_called_once_with( + addr=124, + width=32, + accesswidth=self.dut.Tx_Sync_Ctrl.tx_sync_ena.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0xFFFFFFFE) | \ + (0x1 & (field_value << 0))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0x1 + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.Tx_Sync_Ctrl.tx_sync_force + with self.subTest(msg='field: msk_top_regs.Tx_Sync_Ctrl.tx_sync_force'): + fut = self.dut.Tx_Sync_Ctrl.tx_sync_force # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0xFFFFFFFD + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=124, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0x2 + self.assertEqual(await fut.read(), + 0x1) + read_callback_mock.assert_called_once_with( + addr=124, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0x2) >> 1 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=124, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0x1 + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0x1, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.Tx_Sync_Ctrl.tx_sync_force.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_called_once_with( + addr=124, + width=32, + accesswidth=fut.parent_register.accesswidth) + + write_callback_mock.assert_called_once_with( + addr=124, + width=32, + accesswidth=self.dut.Tx_Sync_Ctrl.tx_sync_force.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0xFFFFFFFD) | \ + (0x2 & (field_value << 1))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0x1 + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.Tx_Sync_Cnt.tx_sync_cnt + with self.subTest(msg='field: msk_top_regs.Tx_Sync_Cnt.tx_sync_cnt'): + fut = self.dut.Tx_Sync_Cnt.tx_sync_cnt # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0xFF000000 + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=128, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFF + self.assertEqual(await fut.read(), + 0xFFFFFF) + read_callback_mock.assert_called_once_with( + addr=128, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0xFFFFFF) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=128, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0xFFFFFF + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0xFFFFFF, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.Tx_Sync_Cnt.tx_sync_cnt.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_called_once_with( + addr=128, + width=32, + accesswidth=fut.parent_register.accesswidth) + + write_callback_mock.assert_called_once_with( + addr=128, + width=32, + accesswidth=self.dut.Tx_Sync_Cnt.tx_sync_cnt.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0xFF000000) | \ + (0xFFFFFF & (field_value << 0))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0xFFFFFF + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.lowpass_ema_alpha1.alpha + with self.subTest(msg='field: msk_top_regs.lowpass_ema_alpha1.alpha'): + fut = self.dut.lowpass_ema_alpha1.alpha # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0xFFFC0000 + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=132, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0x3FFFF + self.assertEqual(await fut.read(), + 0x3FFFF) + read_callback_mock.assert_called_once_with( + addr=132, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0x3FFFF) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=132, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0x3FFFF + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0x3FFFF, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.lowpass_ema_alpha1.alpha.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_called_once_with( + addr=132, + width=32, + accesswidth=fut.parent_register.accesswidth) + + write_callback_mock.assert_called_once_with( + addr=132, + width=32, + accesswidth=self.dut.lowpass_ema_alpha1.alpha.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0xFFFC0000) | \ + (0x3FFFF & (field_value << 0))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0x3FFFF + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.lowpass_ema_alpha2.alpha + with self.subTest(msg='field: msk_top_regs.lowpass_ema_alpha2.alpha'): + fut = self.dut.lowpass_ema_alpha2.alpha # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0xFFFC0000 + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=136, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0x3FFFF + self.assertEqual(await fut.read(), + 0x3FFFF) + read_callback_mock.assert_called_once_with( + addr=136, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0x3FFFF) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=136, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0x3FFFF + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0x3FFFF, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.lowpass_ema_alpha2.alpha.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_called_once_with( + addr=136, + width=32, + accesswidth=fut.parent_register.accesswidth) + + write_callback_mock.assert_called_once_with( + addr=136, + width=32, + accesswidth=self.dut.lowpass_ema_alpha2.alpha.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0xFFFC0000) | \ + (0x3FFFF & (field_value << 0))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0x3FFFF + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.rx_power.data + with self.subTest(msg='field: msk_top_regs.rx_power.data'): + fut = self.dut.rx_power.data # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0xFF800000 + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=140, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0x7FFFFF + self.assertEqual(await fut.read(), + 0x7FFFFF) + read_callback_mock.assert_called_once_with( + addr=140, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0x7FFFFF) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=140, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0x7FFFFF + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0x7FFFFF, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.rx_power.data.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_called_once_with( + addr=140, + width=32, + accesswidth=fut.parent_register.accesswidth) + + write_callback_mock.assert_called_once_with( + addr=140, + width=32, + accesswidth=self.dut.rx_power.data.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0xFF800000) | \ + (0x7FFFFF & (field_value << 0))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0x7FFFFF + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.tx_async_fifo_rd_wr_ptr.data + with self.subTest(msg='field: msk_top_regs.tx_async_fifo_rd_wr_ptr.data'): + fut = self.dut.tx_async_fifo_rd_wr_ptr.data # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0x0 + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=144, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await fut.read(), + 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=144, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=144, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0xFFFFFFFF + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0xFFFFFFFF, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.tx_async_fifo_rd_wr_ptr.data.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_not_called() + write_callback_mock.assert_called_once_with( + addr=144, + width=32, + accesswidth=self.dut.tx_async_fifo_rd_wr_ptr.data.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0x0) | \ + (0xFFFFFFFF & (field_value << 0))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0xFFFFFFFF + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.rx_async_fifo_rd_wr_ptr.data + with self.subTest(msg='field: msk_top_regs.rx_async_fifo_rd_wr_ptr.data'): + fut = self.dut.rx_async_fifo_rd_wr_ptr.data # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0x0 + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=148, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFFFFFFFF + self.assertEqual(await fut.read(), + 0xFFFFFFFF) + read_callback_mock.assert_called_once_with( + addr=148, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=148, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0xFFFFFFFF + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0xFFFFFFFF, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.rx_async_fifo_rd_wr_ptr.data.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_not_called() + write_callback_mock.assert_called_once_with( + addr=148, + width=32, + accesswidth=self.dut.rx_async_fifo_rd_wr_ptr.data.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0x0) | \ + (0xFFFFFFFF & (field_value << 0))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0xFFFFFFFF + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.rx_frame_sync_status.frame_sync_locked + with self.subTest(msg='field: msk_top_regs.rx_frame_sync_status.frame_sync_locked'): + fut = self.dut.rx_frame_sync_status.frame_sync_locked # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0xFFFFFFFE + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=152, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0x1 + self.assertEqual(await fut.read(), + 0x1) + read_callback_mock.assert_called_once_with( + addr=152, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0x1) >> 0 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=152, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + # test access operations (read and/or write) to field: + # msk_top_regs.rx_frame_sync_status.frame_buffer_overflow + with self.subTest(msg='field: msk_top_regs.rx_frame_sync_status.frame_buffer_overflow'): + fut = self.dut.rx_frame_sync_status.frame_buffer_overflow # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0xFFFFFFFD + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=152, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0x2 + self.assertEqual(await fut.read(), + 0x1) + read_callback_mock.assert_called_once_with( + addr=152, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0x2) >> 1 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=152, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + + # test access operations (read and/or write) to field: + # msk_top_regs.rx_frame_sync_status.frames_received + with self.subTest(msg='field: msk_top_regs.rx_frame_sync_status.frames_received'): + fut = self.dut.rx_frame_sync_status.frames_received # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0xFC000003 + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=152, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0x3FFFFFC + self.assertEqual(await fut.read(), + 0xFFFFFF) + read_callback_mock.assert_called_once_with( + addr=152, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0x3FFFFFC) >> 2 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=152, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0xFFFFFF + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0xFFFFFF, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.rx_frame_sync_status.frames_received.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_called_once_with( + addr=152, + width=32, + accesswidth=fut.parent_register.accesswidth) + + write_callback_mock.assert_called_once_with( + addr=152, + width=32, + accesswidth=self.dut.rx_frame_sync_status.frames_received.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0xFC000003) | \ + (0x3FFFFFC & (field_value << 2))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0xFFFFFF + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + # test access operations (read and/or write) to field: + # msk_top_regs.rx_frame_sync_status.frame_sync_errors + with self.subTest(msg='field: msk_top_regs.rx_frame_sync_status.frame_sync_errors'): + fut = self.dut.rx_frame_sync_status.frame_sync_errors # type: ignore[union-attr] + with patch(base_name + '.write_addr_space') as write_callback_mock,\ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + + + + if not isinstance(fut, (FieldAsyncReadOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a readable async field') + + + # read back - zero, this is achieved by setting the register to inverse bitmask + read_callback_mock.return_value = 0x3FFFFFF + self.assertEqual(await fut.read(), + 0) + read_callback_mock.assert_called_once_with( + addr=152, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - max_value, this is achieved by setting the register to bitmask + read_callback_mock.reset_mock() + read_callback_mock.return_value = 0xFC000000 + self.assertEqual(await fut.read(), + 0x3F) + read_callback_mock.assert_called_once_with( + addr=152, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # read back - random value + read_callback_mock.reset_mock() + random_value = random.randrange(0, 0xFFFFFFFF+1) + read_callback_mock.return_value = random_value + random_field_value = (random_value & 0xFC000000) >> 26 + self.assertEqual(await fut.read(), + random_field_value) + read_callback_mock.assert_called_once_with( + addr=152, + width=32, + accesswidth=fut.parent_register.accesswidth) + + # at the end of the read tests the write should not have been called + read_callback_mock.reset_mock() + write_callback_mock.assert_not_called() + # check the write + + if not isinstance(fut, (FieldAsyncWriteOnly, FieldAsyncReadWrite)): + raise TypeError('Test can not proceed as the fut is not a writable async field') + + + random_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + random_field_value = random.randrange(0, 0x3F + 1) + for reg_base_value in [0, 0xFFFFFFFF, random_reg_value]: + for field_value in [0, 0x3F, random_field_value]: + read_callback_mock.reset_mock() + write_callback_mock.reset_mock() + read_callback_mock.return_value = reg_base_value + + await self.dut.rx_frame_sync_status.frame_sync_errors.write(field_value) # type: ignore[union-attr] + + + read_callback_mock.assert_called_once_with( + addr=152, + width=32, + accesswidth=fut.parent_register.accesswidth) + + write_callback_mock.assert_called_once_with( + addr=152, + width=32, + accesswidth=self.dut.rx_frame_sync_status.frame_sync_errors.parent_register.accesswidth, # type: ignore[union-attr] + data=(reg_base_value & 0x3FFFFFF) | \ + (0xFC000000 & (field_value << 26))) + + + # check invalid write values bounce + with self.assertRaises(ValueError): + await fut.write(0x3F + 1) + + with self.assertRaises(ValueError): + await fut.write(-1) + + + + async def test_register_read_fields(self) -> None: + """ + Walk the register map and check every register read_fields method + """ + reference_read_fields: dict[str, Union[bool, SystemRDLEnum, int]] + + with self.subTest(msg='register: msk_top_regs.Hash_ID_Low'): + # test read_fields to register: + # msk_top_regs.Hash_ID_Low + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'hash_id_lo' : await self.dut.Hash_ID_Low.hash_id_lo.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.Hash_ID_Low.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.Hash_ID_High'): + # test read_fields to register: + # msk_top_regs.Hash_ID_High + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'hash_id_hi' : await self.dut.Hash_ID_High.hash_id_hi.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.Hash_ID_High.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.MSK_Init'): + # test read_fields to register: + # msk_top_regs.MSK_Init + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFFE) | (rand_field_value << 0) + + + + + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFFD) | (rand_field_value << 1) + + + + + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFFB) | (rand_field_value << 2) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'txrxinit' : await self.dut.MSK_Init.txrxinit.read(), + 'txinit' : await self.dut.MSK_Init.txinit.read(), + 'rxinit' : await self.dut.MSK_Init.rxinit.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.MSK_Init.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.MSK_Control'): + # test read_fields to register: + # msk_top_regs.MSK_Control + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFFE) | (rand_field_value << 0) + + + + + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFFD) | (rand_field_value << 1) + + + + + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFFB) | (rand_field_value << 2) + + + + + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFF7) | (rand_field_value << 3) + + + + + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFEF) | (rand_field_value << 4) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'ptt' : await self.dut.MSK_Control.ptt.read(), + 'loopback_ena' : await self.dut.MSK_Control.loopback_ena.read(), + 'rx_invert' : await self.dut.MSK_Control.rx_invert.read(), + 'clear_counts' : await self.dut.MSK_Control.clear_counts.read(), + 'diff_encoder_loopback' : await self.dut.MSK_Control.diff_encoder_loopback.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.MSK_Control.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.MSK_Status'): + # test read_fields to register: + # msk_top_regs.MSK_Status + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFFE) | (rand_field_value << 0) + + + + + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFFD) | (rand_field_value << 1) + + + + + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFFB) | (rand_field_value << 2) + + + + + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFF7) | (rand_field_value << 3) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'demod_sync_lock' : await self.dut.MSK_Status.demod_sync_lock.read(), + 'tx_enable' : await self.dut.MSK_Status.tx_enable.read(), + 'rx_enable' : await self.dut.MSK_Status.rx_enable.read(), + 'tx_axis_valid' : await self.dut.MSK_Status.tx_axis_valid.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.MSK_Status.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.Tx_Bit_Count'): + # test read_fields to register: + # msk_top_regs.Tx_Bit_Count + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'data' : await self.dut.Tx_Bit_Count.data.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.Tx_Bit_Count.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.Tx_Enable_Count'): + # test read_fields to register: + # msk_top_regs.Tx_Enable_Count + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'data' : await self.dut.Tx_Enable_Count.data.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.Tx_Enable_Count.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.Fb_FreqWord'): + # test read_fields to register: + # msk_top_regs.Fb_FreqWord + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'config_data' : await self.dut.Fb_FreqWord.config_data.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.Fb_FreqWord.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.TX_F1_FreqWord'): + # test read_fields to register: + # msk_top_regs.TX_F1_FreqWord + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'config_data' : await self.dut.TX_F1_FreqWord.config_data.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.TX_F1_FreqWord.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.TX_F2_FreqWord'): + # test read_fields to register: + # msk_top_regs.TX_F2_FreqWord + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'config_data' : await self.dut.TX_F2_FreqWord.config_data.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.TX_F2_FreqWord.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.RX_F1_FreqWord'): + # test read_fields to register: + # msk_top_regs.RX_F1_FreqWord + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'config_data' : await self.dut.RX_F1_FreqWord.config_data.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.RX_F1_FreqWord.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.RX_F2_FreqWord'): + # test read_fields to register: + # msk_top_regs.RX_F2_FreqWord + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'config_data' : await self.dut.RX_F2_FreqWord.config_data.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.RX_F2_FreqWord.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.LPF_Config_0'): + # test read_fields to register: + # msk_top_regs.LPF_Config_0 + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFFE) | (rand_field_value << 0) + + + + + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFFD) | (rand_field_value << 1) + + + + + + + + rand_field_value = random.randrange(0, 0x3F + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFF03) | (rand_field_value << 2) + + + + + + + + rand_field_value = random.randrange(0, 0xFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0xFF) | (rand_field_value << 8) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'lpf_freeze' : await self.dut.LPF_Config_0.lpf_freeze.read(), + 'lpf_zero' : await self.dut.LPF_Config_0.lpf_zero.read(), + 'prbs_reserved' : await self.dut.LPF_Config_0.prbs_reserved.read(), + 'lpf_alpha' : await self.dut.LPF_Config_0.lpf_alpha.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.LPF_Config_0.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.LPF_Config_1'): + # test read_fields to register: + # msk_top_regs.LPF_Config_1 + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0xFF000000) | (rand_field_value << 0) + + + + + + + + rand_field_value = random.randrange(0, 0xFF + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFF) | (rand_field_value << 24) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'i_gain' : await self.dut.LPF_Config_1.i_gain.read(), + 'i_shift' : await self.dut.LPF_Config_1.i_shift.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.LPF_Config_1.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.Tx_Data_Width'): + # test read_fields to register: + # msk_top_regs.Tx_Data_Width + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFF + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFF00) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'data_width' : await self.dut.Tx_Data_Width.data_width.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.Tx_Data_Width.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.Rx_Data_Width'): + # test read_fields to register: + # msk_top_regs.Rx_Data_Width + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFF + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFF00) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'data_width' : await self.dut.Rx_Data_Width.data_width.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.Rx_Data_Width.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.PRBS_Control'): + # test read_fields to register: + # msk_top_regs.PRBS_Control + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFFE) | (rand_field_value << 0) + + + + + + + + + + + + + + + + + + + + rand_field_value = random.randrange(0, 0xFFF + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFF000F) | (rand_field_value << 4) + + + + + + + + rand_field_value = random.randrange(0, 0xFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFF) | (rand_field_value << 16) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'prbs_sel' : await self.dut.PRBS_Control.prbs_sel.read(), + 'prbs_reserved' : await self.dut.PRBS_Control.prbs_reserved.read(), + 'prbs_sync_threshold' : await self.dut.PRBS_Control.prbs_sync_threshold.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.PRBS_Control.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.PRBS_Initial_State'): + # test read_fields to register: + # msk_top_regs.PRBS_Initial_State + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'config_data' : await self.dut.PRBS_Initial_State.config_data.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.PRBS_Initial_State.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.PRBS_Polynomial'): + # test read_fields to register: + # msk_top_regs.PRBS_Polynomial + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'config_data' : await self.dut.PRBS_Polynomial.config_data.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.PRBS_Polynomial.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.PRBS_Error_Mask'): + # test read_fields to register: + # msk_top_regs.PRBS_Error_Mask + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'config_data' : await self.dut.PRBS_Error_Mask.config_data.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.PRBS_Error_Mask.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.PRBS_Bit_Count'): + # test read_fields to register: + # msk_top_regs.PRBS_Bit_Count + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'data' : await self.dut.PRBS_Bit_Count.data.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.PRBS_Bit_Count.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.PRBS_Error_Count'): + # test read_fields to register: + # msk_top_regs.PRBS_Error_Count + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'data' : await self.dut.PRBS_Error_Count.data.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.PRBS_Error_Count.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.LPF_Accum_F1'): + # test read_fields to register: + # msk_top_regs.LPF_Accum_F1 + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'data' : await self.dut.LPF_Accum_F1.data.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.LPF_Accum_F1.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.LPF_Accum_F2'): + # test read_fields to register: + # msk_top_regs.LPF_Accum_F2 + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'data' : await self.dut.LPF_Accum_F2.data.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.LPF_Accum_F2.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.axis_xfer_count'): + # test read_fields to register: + # msk_top_regs.axis_xfer_count + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'data' : await self.dut.axis_xfer_count.data.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.axis_xfer_count.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.Rx_Sample_Discard'): + # test read_fields to register: + # msk_top_regs.Rx_Sample_Discard + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFF + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFF00) | (rand_field_value << 0) + + + + + + + + rand_field_value = random.randrange(0, 0xFF + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFF00FF) | (rand_field_value << 8) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'rx_sample_discard' : await self.dut.Rx_Sample_Discard.rx_sample_discard.read(), + 'rx_nco_discard' : await self.dut.Rx_Sample_Discard.rx_nco_discard.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.Rx_Sample_Discard.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.LPF_Config_2'): + # test read_fields to register: + # msk_top_regs.LPF_Config_2 + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0xFF000000) | (rand_field_value << 0) + + + + + + + + rand_field_value = random.randrange(0, 0xFF + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFF) | (rand_field_value << 24) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'p_gain' : await self.dut.LPF_Config_2.p_gain.read(), + 'p_shift' : await self.dut.LPF_Config_2.p_shift.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.LPF_Config_2.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.f1_nco_adjust'): + # test read_fields to register: + # msk_top_regs.f1_nco_adjust + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'data' : await self.dut.f1_nco_adjust.data.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.f1_nco_adjust.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.f2_nco_adjust'): + # test read_fields to register: + # msk_top_regs.f2_nco_adjust + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'data' : await self.dut.f2_nco_adjust.data.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.f2_nco_adjust.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.f1_error'): + # test read_fields to register: + # msk_top_regs.f1_error + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'data' : await self.dut.f1_error.data.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.f1_error.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.f2_error'): + # test read_fields to register: + # msk_top_regs.f2_error + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'data' : await self.dut.f2_error.data.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.f2_error.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.Tx_Sync_Ctrl'): + # test read_fields to register: + # msk_top_regs.Tx_Sync_Ctrl + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFFE) | (rand_field_value << 0) + + + + + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFFD) | (rand_field_value << 1) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'tx_sync_ena' : await self.dut.Tx_Sync_Ctrl.tx_sync_ena.read(), + 'tx_sync_force' : await self.dut.Tx_Sync_Ctrl.tx_sync_force.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.Tx_Sync_Ctrl.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.Tx_Sync_Cnt'): + # test read_fields to register: + # msk_top_regs.Tx_Sync_Cnt + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0xFF000000) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'tx_sync_cnt' : await self.dut.Tx_Sync_Cnt.tx_sync_cnt.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.Tx_Sync_Cnt.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.lowpass_ema_alpha1'): + # test read_fields to register: + # msk_top_regs.lowpass_ema_alpha1 + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0x3FFFF + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFC0000) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'alpha' : await self.dut.lowpass_ema_alpha1.alpha.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.lowpass_ema_alpha1.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.lowpass_ema_alpha2'): + # test read_fields to register: + # msk_top_regs.lowpass_ema_alpha2 + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0x3FFFF + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFC0000) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'alpha' : await self.dut.lowpass_ema_alpha2.alpha.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.lowpass_ema_alpha2.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.rx_power'): + # test read_fields to register: + # msk_top_regs.rx_power + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0x7FFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0xFF800000) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'data' : await self.dut.rx_power.data.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.rx_power.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.tx_async_fifo_rd_wr_ptr'): + # test read_fields to register: + # msk_top_regs.tx_async_fifo_rd_wr_ptr + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'data' : await self.dut.tx_async_fifo_rd_wr_ptr.data.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.tx_async_fifo_rd_wr_ptr.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.rx_async_fifo_rd_wr_ptr'): + # test read_fields to register: + # msk_top_regs.rx_async_fifo_rd_wr_ptr + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'data' : await self.dut.rx_async_fifo_rd_wr_ptr.data.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.rx_async_fifo_rd_wr_ptr.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + with self.subTest(msg='register: msk_top_regs.rx_frame_sync_status'): + # test read_fields to register: + # msk_top_regs.rx_frame_sync_status + # build up the register value with a random base value, overlaid with + # a random value for each field + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFFE) | (rand_field_value << 0) + + + + + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFFD) | (rand_field_value << 1) + + + + + + + + rand_field_value = random.randrange(0, 0xFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0xFC000003) | (rand_field_value << 2) + + + + + + + + rand_field_value = random.randrange(0, 0x3F + 1) + + + rand_reg_value = (rand_reg_value & 0x3FFFFFF) | (rand_field_value << 26) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + # the read_fields method gets a dictionary back + # from the object with all the read back field + # values + reference_read_fields = { + 'frame_sync_locked' : await self.dut.rx_frame_sync_status.frame_sync_locked.read(), + 'frame_buffer_overflow' : await self.dut.rx_frame_sync_status.frame_buffer_overflow.read(), + 'frames_received' : await self.dut.rx_frame_sync_status.frames_received.read(), + 'frame_sync_errors' : await self.dut.rx_frame_sync_status.frame_sync_errors.read() + } + + read_callback_mock.reset_mock() + + self.assertDictEqual(await self.dut.rx_frame_sync_status.read_fields(), + reference_read_fields) + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + + async def test_register_read_context_manager(self) -> None: + """ + Walk the register map and check every register read_fields method + """ + reference_read_fields: dict[str, Union[bool, SystemRDLEnum, int]] + + # test context manager to register: + # msk_top_regs.Hash_ID_Low + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.Hash_ID_Low'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'hash_id_lo' : await self.dut.Hash_ID_Low.hash_id_lo.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.Hash_ID_Low.single_read() as reg_context: # type: ignore[union-attr] + self.assertEqual(reference_read_fields['hash_id_lo'], + await reg_context.get_child_by_system_rdl_name('hash_id_lo').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.Hash_ID_High + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.Hash_ID_High'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'hash_id_hi' : await self.dut.Hash_ID_High.hash_id_hi.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.Hash_ID_High.single_read() as reg_context: # type: ignore[union-attr] + self.assertEqual(reference_read_fields['hash_id_hi'], + await reg_context.get_child_by_system_rdl_name('hash_id_hi').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.MSK_Init + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.MSK_Init'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFFE) | (rand_field_value << 0) + + + + + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFFD) | (rand_field_value << 1) + + + + + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFFB) | (rand_field_value << 2) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'txrxinit' : await self.dut.MSK_Init.txrxinit.read(), # type: ignore[union-attr] + 'txinit' : await self.dut.MSK_Init.txinit.read(), # type: ignore[union-attr] + 'rxinit' : await self.dut.MSK_Init.rxinit.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.MSK_Init.single_read_modify_write(skip_write=True) as reg_context: # type: ignore[union-attr] + + self.assertEqual(reference_read_fields['txrxinit'], + await reg_context.get_child_by_system_rdl_name('txrxinit').read() + ) + self.assertEqual(reference_read_fields['txinit'], + await reg_context.get_child_by_system_rdl_name('txinit').read() + ) + self.assertEqual(reference_read_fields['rxinit'], + await reg_context.get_child_by_system_rdl_name('rxinit').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.MSK_Control + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.MSK_Control'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFFE) | (rand_field_value << 0) + + + + + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFFD) | (rand_field_value << 1) + + + + + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFFB) | (rand_field_value << 2) + + + + + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFF7) | (rand_field_value << 3) + + + + + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFEF) | (rand_field_value << 4) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'ptt' : await self.dut.MSK_Control.ptt.read(), # type: ignore[union-attr] + 'loopback_ena' : await self.dut.MSK_Control.loopback_ena.read(), # type: ignore[union-attr] + 'rx_invert' : await self.dut.MSK_Control.rx_invert.read(), # type: ignore[union-attr] + 'clear_counts' : await self.dut.MSK_Control.clear_counts.read(), # type: ignore[union-attr] + 'diff_encoder_loopback' : await self.dut.MSK_Control.diff_encoder_loopback.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.MSK_Control.single_read_modify_write(skip_write=True) as reg_context: # type: ignore[union-attr] + + self.assertEqual(reference_read_fields['ptt'], + await reg_context.get_child_by_system_rdl_name('ptt').read() + ) + self.assertEqual(reference_read_fields['loopback_ena'], + await reg_context.get_child_by_system_rdl_name('loopback_ena').read() + ) + self.assertEqual(reference_read_fields['rx_invert'], + await reg_context.get_child_by_system_rdl_name('rx_invert').read() + ) + self.assertEqual(reference_read_fields['clear_counts'], + await reg_context.get_child_by_system_rdl_name('clear_counts').read() + ) + self.assertEqual(reference_read_fields['diff_encoder_loopback'], + await reg_context.get_child_by_system_rdl_name('diff_encoder_loopback').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.MSK_Status + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.MSK_Status'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFFE) | (rand_field_value << 0) + + + + + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFFD) | (rand_field_value << 1) + + + + + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFFB) | (rand_field_value << 2) + + + + + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFF7) | (rand_field_value << 3) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'demod_sync_lock' : await self.dut.MSK_Status.demod_sync_lock.read(), # type: ignore[union-attr] + 'tx_enable' : await self.dut.MSK_Status.tx_enable.read(), # type: ignore[union-attr] + 'rx_enable' : await self.dut.MSK_Status.rx_enable.read(), # type: ignore[union-attr] + 'tx_axis_valid' : await self.dut.MSK_Status.tx_axis_valid.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.MSK_Status.single_read() as reg_context: # type: ignore[union-attr] + self.assertEqual(reference_read_fields['demod_sync_lock'], + await reg_context.get_child_by_system_rdl_name('demod_sync_lock').read() + ) + self.assertEqual(reference_read_fields['tx_enable'], + await reg_context.get_child_by_system_rdl_name('tx_enable').read() + ) + self.assertEqual(reference_read_fields['rx_enable'], + await reg_context.get_child_by_system_rdl_name('rx_enable').read() + ) + self.assertEqual(reference_read_fields['tx_axis_valid'], + await reg_context.get_child_by_system_rdl_name('tx_axis_valid').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.Tx_Bit_Count + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.Tx_Bit_Count'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'data' : await self.dut.Tx_Bit_Count.data.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.Tx_Bit_Count.single_read_modify_write(skip_write=True) as reg_context: # type: ignore[union-attr] + + self.assertEqual(reference_read_fields['data'], + await reg_context.get_child_by_system_rdl_name('data').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.Tx_Enable_Count + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.Tx_Enable_Count'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'data' : await self.dut.Tx_Enable_Count.data.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.Tx_Enable_Count.single_read_modify_write(skip_write=True) as reg_context: # type: ignore[union-attr] + + self.assertEqual(reference_read_fields['data'], + await reg_context.get_child_by_system_rdl_name('data').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.Fb_FreqWord + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.Fb_FreqWord'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'config_data' : await self.dut.Fb_FreqWord.config_data.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.Fb_FreqWord.single_read_modify_write(skip_write=True) as reg_context: # type: ignore[union-attr] + + self.assertEqual(reference_read_fields['config_data'], + await reg_context.get_child_by_system_rdl_name('config_data').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.TX_F1_FreqWord + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.TX_F1_FreqWord'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'config_data' : await self.dut.TX_F1_FreqWord.config_data.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.TX_F1_FreqWord.single_read_modify_write(skip_write=True) as reg_context: # type: ignore[union-attr] + + self.assertEqual(reference_read_fields['config_data'], + await reg_context.get_child_by_system_rdl_name('config_data').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.TX_F2_FreqWord + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.TX_F2_FreqWord'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'config_data' : await self.dut.TX_F2_FreqWord.config_data.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.TX_F2_FreqWord.single_read_modify_write(skip_write=True) as reg_context: # type: ignore[union-attr] + + self.assertEqual(reference_read_fields['config_data'], + await reg_context.get_child_by_system_rdl_name('config_data').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.RX_F1_FreqWord + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.RX_F1_FreqWord'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'config_data' : await self.dut.RX_F1_FreqWord.config_data.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.RX_F1_FreqWord.single_read_modify_write(skip_write=True) as reg_context: # type: ignore[union-attr] + + self.assertEqual(reference_read_fields['config_data'], + await reg_context.get_child_by_system_rdl_name('config_data').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.RX_F2_FreqWord + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.RX_F2_FreqWord'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'config_data' : await self.dut.RX_F2_FreqWord.config_data.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.RX_F2_FreqWord.single_read_modify_write(skip_write=True) as reg_context: # type: ignore[union-attr] + + self.assertEqual(reference_read_fields['config_data'], + await reg_context.get_child_by_system_rdl_name('config_data').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.LPF_Config_0 + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.LPF_Config_0'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFFE) | (rand_field_value << 0) + + + + + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFFD) | (rand_field_value << 1) + + + + + + + + rand_field_value = random.randrange(0, 0x3F + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFF03) | (rand_field_value << 2) + + + + + + + + rand_field_value = random.randrange(0, 0xFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0xFF) | (rand_field_value << 8) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'lpf_freeze' : await self.dut.LPF_Config_0.lpf_freeze.read(), # type: ignore[union-attr] + 'lpf_zero' : await self.dut.LPF_Config_0.lpf_zero.read(), # type: ignore[union-attr] + 'prbs_reserved' : await self.dut.LPF_Config_0.prbs_reserved.read(), # type: ignore[union-attr] + 'lpf_alpha' : await self.dut.LPF_Config_0.lpf_alpha.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.LPF_Config_0.single_read_modify_write(skip_write=True) as reg_context: # type: ignore[union-attr] + + self.assertEqual(reference_read_fields['lpf_freeze'], + await reg_context.get_child_by_system_rdl_name('lpf_freeze').read() + ) + self.assertEqual(reference_read_fields['lpf_zero'], + await reg_context.get_child_by_system_rdl_name('lpf_zero').read() + ) + self.assertEqual(reference_read_fields['prbs_reserved'], + await reg_context.get_child_by_system_rdl_name('prbs_reserved').read() + ) + self.assertEqual(reference_read_fields['lpf_alpha'], + await reg_context.get_child_by_system_rdl_name('lpf_alpha').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.LPF_Config_1 + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.LPF_Config_1'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0xFF000000) | (rand_field_value << 0) + + + + + + + + rand_field_value = random.randrange(0, 0xFF + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFF) | (rand_field_value << 24) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'i_gain' : await self.dut.LPF_Config_1.i_gain.read(), # type: ignore[union-attr] + 'i_shift' : await self.dut.LPF_Config_1.i_shift.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.LPF_Config_1.single_read_modify_write(skip_write=True) as reg_context: # type: ignore[union-attr] + + self.assertEqual(reference_read_fields['i_gain'], + await reg_context.get_child_by_system_rdl_name('i_gain').read() + ) + self.assertEqual(reference_read_fields['i_shift'], + await reg_context.get_child_by_system_rdl_name('i_shift').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.Tx_Data_Width + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.Tx_Data_Width'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFF + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFF00) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'data_width' : await self.dut.Tx_Data_Width.data_width.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.Tx_Data_Width.single_read_modify_write(skip_write=True) as reg_context: # type: ignore[union-attr] + + self.assertEqual(reference_read_fields['data_width'], + await reg_context.get_child_by_system_rdl_name('data_width').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.Rx_Data_Width + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.Rx_Data_Width'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFF + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFF00) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'data_width' : await self.dut.Rx_Data_Width.data_width.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.Rx_Data_Width.single_read_modify_write(skip_write=True) as reg_context: # type: ignore[union-attr] + + self.assertEqual(reference_read_fields['data_width'], + await reg_context.get_child_by_system_rdl_name('data_width').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.PRBS_Control + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.PRBS_Control'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFFE) | (rand_field_value << 0) + + + + + + + + + + + + + + + + + + + + rand_field_value = random.randrange(0, 0xFFF + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFF000F) | (rand_field_value << 4) + + + + + + + + rand_field_value = random.randrange(0, 0xFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFF) | (rand_field_value << 16) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'prbs_sel' : await self.dut.PRBS_Control.prbs_sel.read(), # type: ignore[union-attr] + 'prbs_reserved' : await self.dut.PRBS_Control.prbs_reserved.read(), # type: ignore[union-attr] + 'prbs_sync_threshold' : await self.dut.PRBS_Control.prbs_sync_threshold.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.PRBS_Control.single_read_modify_write(skip_write=True) as reg_context: # type: ignore[union-attr] + + self.assertEqual(reference_read_fields['prbs_sel'], + await reg_context.get_child_by_system_rdl_name('prbs_sel').read() + ) + self.assertEqual(reference_read_fields['prbs_reserved'], + await reg_context.get_child_by_system_rdl_name('prbs_reserved').read() + ) + self.assertEqual(reference_read_fields['prbs_sync_threshold'], + await reg_context.get_child_by_system_rdl_name('prbs_sync_threshold').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.PRBS_Initial_State + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.PRBS_Initial_State'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'config_data' : await self.dut.PRBS_Initial_State.config_data.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.PRBS_Initial_State.single_read_modify_write(skip_write=True) as reg_context: # type: ignore[union-attr] + + self.assertEqual(reference_read_fields['config_data'], + await reg_context.get_child_by_system_rdl_name('config_data').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.PRBS_Polynomial + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.PRBS_Polynomial'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'config_data' : await self.dut.PRBS_Polynomial.config_data.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.PRBS_Polynomial.single_read_modify_write(skip_write=True) as reg_context: # type: ignore[union-attr] + + self.assertEqual(reference_read_fields['config_data'], + await reg_context.get_child_by_system_rdl_name('config_data').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.PRBS_Error_Mask + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.PRBS_Error_Mask'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'config_data' : await self.dut.PRBS_Error_Mask.config_data.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.PRBS_Error_Mask.single_read_modify_write(skip_write=True) as reg_context: # type: ignore[union-attr] + + self.assertEqual(reference_read_fields['config_data'], + await reg_context.get_child_by_system_rdl_name('config_data').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.PRBS_Bit_Count + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.PRBS_Bit_Count'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'data' : await self.dut.PRBS_Bit_Count.data.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.PRBS_Bit_Count.single_read_modify_write(skip_write=True) as reg_context: # type: ignore[union-attr] + + self.assertEqual(reference_read_fields['data'], + await reg_context.get_child_by_system_rdl_name('data').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.PRBS_Error_Count + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.PRBS_Error_Count'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'data' : await self.dut.PRBS_Error_Count.data.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.PRBS_Error_Count.single_read_modify_write(skip_write=True) as reg_context: # type: ignore[union-attr] + + self.assertEqual(reference_read_fields['data'], + await reg_context.get_child_by_system_rdl_name('data').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.LPF_Accum_F1 + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.LPF_Accum_F1'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'data' : await self.dut.LPF_Accum_F1.data.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.LPF_Accum_F1.single_read_modify_write(skip_write=True) as reg_context: # type: ignore[union-attr] + + self.assertEqual(reference_read_fields['data'], + await reg_context.get_child_by_system_rdl_name('data').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.LPF_Accum_F2 + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.LPF_Accum_F2'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'data' : await self.dut.LPF_Accum_F2.data.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.LPF_Accum_F2.single_read_modify_write(skip_write=True) as reg_context: # type: ignore[union-attr] + + self.assertEqual(reference_read_fields['data'], + await reg_context.get_child_by_system_rdl_name('data').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.axis_xfer_count + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.axis_xfer_count'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'data' : await self.dut.axis_xfer_count.data.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.axis_xfer_count.single_read_modify_write(skip_write=True) as reg_context: # type: ignore[union-attr] + + self.assertEqual(reference_read_fields['data'], + await reg_context.get_child_by_system_rdl_name('data').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.Rx_Sample_Discard + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.Rx_Sample_Discard'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFF + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFF00) | (rand_field_value << 0) + + + + + + + + rand_field_value = random.randrange(0, 0xFF + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFF00FF) | (rand_field_value << 8) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'rx_sample_discard' : await self.dut.Rx_Sample_Discard.rx_sample_discard.read(), # type: ignore[union-attr] + 'rx_nco_discard' : await self.dut.Rx_Sample_Discard.rx_nco_discard.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.Rx_Sample_Discard.single_read_modify_write(skip_write=True) as reg_context: # type: ignore[union-attr] + + self.assertEqual(reference_read_fields['rx_sample_discard'], + await reg_context.get_child_by_system_rdl_name('rx_sample_discard').read() + ) + self.assertEqual(reference_read_fields['rx_nco_discard'], + await reg_context.get_child_by_system_rdl_name('rx_nco_discard').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.LPF_Config_2 + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.LPF_Config_2'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0xFF000000) | (rand_field_value << 0) + + + + + + + + rand_field_value = random.randrange(0, 0xFF + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFF) | (rand_field_value << 24) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'p_gain' : await self.dut.LPF_Config_2.p_gain.read(), # type: ignore[union-attr] + 'p_shift' : await self.dut.LPF_Config_2.p_shift.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.LPF_Config_2.single_read_modify_write(skip_write=True) as reg_context: # type: ignore[union-attr] + + self.assertEqual(reference_read_fields['p_gain'], + await reg_context.get_child_by_system_rdl_name('p_gain').read() + ) + self.assertEqual(reference_read_fields['p_shift'], + await reg_context.get_child_by_system_rdl_name('p_shift').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.f1_nco_adjust + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.f1_nco_adjust'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'data' : await self.dut.f1_nco_adjust.data.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.f1_nco_adjust.single_read_modify_write(skip_write=True) as reg_context: # type: ignore[union-attr] + + self.assertEqual(reference_read_fields['data'], + await reg_context.get_child_by_system_rdl_name('data').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.f2_nco_adjust + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.f2_nco_adjust'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'data' : await self.dut.f2_nco_adjust.data.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.f2_nco_adjust.single_read_modify_write(skip_write=True) as reg_context: # type: ignore[union-attr] + + self.assertEqual(reference_read_fields['data'], + await reg_context.get_child_by_system_rdl_name('data').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.f1_error + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.f1_error'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'data' : await self.dut.f1_error.data.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.f1_error.single_read_modify_write(skip_write=True) as reg_context: # type: ignore[union-attr] + + self.assertEqual(reference_read_fields['data'], + await reg_context.get_child_by_system_rdl_name('data').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.f2_error + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.f2_error'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'data' : await self.dut.f2_error.data.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.f2_error.single_read_modify_write(skip_write=True) as reg_context: # type: ignore[union-attr] + + self.assertEqual(reference_read_fields['data'], + await reg_context.get_child_by_system_rdl_name('data').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.Tx_Sync_Ctrl + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.Tx_Sync_Ctrl'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFFE) | (rand_field_value << 0) + + + + + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFFD) | (rand_field_value << 1) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'tx_sync_ena' : await self.dut.Tx_Sync_Ctrl.tx_sync_ena.read(), # type: ignore[union-attr] + 'tx_sync_force' : await self.dut.Tx_Sync_Ctrl.tx_sync_force.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.Tx_Sync_Ctrl.single_read_modify_write(skip_write=True) as reg_context: # type: ignore[union-attr] + + self.assertEqual(reference_read_fields['tx_sync_ena'], + await reg_context.get_child_by_system_rdl_name('tx_sync_ena').read() + ) + self.assertEqual(reference_read_fields['tx_sync_force'], + await reg_context.get_child_by_system_rdl_name('tx_sync_force').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.Tx_Sync_Cnt + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.Tx_Sync_Cnt'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0xFF000000) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'tx_sync_cnt' : await self.dut.Tx_Sync_Cnt.tx_sync_cnt.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.Tx_Sync_Cnt.single_read_modify_write(skip_write=True) as reg_context: # type: ignore[union-attr] + + self.assertEqual(reference_read_fields['tx_sync_cnt'], + await reg_context.get_child_by_system_rdl_name('tx_sync_cnt').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.lowpass_ema_alpha1 + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.lowpass_ema_alpha1'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0x3FFFF + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFC0000) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'alpha' : await self.dut.lowpass_ema_alpha1.alpha.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.lowpass_ema_alpha1.single_read_modify_write(skip_write=True) as reg_context: # type: ignore[union-attr] + + self.assertEqual(reference_read_fields['alpha'], + await reg_context.get_child_by_system_rdl_name('alpha').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.lowpass_ema_alpha2 + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.lowpass_ema_alpha2'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0x3FFFF + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFC0000) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'alpha' : await self.dut.lowpass_ema_alpha2.alpha.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.lowpass_ema_alpha2.single_read_modify_write(skip_write=True) as reg_context: # type: ignore[union-attr] + + self.assertEqual(reference_read_fields['alpha'], + await reg_context.get_child_by_system_rdl_name('alpha').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.rx_power + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.rx_power'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0x7FFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0xFF800000) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'data' : await self.dut.rx_power.data.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.rx_power.single_read_modify_write(skip_write=True) as reg_context: # type: ignore[union-attr] + + self.assertEqual(reference_read_fields['data'], + await reg_context.get_child_by_system_rdl_name('data').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.tx_async_fifo_rd_wr_ptr + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.tx_async_fifo_rd_wr_ptr'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'data' : await self.dut.tx_async_fifo_rd_wr_ptr.data.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.tx_async_fifo_rd_wr_ptr.single_read_modify_write(skip_write=True) as reg_context: # type: ignore[union-attr] + + self.assertEqual(reference_read_fields['data'], + await reg_context.get_child_by_system_rdl_name('data').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.rx_async_fifo_rd_wr_ptr + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.rx_async_fifo_rd_wr_ptr'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0xFFFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0x0) | (rand_field_value << 0) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'data' : await self.dut.rx_async_fifo_rd_wr_ptr.data.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.rx_async_fifo_rd_wr_ptr.single_read_modify_write(skip_write=True) as reg_context: # type: ignore[union-attr] + + self.assertEqual(reference_read_fields['data'], + await reg_context.get_child_by_system_rdl_name('data').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + # test context manager to register: + # msk_top_regs.rx_frame_sync_status + # build up the register value with a random base value, overlaid with + # a random value for each field + with self.subTest(msg='register: msk_top_regs.rx_frame_sync_status'): + rand_reg_value = random.randrange(0, 0xFFFFFFFF + 1) + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFFE) | (rand_field_value << 0) + + + + + + + + rand_field_value = random.randrange(0, 0x1 + 1) + + + rand_reg_value = (rand_reg_value & 0xFFFFFFFD) | (rand_field_value << 1) + + + + + + + + rand_field_value = random.randrange(0, 0xFFFFFF + 1) + + + rand_reg_value = (rand_reg_value & 0xFC000003) | (rand_field_value << 2) + + + + + + + + rand_field_value = random.randrange(0, 0x3F + 1) + + + rand_reg_value = (rand_reg_value & 0x3FFFFFF) | (rand_field_value << 26) + + + + + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=rand_reg_value) as read_callback_mock: + + # first read the fields using the "normal" method, then compare the result to reading + # via the context manager + reference_read_fields = { + 'frame_sync_locked' : await self.dut.rx_frame_sync_status.frame_sync_locked.read(), # type: ignore[union-attr] + 'frame_buffer_overflow' : await self.dut.rx_frame_sync_status.frame_buffer_overflow.read(), # type: ignore[union-attr] + 'frames_received' : await self.dut.rx_frame_sync_status.frames_received.read(), # type: ignore[union-attr] + 'frame_sync_errors' : await self.dut.rx_frame_sync_status.frame_sync_errors.read() # type: ignore[union-attr] + } + read_callback_mock.reset_mock() + + + async with self.dut.rx_frame_sync_status.single_read_modify_write(skip_write=True) as reg_context: # type: ignore[union-attr] + + self.assertEqual(reference_read_fields['frame_sync_locked'], + await reg_context.get_child_by_system_rdl_name('frame_sync_locked').read() + ) + self.assertEqual(reference_read_fields['frame_buffer_overflow'], + await reg_context.get_child_by_system_rdl_name('frame_buffer_overflow').read() + ) + self.assertEqual(reference_read_fields['frames_received'], + await reg_context.get_child_by_system_rdl_name('frames_received').read() + ) + self.assertEqual(reference_read_fields['frame_sync_errors'], + await reg_context.get_child_by_system_rdl_name('frame_sync_errors').read() + ) + pass + + read_callback_mock.assert_called_once() + write_callback_mock.assert_not_called() + + async def test_register_write_context_manager(self) -> None: + """ + Test the read modify write context manager + """ + async def write_field_combinations(reg: RegAsyncReadWrite, writable_fields:list[str]) -> None: + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + # fix for #196 (excessive test time) if the number of fields is greater than 4 + # the combinations are reduced to only tests combinations of three plus the full + # set + if len(writable_fields) > 4: + perms_iterator: Iterable[int] = chain(range(1,4), [len(writable_fields)]) + else: + perms_iterator = range(1, len(writable_fields) + 1) + for fields_to_write in chain.from_iterable((combinations(writable_fields, perms) for perms in perms_iterator)): + field_values: dict[str, Union[bool, SystemRDLEnum, int]] = {} + expected_value = 0 + for field_str in fields_to_write: + field = getattr(reg, field_str) + if hasattr(field, 'enum_cls'): + rand_enum_value = random_enum_reg_value(field.enum_cls) + rand_field_value = rand_enum_value.value + field_values[field_str] = rand_enum_value + else: + rand_field_value = random.randrange(0, field.max_value + 1) + field_values[field_str] = rand_field_value + + if field.msb == field.high: + expected_value = ( expected_value & field.inverse_bitmask ) | (rand_field_value << field.low) + elif field.msb == field.low: + expected_value = ( expected_value & field.inverse_bitmask ) | (self._reverse_bits(value=rand_field_value, number_bits=field.width) << field.low) + else: + raise RuntimeError('invalid msb/lsb high/low combination') + + # read/write without verify + read_callback_mock.return_value = 0 + async with reg.single_read_modify_write(verify=False) as reg_session: + for field_name, field_value in field_values.items(): + field = getattr(reg_session, field_name) + await field.write(field_value) + + write_callback_mock.assert_called_once_with( + addr=reg.address, + width=reg.width, + accesswidth=reg.accesswidth, + data=expected_value) + read_callback_mock.assert_called_once() + write_callback_mock.reset_mock() + read_callback_mock.reset_mock() + + # read/write/verify pass + async with reg.single_read_modify_write(verify=True) as reg_session: + for field_name, field_value in field_values.items(): + field = getattr(reg_session, field_name) + await field.write(field_value) + read_callback_mock.return_value = expected_value + + write_callback_mock.assert_called_once_with( + addr=reg.address, + width=reg.width, + accesswidth=reg.accesswidth, + data=expected_value) + self.assertEqual(read_callback_mock.call_count, 2) + write_callback_mock.reset_mock() + read_callback_mock.reset_mock() + + # read/write/verify pass + with self.assertRaises(RegisterWriteVerifyError) as context: + async with reg.single_read_modify_write(verify=True) as reg_session: + for field_name, field_value in field_values.items(): + field = getattr(reg_session, field_name) + await field.write(field_value) + read_callback_mock.return_value = expected_value ^ reg_session.max_value + + write_callback_mock.reset_mock() + read_callback_mock.reset_mock() + + + with self.subTest(msg='register: msk_top_regs.MSK_Init'): + await write_field_combinations(reg=self.dut.MSK_Init, + writable_fields = [ 'txrxinit', + 'txinit', + 'rxinit' + ]) + with self.subTest(msg='register: msk_top_regs.MSK_Control'): + await write_field_combinations(reg=self.dut.MSK_Control, + writable_fields = [ 'ptt', + 'loopback_ena', + 'rx_invert', + 'clear_counts', + 'diff_encoder_loopback' + ]) + with self.subTest(msg='register: msk_top_regs.Tx_Bit_Count'): + await write_field_combinations(reg=self.dut.Tx_Bit_Count, + writable_fields = [ 'data' + ]) + with self.subTest(msg='register: msk_top_regs.Tx_Enable_Count'): + await write_field_combinations(reg=self.dut.Tx_Enable_Count, + writable_fields = [ 'data' + ]) + with self.subTest(msg='register: msk_top_regs.Fb_FreqWord'): + await write_field_combinations(reg=self.dut.Fb_FreqWord, + writable_fields = [ 'config_data' + ]) + with self.subTest(msg='register: msk_top_regs.TX_F1_FreqWord'): + await write_field_combinations(reg=self.dut.TX_F1_FreqWord, + writable_fields = [ 'config_data' + ]) + with self.subTest(msg='register: msk_top_regs.TX_F2_FreqWord'): + await write_field_combinations(reg=self.dut.TX_F2_FreqWord, + writable_fields = [ 'config_data' + ]) + with self.subTest(msg='register: msk_top_regs.RX_F1_FreqWord'): + await write_field_combinations(reg=self.dut.RX_F1_FreqWord, + writable_fields = [ 'config_data' + ]) + with self.subTest(msg='register: msk_top_regs.RX_F2_FreqWord'): + await write_field_combinations(reg=self.dut.RX_F2_FreqWord, + writable_fields = [ 'config_data' + ]) + with self.subTest(msg='register: msk_top_regs.LPF_Config_0'): + await write_field_combinations(reg=self.dut.LPF_Config_0, + writable_fields = [ 'lpf_freeze', + 'lpf_zero', + 'prbs_reserved', + 'lpf_alpha' + ]) + with self.subTest(msg='register: msk_top_regs.LPF_Config_1'): + await write_field_combinations(reg=self.dut.LPF_Config_1, + writable_fields = [ 'i_gain', + 'i_shift' + ]) + with self.subTest(msg='register: msk_top_regs.Tx_Data_Width'): + await write_field_combinations(reg=self.dut.Tx_Data_Width, + writable_fields = [ 'data_width' + ]) + with self.subTest(msg='register: msk_top_regs.Rx_Data_Width'): + await write_field_combinations(reg=self.dut.Rx_Data_Width, + writable_fields = [ 'data_width' + ]) + with self.subTest(msg='register: msk_top_regs.PRBS_Control'): + await write_field_combinations(reg=self.dut.PRBS_Control, + writable_fields = [ 'prbs_sel', + 'prbs_error_insert', + 'prbs_clear', + 'prbs_manual_sync', + 'prbs_reserved', + 'prbs_sync_threshold' + ]) + with self.subTest(msg='register: msk_top_regs.PRBS_Initial_State'): + await write_field_combinations(reg=self.dut.PRBS_Initial_State, + writable_fields = [ 'config_data' + ]) + with self.subTest(msg='register: msk_top_regs.PRBS_Polynomial'): + await write_field_combinations(reg=self.dut.PRBS_Polynomial, + writable_fields = [ 'config_data' + ]) + with self.subTest(msg='register: msk_top_regs.PRBS_Error_Mask'): + await write_field_combinations(reg=self.dut.PRBS_Error_Mask, + writable_fields = [ 'config_data' + ]) + with self.subTest(msg='register: msk_top_regs.PRBS_Bit_Count'): + await write_field_combinations(reg=self.dut.PRBS_Bit_Count, + writable_fields = [ 'data' + ]) + with self.subTest(msg='register: msk_top_regs.PRBS_Error_Count'): + await write_field_combinations(reg=self.dut.PRBS_Error_Count, + writable_fields = [ 'data' + ]) + with self.subTest(msg='register: msk_top_regs.LPF_Accum_F1'): + await write_field_combinations(reg=self.dut.LPF_Accum_F1, + writable_fields = [ 'data' + ]) + with self.subTest(msg='register: msk_top_regs.LPF_Accum_F2'): + await write_field_combinations(reg=self.dut.LPF_Accum_F2, + writable_fields = [ 'data' + ]) + with self.subTest(msg='register: msk_top_regs.axis_xfer_count'): + await write_field_combinations(reg=self.dut.axis_xfer_count, + writable_fields = [ 'data' + ]) + with self.subTest(msg='register: msk_top_regs.Rx_Sample_Discard'): + await write_field_combinations(reg=self.dut.Rx_Sample_Discard, + writable_fields = [ 'rx_sample_discard', + 'rx_nco_discard' + ]) + with self.subTest(msg='register: msk_top_regs.LPF_Config_2'): + await write_field_combinations(reg=self.dut.LPF_Config_2, + writable_fields = [ 'p_gain', + 'p_shift' + ]) + with self.subTest(msg='register: msk_top_regs.f1_nco_adjust'): + await write_field_combinations(reg=self.dut.f1_nco_adjust, + writable_fields = [ 'data' + ]) + with self.subTest(msg='register: msk_top_regs.f2_nco_adjust'): + await write_field_combinations(reg=self.dut.f2_nco_adjust, + writable_fields = [ 'data' + ]) + with self.subTest(msg='register: msk_top_regs.f1_error'): + await write_field_combinations(reg=self.dut.f1_error, + writable_fields = [ 'data' + ]) + with self.subTest(msg='register: msk_top_regs.f2_error'): + await write_field_combinations(reg=self.dut.f2_error, + writable_fields = [ 'data' + ]) + with self.subTest(msg='register: msk_top_regs.Tx_Sync_Ctrl'): + await write_field_combinations(reg=self.dut.Tx_Sync_Ctrl, + writable_fields = [ 'tx_sync_ena', + 'tx_sync_force' + ]) + with self.subTest(msg='register: msk_top_regs.Tx_Sync_Cnt'): + await write_field_combinations(reg=self.dut.Tx_Sync_Cnt, + writable_fields = [ 'tx_sync_cnt' + ]) + with self.subTest(msg='register: msk_top_regs.lowpass_ema_alpha1'): + await write_field_combinations(reg=self.dut.lowpass_ema_alpha1, + writable_fields = [ 'alpha' + ]) + with self.subTest(msg='register: msk_top_regs.lowpass_ema_alpha2'): + await write_field_combinations(reg=self.dut.lowpass_ema_alpha2, + writable_fields = [ 'alpha' + ]) + with self.subTest(msg='register: msk_top_regs.rx_power'): + await write_field_combinations(reg=self.dut.rx_power, + writable_fields = [ 'data' + ]) + with self.subTest(msg='register: msk_top_regs.tx_async_fifo_rd_wr_ptr'): + await write_field_combinations(reg=self.dut.tx_async_fifo_rd_wr_ptr, + writable_fields = [ 'data' + ]) + with self.subTest(msg='register: msk_top_regs.rx_async_fifo_rd_wr_ptr'): + await write_field_combinations(reg=self.dut.rx_async_fifo_rd_wr_ptr, + writable_fields = [ 'data' + ]) + with self.subTest(msg='register: msk_top_regs.rx_frame_sync_status'): + await write_field_combinations(reg=self.dut.rx_frame_sync_status, + writable_fields = [ 'frames_received', + 'frame_sync_errors' + ]) + + async def test_register_write_fields(self) -> None: + """ + Walk the register map and check every register write_fields method + """ + rand_enum_value:SystemRDLEnum + async def write_field_combinations(reg: RegAsyncReadWrite, writable_fields:list[str]) -> None: + with patch(base_name + '.write_addr_space') as write_callback_mock, \ + patch(base_name + '.read_addr_space', return_value=0) as read_callback_mock: + # fix for #196 (excessive test time) if the number of fields is greater than 4 + # the combinations are reduced to only tests combinations of three plus the full + # set + if len(writable_fields) > 4: + perms_iterator: Iterable[int] = chain(range(1,4), [len(writable_fields)]) + else: + perms_iterator = range(1, len(writable_fields) + 1) + for fields_to_write in chain.from_iterable((combinations(writable_fields, perms) for perms in perms_iterator)): + kwargs: dict[str, Union[bool, SystemRDLEnum, int]] = {} + expected_value = 0 + for field_str in fields_to_write: + field = getattr(reg, field_str) + if hasattr(field, 'enum_cls'): + rand_enum_value = random_enum_reg_value(field.enum_cls) + rand_field_value = rand_enum_value.value + kwargs[field_str] = rand_enum_value + else: + rand_field_value = random.randrange(0, field.max_value + 1) + kwargs[field_str] = rand_field_value + + if field.msb == field.high: + expected_value = ( expected_value & field.inverse_bitmask ) | (rand_field_value << field.low) + elif field.msb == field.low: + expected_value = ( expected_value & field.inverse_bitmask ) | (self._reverse_bits(value=rand_field_value, number_bits=field.width) << field.low) + else: + raise RuntimeError('invalid msb/lsb high/low combination') + + await reg.write_fields(**kwargs) + write_callback_mock.assert_called_once_with( + addr=reg.address, + width=reg.width, + accesswidth=reg.accesswidth, + data=expected_value) + read_callback_mock.assert_called_once() + write_callback_mock.reset_mock() + read_callback_mock.reset_mock() + + kwargs : dict[str, Union[bool, SystemRDLEnum, int]] + + + with self.subTest(msg='register: msk_top_regs.MSK_Init'): + # test read_fields to register: + # msk_top_regs.MSK_Init + await write_field_combinations(reg=self.dut.MSK_Init, + writable_fields = [ 'txrxinit', + 'txinit', + 'rxinit' + ]) + + with self.subTest(msg='register: msk_top_regs.MSK_Control'): + # test read_fields to register: + # msk_top_regs.MSK_Control + await write_field_combinations(reg=self.dut.MSK_Control, + writable_fields = [ 'ptt', + 'loopback_ena', + 'rx_invert', + 'clear_counts', + 'diff_encoder_loopback' + ]) + + with self.subTest(msg='register: msk_top_regs.Tx_Bit_Count'): + # test read_fields to register: + # msk_top_regs.Tx_Bit_Count + await write_field_combinations(reg=self.dut.Tx_Bit_Count, + writable_fields = [ 'data' + ]) + + with self.subTest(msg='register: msk_top_regs.Tx_Enable_Count'): + # test read_fields to register: + # msk_top_regs.Tx_Enable_Count + await write_field_combinations(reg=self.dut.Tx_Enable_Count, + writable_fields = [ 'data' + ]) + + with self.subTest(msg='register: msk_top_regs.Fb_FreqWord'): + # test read_fields to register: + # msk_top_regs.Fb_FreqWord + await write_field_combinations(reg=self.dut.Fb_FreqWord, + writable_fields = [ 'config_data' + ]) + + with self.subTest(msg='register: msk_top_regs.TX_F1_FreqWord'): + # test read_fields to register: + # msk_top_regs.TX_F1_FreqWord + await write_field_combinations(reg=self.dut.TX_F1_FreqWord, + writable_fields = [ 'config_data' + ]) + + with self.subTest(msg='register: msk_top_regs.TX_F2_FreqWord'): + # test read_fields to register: + # msk_top_regs.TX_F2_FreqWord + await write_field_combinations(reg=self.dut.TX_F2_FreqWord, + writable_fields = [ 'config_data' + ]) + + with self.subTest(msg='register: msk_top_regs.RX_F1_FreqWord'): + # test read_fields to register: + # msk_top_regs.RX_F1_FreqWord + await write_field_combinations(reg=self.dut.RX_F1_FreqWord, + writable_fields = [ 'config_data' + ]) + + with self.subTest(msg='register: msk_top_regs.RX_F2_FreqWord'): + # test read_fields to register: + # msk_top_regs.RX_F2_FreqWord + await write_field_combinations(reg=self.dut.RX_F2_FreqWord, + writable_fields = [ 'config_data' + ]) + + with self.subTest(msg='register: msk_top_regs.LPF_Config_0'): + # test read_fields to register: + # msk_top_regs.LPF_Config_0 + await write_field_combinations(reg=self.dut.LPF_Config_0, + writable_fields = [ 'lpf_freeze', + 'lpf_zero', + 'prbs_reserved', + 'lpf_alpha' + ]) + + with self.subTest(msg='register: msk_top_regs.LPF_Config_1'): + # test read_fields to register: + # msk_top_regs.LPF_Config_1 + await write_field_combinations(reg=self.dut.LPF_Config_1, + writable_fields = [ 'i_gain', + 'i_shift' + ]) + + with self.subTest(msg='register: msk_top_regs.Tx_Data_Width'): + # test read_fields to register: + # msk_top_regs.Tx_Data_Width + await write_field_combinations(reg=self.dut.Tx_Data_Width, + writable_fields = [ 'data_width' + ]) + + with self.subTest(msg='register: msk_top_regs.Rx_Data_Width'): + # test read_fields to register: + # msk_top_regs.Rx_Data_Width + await write_field_combinations(reg=self.dut.Rx_Data_Width, + writable_fields = [ 'data_width' + ]) + + with self.subTest(msg='register: msk_top_regs.PRBS_Control'): + # test read_fields to register: + # msk_top_regs.PRBS_Control + await write_field_combinations(reg=self.dut.PRBS_Control, + writable_fields = [ 'prbs_sel', + 'prbs_error_insert', + 'prbs_clear', + 'prbs_manual_sync', + 'prbs_reserved', + 'prbs_sync_threshold' + ]) + + with self.subTest(msg='register: msk_top_regs.PRBS_Initial_State'): + # test read_fields to register: + # msk_top_regs.PRBS_Initial_State + await write_field_combinations(reg=self.dut.PRBS_Initial_State, + writable_fields = [ 'config_data' + ]) + + with self.subTest(msg='register: msk_top_regs.PRBS_Polynomial'): + # test read_fields to register: + # msk_top_regs.PRBS_Polynomial + await write_field_combinations(reg=self.dut.PRBS_Polynomial, + writable_fields = [ 'config_data' + ]) + + with self.subTest(msg='register: msk_top_regs.PRBS_Error_Mask'): + # test read_fields to register: + # msk_top_regs.PRBS_Error_Mask + await write_field_combinations(reg=self.dut.PRBS_Error_Mask, + writable_fields = [ 'config_data' + ]) + + with self.subTest(msg='register: msk_top_regs.PRBS_Bit_Count'): + # test read_fields to register: + # msk_top_regs.PRBS_Bit_Count + await write_field_combinations(reg=self.dut.PRBS_Bit_Count, + writable_fields = [ 'data' + ]) + + with self.subTest(msg='register: msk_top_regs.PRBS_Error_Count'): + # test read_fields to register: + # msk_top_regs.PRBS_Error_Count + await write_field_combinations(reg=self.dut.PRBS_Error_Count, + writable_fields = [ 'data' + ]) + + with self.subTest(msg='register: msk_top_regs.LPF_Accum_F1'): + # test read_fields to register: + # msk_top_regs.LPF_Accum_F1 + await write_field_combinations(reg=self.dut.LPF_Accum_F1, + writable_fields = [ 'data' + ]) + + with self.subTest(msg='register: msk_top_regs.LPF_Accum_F2'): + # test read_fields to register: + # msk_top_regs.LPF_Accum_F2 + await write_field_combinations(reg=self.dut.LPF_Accum_F2, + writable_fields = [ 'data' + ]) + + with self.subTest(msg='register: msk_top_regs.axis_xfer_count'): + # test read_fields to register: + # msk_top_regs.axis_xfer_count + await write_field_combinations(reg=self.dut.axis_xfer_count, + writable_fields = [ 'data' + ]) + + with self.subTest(msg='register: msk_top_regs.Rx_Sample_Discard'): + # test read_fields to register: + # msk_top_regs.Rx_Sample_Discard + await write_field_combinations(reg=self.dut.Rx_Sample_Discard, + writable_fields = [ 'rx_sample_discard', + 'rx_nco_discard' + ]) + + with self.subTest(msg='register: msk_top_regs.LPF_Config_2'): + # test read_fields to register: + # msk_top_regs.LPF_Config_2 + await write_field_combinations(reg=self.dut.LPF_Config_2, + writable_fields = [ 'p_gain', + 'p_shift' + ]) + + with self.subTest(msg='register: msk_top_regs.f1_nco_adjust'): + # test read_fields to register: + # msk_top_regs.f1_nco_adjust + await write_field_combinations(reg=self.dut.f1_nco_adjust, + writable_fields = [ 'data' + ]) + + with self.subTest(msg='register: msk_top_regs.f2_nco_adjust'): + # test read_fields to register: + # msk_top_regs.f2_nco_adjust + await write_field_combinations(reg=self.dut.f2_nco_adjust, + writable_fields = [ 'data' + ]) + + with self.subTest(msg='register: msk_top_regs.f1_error'): + # test read_fields to register: + # msk_top_regs.f1_error + await write_field_combinations(reg=self.dut.f1_error, + writable_fields = [ 'data' + ]) + + with self.subTest(msg='register: msk_top_regs.f2_error'): + # test read_fields to register: + # msk_top_regs.f2_error + await write_field_combinations(reg=self.dut.f2_error, + writable_fields = [ 'data' + ]) + + with self.subTest(msg='register: msk_top_regs.Tx_Sync_Ctrl'): + # test read_fields to register: + # msk_top_regs.Tx_Sync_Ctrl + await write_field_combinations(reg=self.dut.Tx_Sync_Ctrl, + writable_fields = [ 'tx_sync_ena', + 'tx_sync_force' + ]) + + with self.subTest(msg='register: msk_top_regs.Tx_Sync_Cnt'): + # test read_fields to register: + # msk_top_regs.Tx_Sync_Cnt + await write_field_combinations(reg=self.dut.Tx_Sync_Cnt, + writable_fields = [ 'tx_sync_cnt' + ]) + + with self.subTest(msg='register: msk_top_regs.lowpass_ema_alpha1'): + # test read_fields to register: + # msk_top_regs.lowpass_ema_alpha1 + await write_field_combinations(reg=self.dut.lowpass_ema_alpha1, + writable_fields = [ 'alpha' + ]) + + with self.subTest(msg='register: msk_top_regs.lowpass_ema_alpha2'): + # test read_fields to register: + # msk_top_regs.lowpass_ema_alpha2 + await write_field_combinations(reg=self.dut.lowpass_ema_alpha2, + writable_fields = [ 'alpha' + ]) + + with self.subTest(msg='register: msk_top_regs.rx_power'): + # test read_fields to register: + # msk_top_regs.rx_power + await write_field_combinations(reg=self.dut.rx_power, + writable_fields = [ 'data' + ]) + + with self.subTest(msg='register: msk_top_regs.tx_async_fifo_rd_wr_ptr'): + # test read_fields to register: + # msk_top_regs.tx_async_fifo_rd_wr_ptr + await write_field_combinations(reg=self.dut.tx_async_fifo_rd_wr_ptr, + writable_fields = [ 'data' + ]) + + with self.subTest(msg='register: msk_top_regs.rx_async_fifo_rd_wr_ptr'): + # test read_fields to register: + # msk_top_regs.rx_async_fifo_rd_wr_ptr + await write_field_combinations(reg=self.dut.rx_async_fifo_rd_wr_ptr, + writable_fields = [ 'data' + ]) + + with self.subTest(msg='register: msk_top_regs.rx_frame_sync_status'): + # test read_fields to register: + # msk_top_regs.rx_frame_sync_status + await write_field_combinations(reg=self.dut.rx_frame_sync_status, + writable_fields = [ 'frames_received', + 'frame_sync_errors' + ]) + + + + + def test_adding_attributes(self) -> None: + """ + Walk the address map and attempt to set a new value on each node + + The attribute name: cppkbrgmgeloagvfgjjeiiushygirh was randomly generated to be unlikely to + every be a attribute name + + """ + with self.subTest(msg='node: msk_top_regs.Hash_ID_Low'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.Hash_ID_Low.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.Hash_ID_High'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.Hash_ID_High.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.MSK_Init'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.MSK_Init.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.MSK_Control'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.MSK_Control.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.MSK_Status'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.MSK_Status.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.Tx_Bit_Count'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.Tx_Bit_Count.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.Tx_Enable_Count'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.Tx_Enable_Count.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.Fb_FreqWord'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.Fb_FreqWord.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.TX_F1_FreqWord'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.TX_F1_FreqWord.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.TX_F2_FreqWord'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.TX_F2_FreqWord.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.RX_F1_FreqWord'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.RX_F1_FreqWord.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.RX_F2_FreqWord'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.RX_F2_FreqWord.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.LPF_Config_0'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.LPF_Config_0.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.LPF_Config_1'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.LPF_Config_1.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.Tx_Data_Width'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.Tx_Data_Width.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.Rx_Data_Width'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.Rx_Data_Width.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Control'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.PRBS_Control.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Initial_State'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.PRBS_Initial_State.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Polynomial'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.PRBS_Polynomial.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Error_Mask'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.PRBS_Error_Mask.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Bit_Count'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.PRBS_Bit_Count.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Error_Count'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.PRBS_Error_Count.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.LPF_Accum_F1'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.LPF_Accum_F1.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.LPF_Accum_F2'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.LPF_Accum_F2.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.axis_xfer_count'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.axis_xfer_count.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.Rx_Sample_Discard'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.Rx_Sample_Discard.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.LPF_Config_2'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.LPF_Config_2.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.f1_nco_adjust'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.f1_nco_adjust.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.f2_nco_adjust'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.f2_nco_adjust.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.f1_error'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.f1_error.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.f2_error'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.f2_error.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.Tx_Sync_Ctrl'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.Tx_Sync_Ctrl.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.Tx_Sync_Cnt'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.Tx_Sync_Cnt.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.lowpass_ema_alpha1'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.lowpass_ema_alpha1.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.lowpass_ema_alpha2'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.lowpass_ema_alpha2.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.rx_power'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.rx_power.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.tx_async_fifo_rd_wr_ptr'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.tx_async_fifo_rd_wr_ptr.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.rx_async_fifo_rd_wr_ptr'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.rx_async_fifo_rd_wr_ptr.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.rx_frame_sync_status'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.rx_frame_sync_status.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.Hash_ID_Low.hash_id_lo'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.Hash_ID_Low.hash_id_lo.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.Hash_ID_High.hash_id_hi'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.Hash_ID_High.hash_id_hi.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.MSK_Init.txrxinit'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.MSK_Init.txrxinit.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.MSK_Init.txinit'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.MSK_Init.txinit.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.MSK_Init.rxinit'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.MSK_Init.rxinit.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.MSK_Control.ptt'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.MSK_Control.ptt.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.MSK_Control.loopback_ena'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.MSK_Control.loopback_ena.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.MSK_Control.rx_invert'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.MSK_Control.rx_invert.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.MSK_Control.clear_counts'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.MSK_Control.clear_counts.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.MSK_Control.diff_encoder_loopback'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.MSK_Control.diff_encoder_loopback.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.MSK_Status.demod_sync_lock'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.MSK_Status.demod_sync_lock.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.MSK_Status.tx_enable'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.MSK_Status.tx_enable.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.MSK_Status.rx_enable'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.MSK_Status.rx_enable.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.MSK_Status.tx_axis_valid'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.MSK_Status.tx_axis_valid.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.Tx_Bit_Count.data'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.Tx_Bit_Count.data.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.Tx_Enable_Count.data'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.Tx_Enable_Count.data.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.Fb_FreqWord.config_data'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.Fb_FreqWord.config_data.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.TX_F1_FreqWord.config_data'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.TX_F1_FreqWord.config_data.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.TX_F2_FreqWord.config_data'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.TX_F2_FreqWord.config_data.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.RX_F1_FreqWord.config_data'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.RX_F1_FreqWord.config_data.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.RX_F2_FreqWord.config_data'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.RX_F2_FreqWord.config_data.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.LPF_Config_0.lpf_freeze'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.LPF_Config_0.lpf_freeze.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.LPF_Config_0.lpf_zero'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.LPF_Config_0.lpf_zero.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.LPF_Config_0.prbs_reserved'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.LPF_Config_0.prbs_reserved.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.LPF_Config_0.lpf_alpha'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.LPF_Config_0.lpf_alpha.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.LPF_Config_1.i_gain'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.LPF_Config_1.i_gain.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.LPF_Config_1.i_shift'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.LPF_Config_1.i_shift.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.Tx_Data_Width.data_width'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.Tx_Data_Width.data_width.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.Rx_Data_Width.data_width'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.Rx_Data_Width.data_width.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Control.prbs_sel'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.PRBS_Control.prbs_sel.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Control.prbs_error_insert'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.PRBS_Control.prbs_error_insert.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Control.prbs_clear'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.PRBS_Control.prbs_clear.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Control.prbs_manual_sync'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.PRBS_Control.prbs_manual_sync.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Control.prbs_reserved'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.PRBS_Control.prbs_reserved.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Control.prbs_sync_threshold'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.PRBS_Control.prbs_sync_threshold.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Initial_State.config_data'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.PRBS_Initial_State.config_data.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Polynomial.config_data'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.PRBS_Polynomial.config_data.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Error_Mask.config_data'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.PRBS_Error_Mask.config_data.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Bit_Count.data'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.PRBS_Bit_Count.data.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.PRBS_Error_Count.data'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.PRBS_Error_Count.data.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.LPF_Accum_F1.data'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.LPF_Accum_F1.data.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.LPF_Accum_F2.data'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.LPF_Accum_F2.data.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.axis_xfer_count.data'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.axis_xfer_count.data.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.Rx_Sample_Discard.rx_sample_discard'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.Rx_Sample_Discard.rx_sample_discard.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.Rx_Sample_Discard.rx_nco_discard'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.Rx_Sample_Discard.rx_nco_discard.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.LPF_Config_2.p_gain'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.LPF_Config_2.p_gain.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.LPF_Config_2.p_shift'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.LPF_Config_2.p_shift.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.f1_nco_adjust.data'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.f1_nco_adjust.data.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.f2_nco_adjust.data'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.f2_nco_adjust.data.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.f1_error.data'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.f1_error.data.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.f2_error.data'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.f2_error.data.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.Tx_Sync_Ctrl.tx_sync_ena'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.Tx_Sync_Ctrl.tx_sync_ena.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.Tx_Sync_Ctrl.tx_sync_force'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.Tx_Sync_Ctrl.tx_sync_force.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.Tx_Sync_Cnt.tx_sync_cnt'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.Tx_Sync_Cnt.tx_sync_cnt.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.lowpass_ema_alpha1.alpha'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.lowpass_ema_alpha1.alpha.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.lowpass_ema_alpha2.alpha'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.lowpass_ema_alpha2.alpha.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.rx_power.data'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.rx_power.data.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.tx_async_fifo_rd_wr_ptr.data'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.tx_async_fifo_rd_wr_ptr.data.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.rx_async_fifo_rd_wr_ptr.data'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.rx_async_fifo_rd_wr_ptr.data.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.rx_frame_sync_status.frame_sync_locked'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.rx_frame_sync_status.frame_sync_locked.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.rx_frame_sync_status.frame_buffer_overflow'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.rx_frame_sync_status.frame_buffer_overflow.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.rx_frame_sync_status.frames_received'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.rx_frame_sync_status.frames_received.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + with self.subTest(msg='node: msk_top_regs.rx_frame_sync_status.frame_sync_errors'): + with self.assertRaises(AttributeError): + # this line is trying to set an illegal value so by definition should fail the type + # checks + self.dut.rx_frame_sync_status.frame_sync_errors.cppkbrgmgeloagvfgjjeiiushygirh = 1 # type: ignore[attr-defined,union-attr] + + + + def test_top_traversal_iterators(self) -> None: + + expected_writable_regs: list[WritableAsyncRegister] + expected_readable_regs: list[ReadableAsyncRegister] + expected_memories:list[Union[MemoryAsyncReadOnly, MemoryAsyncWriteOnly, MemoryAsyncReadWrite]] + + + expected_sections : list[Union[AsyncAddressMap, AsyncRegFile]] + + # check the readable registers + expected_readable_regs = [self.dut.Hash_ID_Low, # type: ignore[union-attr,list-item] + + self.dut.Hash_ID_High, # type: ignore[union-attr,list-item] + + self.dut.MSK_Init, # type: ignore[union-attr,list-item] + + self.dut.MSK_Control, # type: ignore[union-attr,list-item] + + self.dut.MSK_Status, # type: ignore[union-attr,list-item] + + self.dut.Tx_Bit_Count, # type: ignore[union-attr,list-item] + + self.dut.Tx_Enable_Count, # type: ignore[union-attr,list-item] + + self.dut.Fb_FreqWord, # type: ignore[union-attr,list-item] + + self.dut.TX_F1_FreqWord, # type: ignore[union-attr,list-item] + + self.dut.TX_F2_FreqWord, # type: ignore[union-attr,list-item] + + self.dut.RX_F1_FreqWord, # type: ignore[union-attr,list-item] + + self.dut.RX_F2_FreqWord, # type: ignore[union-attr,list-item] + + self.dut.LPF_Config_0, # type: ignore[union-attr,list-item] + + self.dut.LPF_Config_1, # type: ignore[union-attr,list-item] + + self.dut.Tx_Data_Width, # type: ignore[union-attr,list-item] + + self.dut.Rx_Data_Width, # type: ignore[union-attr,list-item] + + self.dut.PRBS_Control, # type: ignore[union-attr,list-item] + + self.dut.PRBS_Initial_State, # type: ignore[union-attr,list-item] + + self.dut.PRBS_Polynomial, # type: ignore[union-attr,list-item] + + self.dut.PRBS_Error_Mask, # type: ignore[union-attr,list-item] + + self.dut.PRBS_Bit_Count, # type: ignore[union-attr,list-item] + + self.dut.PRBS_Error_Count, # type: ignore[union-attr,list-item] + + self.dut.LPF_Accum_F1, # type: ignore[union-attr,list-item] + + self.dut.LPF_Accum_F2, # type: ignore[union-attr,list-item] + + self.dut.axis_xfer_count, # type: ignore[union-attr,list-item] + + self.dut.Rx_Sample_Discard, # type: ignore[union-attr,list-item] + + self.dut.LPF_Config_2, # type: ignore[union-attr,list-item] + + self.dut.f1_nco_adjust, # type: ignore[union-attr,list-item] + + self.dut.f2_nco_adjust, # type: ignore[union-attr,list-item] + + self.dut.f1_error, # type: ignore[union-attr,list-item] + + self.dut.f2_error, # type: ignore[union-attr,list-item] + + self.dut.Tx_Sync_Ctrl, # type: ignore[union-attr,list-item] + + self.dut.Tx_Sync_Cnt, # type: ignore[union-attr,list-item] + + self.dut.lowpass_ema_alpha1, # type: ignore[union-attr,list-item] + + self.dut.lowpass_ema_alpha2, # type: ignore[union-attr,list-item] + + self.dut.rx_power, # type: ignore[union-attr,list-item] + + self.dut.tx_async_fifo_rd_wr_ptr, # type: ignore[union-attr,list-item] + + self.dut.rx_async_fifo_rd_wr_ptr, # type: ignore[union-attr,list-item] + + self.dut.rx_frame_sync_status, # type: ignore[union-attr,list-item] + + ] + readable_regs = [] + for readable_reg in self.dut.get_readable_registers(unroll=True): # type: ignore[union-attr] + self.assertIsInstance(readable_reg, (RegAsyncReadWrite, RegAsyncReadOnly)) + readable_regs.append(readable_reg) + self.assertCountEqual(expected_readable_regs, readable_regs) + + expected_readable_regs = [self.dut.Hash_ID_Low, # type: ignore[union-attr,list-item] + + self.dut.Hash_ID_High, # type: ignore[union-attr,list-item] + + self.dut.MSK_Init, # type: ignore[union-attr,list-item] + + self.dut.MSK_Control, # type: ignore[union-attr,list-item] + + self.dut.MSK_Status, # type: ignore[union-attr,list-item] + + self.dut.Tx_Bit_Count, # type: ignore[union-attr,list-item] + + self.dut.Tx_Enable_Count, # type: ignore[union-attr,list-item] + + self.dut.Fb_FreqWord, # type: ignore[union-attr,list-item] + + self.dut.TX_F1_FreqWord, # type: ignore[union-attr,list-item] + + self.dut.TX_F2_FreqWord, # type: ignore[union-attr,list-item] + + self.dut.RX_F1_FreqWord, # type: ignore[union-attr,list-item] + + self.dut.RX_F2_FreqWord, # type: ignore[union-attr,list-item] + + self.dut.LPF_Config_0, # type: ignore[union-attr,list-item] + + self.dut.LPF_Config_1, # type: ignore[union-attr,list-item] + + self.dut.Tx_Data_Width, # type: ignore[union-attr,list-item] + + self.dut.Rx_Data_Width, # type: ignore[union-attr,list-item] + + self.dut.PRBS_Control, # type: ignore[union-attr,list-item] + + self.dut.PRBS_Initial_State, # type: ignore[union-attr,list-item] + + self.dut.PRBS_Polynomial, # type: ignore[union-attr,list-item] + + self.dut.PRBS_Error_Mask, # type: ignore[union-attr,list-item] + + self.dut.PRBS_Bit_Count, # type: ignore[union-attr,list-item] + + self.dut.PRBS_Error_Count, # type: ignore[union-attr,list-item] + + self.dut.LPF_Accum_F1, # type: ignore[union-attr,list-item] + + self.dut.LPF_Accum_F2, # type: ignore[union-attr,list-item] + + self.dut.axis_xfer_count, # type: ignore[union-attr,list-item] + + self.dut.Rx_Sample_Discard, # type: ignore[union-attr,list-item] + + self.dut.LPF_Config_2, # type: ignore[union-attr,list-item] + + self.dut.f1_nco_adjust, # type: ignore[union-attr,list-item] + + self.dut.f2_nco_adjust, # type: ignore[union-attr,list-item] + + self.dut.f1_error, # type: ignore[union-attr,list-item] + + self.dut.f2_error, # type: ignore[union-attr,list-item] + + self.dut.Tx_Sync_Ctrl, # type: ignore[union-attr,list-item] + + self.dut.Tx_Sync_Cnt, # type: ignore[union-attr,list-item] + + self.dut.lowpass_ema_alpha1, # type: ignore[union-attr,list-item] + + self.dut.lowpass_ema_alpha2, # type: ignore[union-attr,list-item] + + self.dut.rx_power, # type: ignore[union-attr,list-item] + + self.dut.tx_async_fifo_rd_wr_ptr, # type: ignore[union-attr,list-item] + + self.dut.rx_async_fifo_rd_wr_ptr, # type: ignore[union-attr,list-item] + + self.dut.rx_frame_sync_status, # type: ignore[union-attr,list-item] + + ] + readable_regs = [] + for readable_reg in self.dut.get_readable_registers(unroll=False): # type: ignore[union-attr] + readable_regs.append(readable_reg) + self.assertCountEqual(expected_readable_regs, readable_regs) + + # check the writable registers + expected_writable_regs = [ + + + + self.dut.MSK_Init, # type: ignore[union-attr,list-item] + + self.dut.MSK_Control, # type: ignore[union-attr,list-item] + + + + self.dut.Tx_Bit_Count, # type: ignore[union-attr,list-item] + + self.dut.Tx_Enable_Count, # type: ignore[union-attr,list-item] + + self.dut.Fb_FreqWord, # type: ignore[union-attr,list-item] + + self.dut.TX_F1_FreqWord, # type: ignore[union-attr,list-item] + + self.dut.TX_F2_FreqWord, # type: ignore[union-attr,list-item] + + self.dut.RX_F1_FreqWord, # type: ignore[union-attr,list-item] + + self.dut.RX_F2_FreqWord, # type: ignore[union-attr,list-item] + + self.dut.LPF_Config_0, # type: ignore[union-attr,list-item] + + self.dut.LPF_Config_1, # type: ignore[union-attr,list-item] + + self.dut.Tx_Data_Width, # type: ignore[union-attr,list-item] + + self.dut.Rx_Data_Width, # type: ignore[union-attr,list-item] + + self.dut.PRBS_Control, # type: ignore[union-attr,list-item] + + self.dut.PRBS_Initial_State, # type: ignore[union-attr,list-item] + + self.dut.PRBS_Polynomial, # type: ignore[union-attr,list-item] + + self.dut.PRBS_Error_Mask, # type: ignore[union-attr,list-item] + + self.dut.PRBS_Bit_Count, # type: ignore[union-attr,list-item] + + self.dut.PRBS_Error_Count, # type: ignore[union-attr,list-item] + + self.dut.LPF_Accum_F1, # type: ignore[union-attr,list-item] + + self.dut.LPF_Accum_F2, # type: ignore[union-attr,list-item] + + self.dut.axis_xfer_count, # type: ignore[union-attr,list-item] + + self.dut.Rx_Sample_Discard, # type: ignore[union-attr,list-item] + + self.dut.LPF_Config_2, # type: ignore[union-attr,list-item] + + self.dut.f1_nco_adjust, # type: ignore[union-attr,list-item] + + self.dut.f2_nco_adjust, # type: ignore[union-attr,list-item] + + self.dut.f1_error, # type: ignore[union-attr,list-item] + + self.dut.f2_error, # type: ignore[union-attr,list-item] + + self.dut.Tx_Sync_Ctrl, # type: ignore[union-attr,list-item] + + self.dut.Tx_Sync_Cnt, # type: ignore[union-attr,list-item] + + self.dut.lowpass_ema_alpha1, # type: ignore[union-attr,list-item] + + self.dut.lowpass_ema_alpha2, # type: ignore[union-attr,list-item] + + self.dut.rx_power, # type: ignore[union-attr,list-item] + + self.dut.tx_async_fifo_rd_wr_ptr, # type: ignore[union-attr,list-item] + + self.dut.rx_async_fifo_rd_wr_ptr, # type: ignore[union-attr,list-item] + + self.dut.rx_frame_sync_status, # type: ignore[union-attr,list-item] + + ] + writable_regs = [] + for writable_reg in self.dut.get_writable_registers(unroll=True): # type: ignore[union-attr] + self.assertIsInstance(writable_reg, (RegAsyncReadWrite, RegAsyncWriteOnly)) + writable_regs.append(writable_reg) + self.assertCountEqual(expected_writable_regs, writable_regs) + + expected_writable_regs = [ + + + + self.dut.MSK_Init, # type: ignore[union-attr,list-item] + + self.dut.MSK_Control, # type: ignore[union-attr,list-item] + + + + self.dut.Tx_Bit_Count, # type: ignore[union-attr,list-item] + + self.dut.Tx_Enable_Count, # type: ignore[union-attr,list-item] + + self.dut.Fb_FreqWord, # type: ignore[union-attr,list-item] + + self.dut.TX_F1_FreqWord, # type: ignore[union-attr,list-item] + + self.dut.TX_F2_FreqWord, # type: ignore[union-attr,list-item] + + self.dut.RX_F1_FreqWord, # type: ignore[union-attr,list-item] + + self.dut.RX_F2_FreqWord, # type: ignore[union-attr,list-item] + + self.dut.LPF_Config_0, # type: ignore[union-attr,list-item] + + self.dut.LPF_Config_1, # type: ignore[union-attr,list-item] + + self.dut.Tx_Data_Width, # type: ignore[union-attr,list-item] + + self.dut.Rx_Data_Width, # type: ignore[union-attr,list-item] + + self.dut.PRBS_Control, # type: ignore[union-attr,list-item] + + self.dut.PRBS_Initial_State, # type: ignore[union-attr,list-item] + + self.dut.PRBS_Polynomial, # type: ignore[union-attr,list-item] + + self.dut.PRBS_Error_Mask, # type: ignore[union-attr,list-item] + + self.dut.PRBS_Bit_Count, # type: ignore[union-attr,list-item] + + self.dut.PRBS_Error_Count, # type: ignore[union-attr,list-item] + + self.dut.LPF_Accum_F1, # type: ignore[union-attr,list-item] + + self.dut.LPF_Accum_F2, # type: ignore[union-attr,list-item] + + self.dut.axis_xfer_count, # type: ignore[union-attr,list-item] + + self.dut.Rx_Sample_Discard, # type: ignore[union-attr,list-item] + + self.dut.LPF_Config_2, # type: ignore[union-attr,list-item] + + self.dut.f1_nco_adjust, # type: ignore[union-attr,list-item] + + self.dut.f2_nco_adjust, # type: ignore[union-attr,list-item] + + self.dut.f1_error, # type: ignore[union-attr,list-item] + + self.dut.f2_error, # type: ignore[union-attr,list-item] + + self.dut.Tx_Sync_Ctrl, # type: ignore[union-attr,list-item] + + self.dut.Tx_Sync_Cnt, # type: ignore[union-attr,list-item] + + self.dut.lowpass_ema_alpha1, # type: ignore[union-attr,list-item] + + self.dut.lowpass_ema_alpha2, # type: ignore[union-attr,list-item] + + self.dut.rx_power, # type: ignore[union-attr,list-item] + + self.dut.tx_async_fifo_rd_wr_ptr, # type: ignore[union-attr,list-item] + + self.dut.rx_async_fifo_rd_wr_ptr, # type: ignore[union-attr,list-item] + + self.dut.rx_frame_sync_status, # type: ignore[union-attr,list-item] + + ] + writable_regs = [] + for writable_reg in self.dut.get_writable_registers(unroll=False): # type: ignore[union-attr] + writable_regs.append(writable_reg) + self.assertCountEqual(expected_writable_regs, writable_regs) + + # check the sections + expected_sections = [ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ] + sections = [] + for section in self.dut.get_sections(unroll=True): # type: ignore[union-attr] + self.assertIsInstance(section, (AsyncAddressMap, AsyncRegFile)) + sections.append(section) + self.assertCountEqual(expected_sections, sections) + + expected_sections = [ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ] + sections = [] + for section in self.dut.get_sections(unroll=False): # type: ignore[union-attr] + sections.append(section) + self.assertCountEqual(expected_sections, sections) + + # check the memories + expected_memories = [ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ] + memories = [] + for memory in self.dut.get_memories(unroll=True): # type: ignore[union-attr] + self.assertIsInstance(memory, (MemoryAsyncReadOnly, MemoryAsyncWriteOnly, MemoryAsyncReadWrite)) + memories.append(memory) + self.assertCountEqual(expected_memories, memories) + + expected_memories = [ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ] + memories = [] + for memory in self.dut.get_memories(unroll=False): # type: ignore[union-attr] + self.assertIsInstance(memory, (MemoryAsyncReadOnly, MemoryAsyncWriteOnly, MemoryAsyncReadWrite, MemoryAsyncReadOnlyArray, MemoryAsyncWriteOnlyArray, MemoryAsyncReadWriteArray)) + memories.append(memory) + self.assertCountEqual(expected_memories, memories) + + + + + + + + + + + + def test_traversal_iterators(self) -> None: + """ + Walk the address map and check that the iterators for each node as as expected + """ + + expected_writable_fields: list[Union[FieldAsyncWriteOnly, FieldAsyncReadWrite]] + expected_readable_fields: list[Union[FieldAsyncReadOnly, FieldAsyncReadWrite]] + expected_fields: list[Union[FieldAsyncWriteOnly, FieldAsyncReadOnly, FieldAsyncReadWrite]] + expected_writable_regs: list[WritableAsyncRegister] + expected_readable_regs: list[ReadableAsyncRegister] + expected_memories:list[Union[MemoryAsyncReadOnly, MemoryAsyncWriteOnly, MemoryAsyncReadWrite]] + + + expected_sections : list[Union[AsyncAddressMap, AsyncRegFile]] + + # test all the registers + with self.subTest(msg='register: msk_top_regs.Hash_ID_Low'): + + expected_fields = [self.dut.Hash_ID_Low.hash_id_lo, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.Hash_ID_Low.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + # register should not have writable_fields attribute + self.assertFalse(hasattr(self.dut.Hash_ID_Low, 'writable_fields')) # type: ignore[union-attr] + + + expected_readable_fields = [self.dut.Hash_ID_Low.hash_id_lo, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.Hash_ID_Low.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.Hash_ID_High'): + + expected_fields = [self.dut.Hash_ID_High.hash_id_hi, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.Hash_ID_High.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + # register should not have writable_fields attribute + self.assertFalse(hasattr(self.dut.Hash_ID_High, 'writable_fields')) # type: ignore[union-attr] + + + expected_readable_fields = [self.dut.Hash_ID_High.hash_id_hi, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.Hash_ID_High.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.MSK_Init'): + + expected_fields = [self.dut.MSK_Init.txrxinit, # type: ignore[union-attr,list-item] + + + self.dut.MSK_Init.txinit, # type: ignore[union-attr,list-item] + + + self.dut.MSK_Init.rxinit, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.MSK_Init.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + expected_writable_fields = [self.dut.MSK_Init.txrxinit, # type: ignore[union-attr,list-item] + + self.dut.MSK_Init.txinit, # type: ignore[union-attr,list-item] + + self.dut.MSK_Init.rxinit, # type: ignore[union-attr,list-item] + + + ] + writable_fields = [] + for writable_field in self.dut.MSK_Init.writable_fields: # type: ignore[union-attr] + writable_fields.append(writable_field) + self.assertCountEqual(expected_writable_fields, writable_fields) + + + expected_readable_fields = [self.dut.MSK_Init.txrxinit, # type: ignore[union-attr,list-item] + + self.dut.MSK_Init.txinit, # type: ignore[union-attr,list-item] + + self.dut.MSK_Init.rxinit, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.MSK_Init.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.MSK_Control'): + + expected_fields = [self.dut.MSK_Control.ptt, # type: ignore[union-attr,list-item] + + + self.dut.MSK_Control.loopback_ena, # type: ignore[union-attr,list-item] + + + self.dut.MSK_Control.rx_invert, # type: ignore[union-attr,list-item] + + + self.dut.MSK_Control.clear_counts, # type: ignore[union-attr,list-item] + + + self.dut.MSK_Control.diff_encoder_loopback, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.MSK_Control.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + expected_writable_fields = [self.dut.MSK_Control.ptt, # type: ignore[union-attr,list-item] + + self.dut.MSK_Control.loopback_ena, # type: ignore[union-attr,list-item] + + self.dut.MSK_Control.rx_invert, # type: ignore[union-attr,list-item] + + self.dut.MSK_Control.clear_counts, # type: ignore[union-attr,list-item] + + self.dut.MSK_Control.diff_encoder_loopback, # type: ignore[union-attr,list-item] + + + ] + writable_fields = [] + for writable_field in self.dut.MSK_Control.writable_fields: # type: ignore[union-attr] + writable_fields.append(writable_field) + self.assertCountEqual(expected_writable_fields, writable_fields) + + + expected_readable_fields = [self.dut.MSK_Control.ptt, # type: ignore[union-attr,list-item] + + self.dut.MSK_Control.loopback_ena, # type: ignore[union-attr,list-item] + + self.dut.MSK_Control.rx_invert, # type: ignore[union-attr,list-item] + + self.dut.MSK_Control.clear_counts, # type: ignore[union-attr,list-item] + + self.dut.MSK_Control.diff_encoder_loopback, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.MSK_Control.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.MSK_Status'): + + expected_fields = [self.dut.MSK_Status.demod_sync_lock, # type: ignore[union-attr,list-item] + + + self.dut.MSK_Status.tx_enable, # type: ignore[union-attr,list-item] + + + self.dut.MSK_Status.rx_enable, # type: ignore[union-attr,list-item] + + + self.dut.MSK_Status.tx_axis_valid, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.MSK_Status.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + # register should not have writable_fields attribute + self.assertFalse(hasattr(self.dut.MSK_Status, 'writable_fields')) # type: ignore[union-attr] + + + expected_readable_fields = [self.dut.MSK_Status.demod_sync_lock, # type: ignore[union-attr,list-item] + + self.dut.MSK_Status.tx_enable, # type: ignore[union-attr,list-item] + + self.dut.MSK_Status.rx_enable, # type: ignore[union-attr,list-item] + + self.dut.MSK_Status.tx_axis_valid, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.MSK_Status.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.Tx_Bit_Count'): + + expected_fields = [self.dut.Tx_Bit_Count.data, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.Tx_Bit_Count.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + expected_writable_fields = [self.dut.Tx_Bit_Count.data, # type: ignore[union-attr,list-item] + + + ] + writable_fields = [] + for writable_field in self.dut.Tx_Bit_Count.writable_fields: # type: ignore[union-attr] + writable_fields.append(writable_field) + self.assertCountEqual(expected_writable_fields, writable_fields) + + + expected_readable_fields = [self.dut.Tx_Bit_Count.data, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.Tx_Bit_Count.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.Tx_Enable_Count'): + + expected_fields = [self.dut.Tx_Enable_Count.data, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.Tx_Enable_Count.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + expected_writable_fields = [self.dut.Tx_Enable_Count.data, # type: ignore[union-attr,list-item] + + + ] + writable_fields = [] + for writable_field in self.dut.Tx_Enable_Count.writable_fields: # type: ignore[union-attr] + writable_fields.append(writable_field) + self.assertCountEqual(expected_writable_fields, writable_fields) + + + expected_readable_fields = [self.dut.Tx_Enable_Count.data, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.Tx_Enable_Count.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.Fb_FreqWord'): + + expected_fields = [self.dut.Fb_FreqWord.config_data, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.Fb_FreqWord.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + expected_writable_fields = [self.dut.Fb_FreqWord.config_data, # type: ignore[union-attr,list-item] + + + ] + writable_fields = [] + for writable_field in self.dut.Fb_FreqWord.writable_fields: # type: ignore[union-attr] + writable_fields.append(writable_field) + self.assertCountEqual(expected_writable_fields, writable_fields) + + + expected_readable_fields = [self.dut.Fb_FreqWord.config_data, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.Fb_FreqWord.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.TX_F1_FreqWord'): + + expected_fields = [self.dut.TX_F1_FreqWord.config_data, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.TX_F1_FreqWord.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + expected_writable_fields = [self.dut.TX_F1_FreqWord.config_data, # type: ignore[union-attr,list-item] + + + ] + writable_fields = [] + for writable_field in self.dut.TX_F1_FreqWord.writable_fields: # type: ignore[union-attr] + writable_fields.append(writable_field) + self.assertCountEqual(expected_writable_fields, writable_fields) + + + expected_readable_fields = [self.dut.TX_F1_FreqWord.config_data, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.TX_F1_FreqWord.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.TX_F2_FreqWord'): + + expected_fields = [self.dut.TX_F2_FreqWord.config_data, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.TX_F2_FreqWord.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + expected_writable_fields = [self.dut.TX_F2_FreqWord.config_data, # type: ignore[union-attr,list-item] + + + ] + writable_fields = [] + for writable_field in self.dut.TX_F2_FreqWord.writable_fields: # type: ignore[union-attr] + writable_fields.append(writable_field) + self.assertCountEqual(expected_writable_fields, writable_fields) + + + expected_readable_fields = [self.dut.TX_F2_FreqWord.config_data, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.TX_F2_FreqWord.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.RX_F1_FreqWord'): + + expected_fields = [self.dut.RX_F1_FreqWord.config_data, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.RX_F1_FreqWord.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + expected_writable_fields = [self.dut.RX_F1_FreqWord.config_data, # type: ignore[union-attr,list-item] + + + ] + writable_fields = [] + for writable_field in self.dut.RX_F1_FreqWord.writable_fields: # type: ignore[union-attr] + writable_fields.append(writable_field) + self.assertCountEqual(expected_writable_fields, writable_fields) + + + expected_readable_fields = [self.dut.RX_F1_FreqWord.config_data, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.RX_F1_FreqWord.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.RX_F2_FreqWord'): + + expected_fields = [self.dut.RX_F2_FreqWord.config_data, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.RX_F2_FreqWord.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + expected_writable_fields = [self.dut.RX_F2_FreqWord.config_data, # type: ignore[union-attr,list-item] + + + ] + writable_fields = [] + for writable_field in self.dut.RX_F2_FreqWord.writable_fields: # type: ignore[union-attr] + writable_fields.append(writable_field) + self.assertCountEqual(expected_writable_fields, writable_fields) + + + expected_readable_fields = [self.dut.RX_F2_FreqWord.config_data, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.RX_F2_FreqWord.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.LPF_Config_0'): + + expected_fields = [self.dut.LPF_Config_0.lpf_freeze, # type: ignore[union-attr,list-item] + + + self.dut.LPF_Config_0.lpf_zero, # type: ignore[union-attr,list-item] + + + self.dut.LPF_Config_0.prbs_reserved, # type: ignore[union-attr,list-item] + + + self.dut.LPF_Config_0.lpf_alpha, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.LPF_Config_0.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + expected_writable_fields = [self.dut.LPF_Config_0.lpf_freeze, # type: ignore[union-attr,list-item] + + self.dut.LPF_Config_0.lpf_zero, # type: ignore[union-attr,list-item] + + self.dut.LPF_Config_0.prbs_reserved, # type: ignore[union-attr,list-item] + + self.dut.LPF_Config_0.lpf_alpha, # type: ignore[union-attr,list-item] + + + ] + writable_fields = [] + for writable_field in self.dut.LPF_Config_0.writable_fields: # type: ignore[union-attr] + writable_fields.append(writable_field) + self.assertCountEqual(expected_writable_fields, writable_fields) + + + expected_readable_fields = [self.dut.LPF_Config_0.lpf_freeze, # type: ignore[union-attr,list-item] + + self.dut.LPF_Config_0.lpf_zero, # type: ignore[union-attr,list-item] + + self.dut.LPF_Config_0.prbs_reserved, # type: ignore[union-attr,list-item] + + self.dut.LPF_Config_0.lpf_alpha, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.LPF_Config_0.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.LPF_Config_1'): + + expected_fields = [self.dut.LPF_Config_1.i_gain, # type: ignore[union-attr,list-item] + + + self.dut.LPF_Config_1.i_shift, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.LPF_Config_1.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + expected_writable_fields = [self.dut.LPF_Config_1.i_gain, # type: ignore[union-attr,list-item] + + self.dut.LPF_Config_1.i_shift, # type: ignore[union-attr,list-item] + + + ] + writable_fields = [] + for writable_field in self.dut.LPF_Config_1.writable_fields: # type: ignore[union-attr] + writable_fields.append(writable_field) + self.assertCountEqual(expected_writable_fields, writable_fields) + + + expected_readable_fields = [self.dut.LPF_Config_1.i_gain, # type: ignore[union-attr,list-item] + + self.dut.LPF_Config_1.i_shift, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.LPF_Config_1.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.Tx_Data_Width'): + + expected_fields = [self.dut.Tx_Data_Width.data_width, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.Tx_Data_Width.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + expected_writable_fields = [self.dut.Tx_Data_Width.data_width, # type: ignore[union-attr,list-item] + + + ] + writable_fields = [] + for writable_field in self.dut.Tx_Data_Width.writable_fields: # type: ignore[union-attr] + writable_fields.append(writable_field) + self.assertCountEqual(expected_writable_fields, writable_fields) + + + expected_readable_fields = [self.dut.Tx_Data_Width.data_width, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.Tx_Data_Width.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.Rx_Data_Width'): + + expected_fields = [self.dut.Rx_Data_Width.data_width, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.Rx_Data_Width.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + expected_writable_fields = [self.dut.Rx_Data_Width.data_width, # type: ignore[union-attr,list-item] + + + ] + writable_fields = [] + for writable_field in self.dut.Rx_Data_Width.writable_fields: # type: ignore[union-attr] + writable_fields.append(writable_field) + self.assertCountEqual(expected_writable_fields, writable_fields) + + + expected_readable_fields = [self.dut.Rx_Data_Width.data_width, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.Rx_Data_Width.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.PRBS_Control'): + + expected_fields = [self.dut.PRBS_Control.prbs_sel, # type: ignore[union-attr,list-item] + + + self.dut.PRBS_Control.prbs_error_insert, # type: ignore[union-attr,list-item] + + + self.dut.PRBS_Control.prbs_clear, # type: ignore[union-attr,list-item] + + + self.dut.PRBS_Control.prbs_manual_sync, # type: ignore[union-attr,list-item] + + + self.dut.PRBS_Control.prbs_reserved, # type: ignore[union-attr,list-item] + + + self.dut.PRBS_Control.prbs_sync_threshold, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.PRBS_Control.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + expected_writable_fields = [self.dut.PRBS_Control.prbs_sel, # type: ignore[union-attr,list-item] + + self.dut.PRBS_Control.prbs_error_insert, # type: ignore[union-attr,list-item] + + self.dut.PRBS_Control.prbs_clear, # type: ignore[union-attr,list-item] + + self.dut.PRBS_Control.prbs_manual_sync, # type: ignore[union-attr,list-item] + + self.dut.PRBS_Control.prbs_reserved, # type: ignore[union-attr,list-item] + + self.dut.PRBS_Control.prbs_sync_threshold, # type: ignore[union-attr,list-item] + + + ] + writable_fields = [] + for writable_field in self.dut.PRBS_Control.writable_fields: # type: ignore[union-attr] + writable_fields.append(writable_field) + self.assertCountEqual(expected_writable_fields, writable_fields) + + + expected_readable_fields = [self.dut.PRBS_Control.prbs_sel, # type: ignore[union-attr,list-item] + + + + + + + + self.dut.PRBS_Control.prbs_reserved, # type: ignore[union-attr,list-item] + + self.dut.PRBS_Control.prbs_sync_threshold, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.PRBS_Control.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.PRBS_Initial_State'): + + expected_fields = [self.dut.PRBS_Initial_State.config_data, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.PRBS_Initial_State.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + expected_writable_fields = [self.dut.PRBS_Initial_State.config_data, # type: ignore[union-attr,list-item] + + + ] + writable_fields = [] + for writable_field in self.dut.PRBS_Initial_State.writable_fields: # type: ignore[union-attr] + writable_fields.append(writable_field) + self.assertCountEqual(expected_writable_fields, writable_fields) + + + expected_readable_fields = [self.dut.PRBS_Initial_State.config_data, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.PRBS_Initial_State.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.PRBS_Polynomial'): + + expected_fields = [self.dut.PRBS_Polynomial.config_data, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.PRBS_Polynomial.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + expected_writable_fields = [self.dut.PRBS_Polynomial.config_data, # type: ignore[union-attr,list-item] + + + ] + writable_fields = [] + for writable_field in self.dut.PRBS_Polynomial.writable_fields: # type: ignore[union-attr] + writable_fields.append(writable_field) + self.assertCountEqual(expected_writable_fields, writable_fields) + + + expected_readable_fields = [self.dut.PRBS_Polynomial.config_data, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.PRBS_Polynomial.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.PRBS_Error_Mask'): + + expected_fields = [self.dut.PRBS_Error_Mask.config_data, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.PRBS_Error_Mask.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + expected_writable_fields = [self.dut.PRBS_Error_Mask.config_data, # type: ignore[union-attr,list-item] + + + ] + writable_fields = [] + for writable_field in self.dut.PRBS_Error_Mask.writable_fields: # type: ignore[union-attr] + writable_fields.append(writable_field) + self.assertCountEqual(expected_writable_fields, writable_fields) + + + expected_readable_fields = [self.dut.PRBS_Error_Mask.config_data, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.PRBS_Error_Mask.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.PRBS_Bit_Count'): + + expected_fields = [self.dut.PRBS_Bit_Count.data, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.PRBS_Bit_Count.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + expected_writable_fields = [self.dut.PRBS_Bit_Count.data, # type: ignore[union-attr,list-item] + + + ] + writable_fields = [] + for writable_field in self.dut.PRBS_Bit_Count.writable_fields: # type: ignore[union-attr] + writable_fields.append(writable_field) + self.assertCountEqual(expected_writable_fields, writable_fields) + + + expected_readable_fields = [self.dut.PRBS_Bit_Count.data, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.PRBS_Bit_Count.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.PRBS_Error_Count'): + + expected_fields = [self.dut.PRBS_Error_Count.data, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.PRBS_Error_Count.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + expected_writable_fields = [self.dut.PRBS_Error_Count.data, # type: ignore[union-attr,list-item] + + + ] + writable_fields = [] + for writable_field in self.dut.PRBS_Error_Count.writable_fields: # type: ignore[union-attr] + writable_fields.append(writable_field) + self.assertCountEqual(expected_writable_fields, writable_fields) + + + expected_readable_fields = [self.dut.PRBS_Error_Count.data, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.PRBS_Error_Count.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.LPF_Accum_F1'): + + expected_fields = [self.dut.LPF_Accum_F1.data, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.LPF_Accum_F1.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + expected_writable_fields = [self.dut.LPF_Accum_F1.data, # type: ignore[union-attr,list-item] + + + ] + writable_fields = [] + for writable_field in self.dut.LPF_Accum_F1.writable_fields: # type: ignore[union-attr] + writable_fields.append(writable_field) + self.assertCountEqual(expected_writable_fields, writable_fields) + + + expected_readable_fields = [self.dut.LPF_Accum_F1.data, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.LPF_Accum_F1.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.LPF_Accum_F2'): + + expected_fields = [self.dut.LPF_Accum_F2.data, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.LPF_Accum_F2.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + expected_writable_fields = [self.dut.LPF_Accum_F2.data, # type: ignore[union-attr,list-item] + + + ] + writable_fields = [] + for writable_field in self.dut.LPF_Accum_F2.writable_fields: # type: ignore[union-attr] + writable_fields.append(writable_field) + self.assertCountEqual(expected_writable_fields, writable_fields) + + + expected_readable_fields = [self.dut.LPF_Accum_F2.data, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.LPF_Accum_F2.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.axis_xfer_count'): + + expected_fields = [self.dut.axis_xfer_count.data, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.axis_xfer_count.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + expected_writable_fields = [self.dut.axis_xfer_count.data, # type: ignore[union-attr,list-item] + + + ] + writable_fields = [] + for writable_field in self.dut.axis_xfer_count.writable_fields: # type: ignore[union-attr] + writable_fields.append(writable_field) + self.assertCountEqual(expected_writable_fields, writable_fields) + + + expected_readable_fields = [self.dut.axis_xfer_count.data, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.axis_xfer_count.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.Rx_Sample_Discard'): + + expected_fields = [self.dut.Rx_Sample_Discard.rx_sample_discard, # type: ignore[union-attr,list-item] + + + self.dut.Rx_Sample_Discard.rx_nco_discard, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.Rx_Sample_Discard.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + expected_writable_fields = [self.dut.Rx_Sample_Discard.rx_sample_discard, # type: ignore[union-attr,list-item] + + self.dut.Rx_Sample_Discard.rx_nco_discard, # type: ignore[union-attr,list-item] + + + ] + writable_fields = [] + for writable_field in self.dut.Rx_Sample_Discard.writable_fields: # type: ignore[union-attr] + writable_fields.append(writable_field) + self.assertCountEqual(expected_writable_fields, writable_fields) + + + expected_readable_fields = [self.dut.Rx_Sample_Discard.rx_sample_discard, # type: ignore[union-attr,list-item] + + self.dut.Rx_Sample_Discard.rx_nco_discard, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.Rx_Sample_Discard.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.LPF_Config_2'): + + expected_fields = [self.dut.LPF_Config_2.p_gain, # type: ignore[union-attr,list-item] + + + self.dut.LPF_Config_2.p_shift, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.LPF_Config_2.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + expected_writable_fields = [self.dut.LPF_Config_2.p_gain, # type: ignore[union-attr,list-item] + + self.dut.LPF_Config_2.p_shift, # type: ignore[union-attr,list-item] + + + ] + writable_fields = [] + for writable_field in self.dut.LPF_Config_2.writable_fields: # type: ignore[union-attr] + writable_fields.append(writable_field) + self.assertCountEqual(expected_writable_fields, writable_fields) + + + expected_readable_fields = [self.dut.LPF_Config_2.p_gain, # type: ignore[union-attr,list-item] + + self.dut.LPF_Config_2.p_shift, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.LPF_Config_2.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.f1_nco_adjust'): + + expected_fields = [self.dut.f1_nco_adjust.data, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.f1_nco_adjust.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + expected_writable_fields = [self.dut.f1_nco_adjust.data, # type: ignore[union-attr,list-item] + + + ] + writable_fields = [] + for writable_field in self.dut.f1_nco_adjust.writable_fields: # type: ignore[union-attr] + writable_fields.append(writable_field) + self.assertCountEqual(expected_writable_fields, writable_fields) + + + expected_readable_fields = [self.dut.f1_nco_adjust.data, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.f1_nco_adjust.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.f2_nco_adjust'): + + expected_fields = [self.dut.f2_nco_adjust.data, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.f2_nco_adjust.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + expected_writable_fields = [self.dut.f2_nco_adjust.data, # type: ignore[union-attr,list-item] + + + ] + writable_fields = [] + for writable_field in self.dut.f2_nco_adjust.writable_fields: # type: ignore[union-attr] + writable_fields.append(writable_field) + self.assertCountEqual(expected_writable_fields, writable_fields) + + + expected_readable_fields = [self.dut.f2_nco_adjust.data, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.f2_nco_adjust.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.f1_error'): + + expected_fields = [self.dut.f1_error.data, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.f1_error.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + expected_writable_fields = [self.dut.f1_error.data, # type: ignore[union-attr,list-item] + + + ] + writable_fields = [] + for writable_field in self.dut.f1_error.writable_fields: # type: ignore[union-attr] + writable_fields.append(writable_field) + self.assertCountEqual(expected_writable_fields, writable_fields) + + + expected_readable_fields = [self.dut.f1_error.data, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.f1_error.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.f2_error'): + + expected_fields = [self.dut.f2_error.data, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.f2_error.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + expected_writable_fields = [self.dut.f2_error.data, # type: ignore[union-attr,list-item] + + + ] + writable_fields = [] + for writable_field in self.dut.f2_error.writable_fields: # type: ignore[union-attr] + writable_fields.append(writable_field) + self.assertCountEqual(expected_writable_fields, writable_fields) + + + expected_readable_fields = [self.dut.f2_error.data, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.f2_error.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.Tx_Sync_Ctrl'): + + expected_fields = [self.dut.Tx_Sync_Ctrl.tx_sync_ena, # type: ignore[union-attr,list-item] + + + self.dut.Tx_Sync_Ctrl.tx_sync_force, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.Tx_Sync_Ctrl.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + expected_writable_fields = [self.dut.Tx_Sync_Ctrl.tx_sync_ena, # type: ignore[union-attr,list-item] + + self.dut.Tx_Sync_Ctrl.tx_sync_force, # type: ignore[union-attr,list-item] + + + ] + writable_fields = [] + for writable_field in self.dut.Tx_Sync_Ctrl.writable_fields: # type: ignore[union-attr] + writable_fields.append(writable_field) + self.assertCountEqual(expected_writable_fields, writable_fields) + + + expected_readable_fields = [self.dut.Tx_Sync_Ctrl.tx_sync_ena, # type: ignore[union-attr,list-item] + + self.dut.Tx_Sync_Ctrl.tx_sync_force, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.Tx_Sync_Ctrl.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.Tx_Sync_Cnt'): + + expected_fields = [self.dut.Tx_Sync_Cnt.tx_sync_cnt, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.Tx_Sync_Cnt.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + expected_writable_fields = [self.dut.Tx_Sync_Cnt.tx_sync_cnt, # type: ignore[union-attr,list-item] + + + ] + writable_fields = [] + for writable_field in self.dut.Tx_Sync_Cnt.writable_fields: # type: ignore[union-attr] + writable_fields.append(writable_field) + self.assertCountEqual(expected_writable_fields, writable_fields) + + + expected_readable_fields = [self.dut.Tx_Sync_Cnt.tx_sync_cnt, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.Tx_Sync_Cnt.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.lowpass_ema_alpha1'): + + expected_fields = [self.dut.lowpass_ema_alpha1.alpha, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.lowpass_ema_alpha1.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + expected_writable_fields = [self.dut.lowpass_ema_alpha1.alpha, # type: ignore[union-attr,list-item] + + + ] + writable_fields = [] + for writable_field in self.dut.lowpass_ema_alpha1.writable_fields: # type: ignore[union-attr] + writable_fields.append(writable_field) + self.assertCountEqual(expected_writable_fields, writable_fields) + + + expected_readable_fields = [self.dut.lowpass_ema_alpha1.alpha, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.lowpass_ema_alpha1.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.lowpass_ema_alpha2'): + + expected_fields = [self.dut.lowpass_ema_alpha2.alpha, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.lowpass_ema_alpha2.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + expected_writable_fields = [self.dut.lowpass_ema_alpha2.alpha, # type: ignore[union-attr,list-item] + + + ] + writable_fields = [] + for writable_field in self.dut.lowpass_ema_alpha2.writable_fields: # type: ignore[union-attr] + writable_fields.append(writable_field) + self.assertCountEqual(expected_writable_fields, writable_fields) + + + expected_readable_fields = [self.dut.lowpass_ema_alpha2.alpha, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.lowpass_ema_alpha2.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.rx_power'): + + expected_fields = [self.dut.rx_power.data, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.rx_power.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + expected_writable_fields = [self.dut.rx_power.data, # type: ignore[union-attr,list-item] + + + ] + writable_fields = [] + for writable_field in self.dut.rx_power.writable_fields: # type: ignore[union-attr] + writable_fields.append(writable_field) + self.assertCountEqual(expected_writable_fields, writable_fields) + + + expected_readable_fields = [self.dut.rx_power.data, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.rx_power.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.tx_async_fifo_rd_wr_ptr'): + + expected_fields = [self.dut.tx_async_fifo_rd_wr_ptr.data, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.tx_async_fifo_rd_wr_ptr.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + expected_writable_fields = [self.dut.tx_async_fifo_rd_wr_ptr.data, # type: ignore[union-attr,list-item] + + + ] + writable_fields = [] + for writable_field in self.dut.tx_async_fifo_rd_wr_ptr.writable_fields: # type: ignore[union-attr] + writable_fields.append(writable_field) + self.assertCountEqual(expected_writable_fields, writable_fields) + + + expected_readable_fields = [self.dut.tx_async_fifo_rd_wr_ptr.data, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.tx_async_fifo_rd_wr_ptr.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.rx_async_fifo_rd_wr_ptr'): + + expected_fields = [self.dut.rx_async_fifo_rd_wr_ptr.data, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.rx_async_fifo_rd_wr_ptr.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + expected_writable_fields = [self.dut.rx_async_fifo_rd_wr_ptr.data, # type: ignore[union-attr,list-item] + + + ] + writable_fields = [] + for writable_field in self.dut.rx_async_fifo_rd_wr_ptr.writable_fields: # type: ignore[union-attr] + writable_fields.append(writable_field) + self.assertCountEqual(expected_writable_fields, writable_fields) + + + expected_readable_fields = [self.dut.rx_async_fifo_rd_wr_ptr.data, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.rx_async_fifo_rd_wr_ptr.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + with self.subTest(msg='register: msk_top_regs.rx_frame_sync_status'): + + expected_fields = [self.dut.rx_frame_sync_status.frame_sync_locked, # type: ignore[union-attr,list-item] + + + self.dut.rx_frame_sync_status.frame_buffer_overflow, # type: ignore[union-attr,list-item] + + + self.dut.rx_frame_sync_status.frames_received, # type: ignore[union-attr,list-item] + + + self.dut.rx_frame_sync_status.frame_sync_errors, # type: ignore[union-attr,list-item] + + + + ] + fields = [] + for field in self.dut.rx_frame_sync_status.fields: # type: ignore[union-attr] + fields.append(field) + self.assertCountEqual(expected_fields, fields) + + expected_writable_fields = [ + + + + self.dut.rx_frame_sync_status.frames_received, # type: ignore[union-attr,list-item] + + self.dut.rx_frame_sync_status.frame_sync_errors, # type: ignore[union-attr,list-item] + + + ] + writable_fields = [] + for writable_field in self.dut.rx_frame_sync_status.writable_fields: # type: ignore[union-attr] + writable_fields.append(writable_field) + self.assertCountEqual(expected_writable_fields, writable_fields) + + + expected_readable_fields = [self.dut.rx_frame_sync_status.frame_sync_locked, # type: ignore[union-attr,list-item] + + self.dut.rx_frame_sync_status.frame_buffer_overflow, # type: ignore[union-attr,list-item] + + self.dut.rx_frame_sync_status.frames_received, # type: ignore[union-attr,list-item] + + self.dut.rx_frame_sync_status.frame_sync_errors, # type: ignore[union-attr,list-item] + + + ] + readable_fields = [] + for readable_field in self.dut.rx_frame_sync_status.readable_fields: # type: ignore[union-attr] + readable_fields.append(readable_field) + self.assertCountEqual(expected_readable_fields, readable_fields) + + + # test all the memories + + # test all the address maps + + # test all the register files + + + def test_name_map(self) -> None: + """ + Check that the function for getting a node by its original systemRDL name works + """ + + + self.assertEqual(self.dut.Hash_ID_Low.get_child_by_system_rdl_name('hash_id_lo').inst_name, 'hash_id_lo') + + + + + + self.assertEqual(self.dut.Hash_ID_High.get_child_by_system_rdl_name('hash_id_hi').inst_name, 'hash_id_hi') + + + + + + self.assertEqual(self.dut.MSK_Init.get_child_by_system_rdl_name('txrxinit').inst_name, 'txrxinit') + + + + + self.assertEqual(self.dut.MSK_Init.get_child_by_system_rdl_name('txinit').inst_name, 'txinit') + + + + + self.assertEqual(self.dut.MSK_Init.get_child_by_system_rdl_name('rxinit').inst_name, 'rxinit') + + + + + + self.assertEqual(self.dut.MSK_Control.get_child_by_system_rdl_name('ptt').inst_name, 'ptt') + + + + + self.assertEqual(self.dut.MSK_Control.get_child_by_system_rdl_name('loopback_ena').inst_name, 'loopback_ena') + + + + + self.assertEqual(self.dut.MSK_Control.get_child_by_system_rdl_name('rx_invert').inst_name, 'rx_invert') + + + + + self.assertEqual(self.dut.MSK_Control.get_child_by_system_rdl_name('clear_counts').inst_name, 'clear_counts') + + + + + self.assertEqual(self.dut.MSK_Control.get_child_by_system_rdl_name('diff_encoder_loopback').inst_name, 'diff_encoder_loopback') + + + + + + self.assertEqual(self.dut.MSK_Status.get_child_by_system_rdl_name('demod_sync_lock').inst_name, 'demod_sync_lock') + + + + + self.assertEqual(self.dut.MSK_Status.get_child_by_system_rdl_name('tx_enable').inst_name, 'tx_enable') + + + + + self.assertEqual(self.dut.MSK_Status.get_child_by_system_rdl_name('rx_enable').inst_name, 'rx_enable') + + + + + self.assertEqual(self.dut.MSK_Status.get_child_by_system_rdl_name('tx_axis_valid').inst_name, 'tx_axis_valid') + + + + + + self.assertEqual(self.dut.Tx_Bit_Count.get_child_by_system_rdl_name('data').inst_name, 'data') + + + + + + self.assertEqual(self.dut.Tx_Enable_Count.get_child_by_system_rdl_name('data').inst_name, 'data') + + + + + + self.assertEqual(self.dut.Fb_FreqWord.get_child_by_system_rdl_name('config_data').inst_name, 'config_data') + + + + + + self.assertEqual(self.dut.TX_F1_FreqWord.get_child_by_system_rdl_name('config_data').inst_name, 'config_data') + + + + + + self.assertEqual(self.dut.TX_F2_FreqWord.get_child_by_system_rdl_name('config_data').inst_name, 'config_data') + + + + + + self.assertEqual(self.dut.RX_F1_FreqWord.get_child_by_system_rdl_name('config_data').inst_name, 'config_data') + + + + + + self.assertEqual(self.dut.RX_F2_FreqWord.get_child_by_system_rdl_name('config_data').inst_name, 'config_data') + + + + + + self.assertEqual(self.dut.LPF_Config_0.get_child_by_system_rdl_name('lpf_freeze').inst_name, 'lpf_freeze') + + + + + self.assertEqual(self.dut.LPF_Config_0.get_child_by_system_rdl_name('lpf_zero').inst_name, 'lpf_zero') + + + + + self.assertEqual(self.dut.LPF_Config_0.get_child_by_system_rdl_name('prbs_reserved').inst_name, 'prbs_reserved') + + + + + self.assertEqual(self.dut.LPF_Config_0.get_child_by_system_rdl_name('lpf_alpha').inst_name, 'lpf_alpha') + + + + + + self.assertEqual(self.dut.LPF_Config_1.get_child_by_system_rdl_name('i_gain').inst_name, 'i_gain') + + + + + self.assertEqual(self.dut.LPF_Config_1.get_child_by_system_rdl_name('i_shift').inst_name, 'i_shift') + + + + + + self.assertEqual(self.dut.Tx_Data_Width.get_child_by_system_rdl_name('data_width').inst_name, 'data_width') + + + + + + self.assertEqual(self.dut.Rx_Data_Width.get_child_by_system_rdl_name('data_width').inst_name, 'data_width') + + + + + + self.assertEqual(self.dut.PRBS_Control.get_child_by_system_rdl_name('prbs_sel').inst_name, 'prbs_sel') + + + + + self.assertEqual(self.dut.PRBS_Control.get_child_by_system_rdl_name('prbs_error_insert').inst_name, 'prbs_error_insert') + + + + + self.assertEqual(self.dut.PRBS_Control.get_child_by_system_rdl_name('prbs_clear').inst_name, 'prbs_clear') + + + + + self.assertEqual(self.dut.PRBS_Control.get_child_by_system_rdl_name('prbs_manual_sync').inst_name, 'prbs_manual_sync') + + + + + self.assertEqual(self.dut.PRBS_Control.get_child_by_system_rdl_name('prbs_reserved').inst_name, 'prbs_reserved') + + + + + self.assertEqual(self.dut.PRBS_Control.get_child_by_system_rdl_name('prbs_sync_threshold').inst_name, 'prbs_sync_threshold') + + + + + + self.assertEqual(self.dut.PRBS_Initial_State.get_child_by_system_rdl_name('config_data').inst_name, 'config_data') + + + + + + self.assertEqual(self.dut.PRBS_Polynomial.get_child_by_system_rdl_name('config_data').inst_name, 'config_data') + + + + + + self.assertEqual(self.dut.PRBS_Error_Mask.get_child_by_system_rdl_name('config_data').inst_name, 'config_data') + + + + + + self.assertEqual(self.dut.PRBS_Bit_Count.get_child_by_system_rdl_name('data').inst_name, 'data') + + + + + + self.assertEqual(self.dut.PRBS_Error_Count.get_child_by_system_rdl_name('data').inst_name, 'data') + + + + + + self.assertEqual(self.dut.LPF_Accum_F1.get_child_by_system_rdl_name('data').inst_name, 'data') + + + + + + self.assertEqual(self.dut.LPF_Accum_F2.get_child_by_system_rdl_name('data').inst_name, 'data') + + + + + + self.assertEqual(self.dut.axis_xfer_count.get_child_by_system_rdl_name('data').inst_name, 'data') + + + + + + self.assertEqual(self.dut.Rx_Sample_Discard.get_child_by_system_rdl_name('rx_sample_discard').inst_name, 'rx_sample_discard') + + + + + self.assertEqual(self.dut.Rx_Sample_Discard.get_child_by_system_rdl_name('rx_nco_discard').inst_name, 'rx_nco_discard') + + + + + + self.assertEqual(self.dut.LPF_Config_2.get_child_by_system_rdl_name('p_gain').inst_name, 'p_gain') + + + + + self.assertEqual(self.dut.LPF_Config_2.get_child_by_system_rdl_name('p_shift').inst_name, 'p_shift') + + + + + + self.assertEqual(self.dut.f1_nco_adjust.get_child_by_system_rdl_name('data').inst_name, 'data') + + + + + + self.assertEqual(self.dut.f2_nco_adjust.get_child_by_system_rdl_name('data').inst_name, 'data') + + + + + + self.assertEqual(self.dut.f1_error.get_child_by_system_rdl_name('data').inst_name, 'data') + + + + + + self.assertEqual(self.dut.f2_error.get_child_by_system_rdl_name('data').inst_name, 'data') + + + + + + self.assertEqual(self.dut.Tx_Sync_Ctrl.get_child_by_system_rdl_name('tx_sync_ena').inst_name, 'tx_sync_ena') + + + + + self.assertEqual(self.dut.Tx_Sync_Ctrl.get_child_by_system_rdl_name('tx_sync_force').inst_name, 'tx_sync_force') + + + + + + self.assertEqual(self.dut.Tx_Sync_Cnt.get_child_by_system_rdl_name('tx_sync_cnt').inst_name, 'tx_sync_cnt') + + + + + + self.assertEqual(self.dut.lowpass_ema_alpha1.get_child_by_system_rdl_name('alpha').inst_name, 'alpha') + + + + + + self.assertEqual(self.dut.lowpass_ema_alpha2.get_child_by_system_rdl_name('alpha').inst_name, 'alpha') + + + + + + self.assertEqual(self.dut.rx_power.get_child_by_system_rdl_name('data').inst_name, 'data') + + + + + + self.assertEqual(self.dut.tx_async_fifo_rd_wr_ptr.get_child_by_system_rdl_name('data').inst_name, 'data') + + + + + + self.assertEqual(self.dut.rx_async_fifo_rd_wr_ptr.get_child_by_system_rdl_name('data').inst_name, 'data') + + + + + + self.assertEqual(self.dut.rx_frame_sync_status.get_child_by_system_rdl_name('frame_sync_locked').inst_name, 'frame_sync_locked') + + + + + self.assertEqual(self.dut.rx_frame_sync_status.get_child_by_system_rdl_name('frame_buffer_overflow').inst_name, 'frame_buffer_overflow') + + + + + self.assertEqual(self.dut.rx_frame_sync_status.get_child_by_system_rdl_name('frames_received').inst_name, 'frames_received') + + + + + self.assertEqual(self.dut.rx_frame_sync_status.get_child_by_system_rdl_name('frame_sync_errors').inst_name, 'frame_sync_errors') + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +class msk_top_regs_block_access(msk_top_regs_TestCase_BlockAccess): # type: ignore[valid-type,misc] + """ + tests for all the block access methods + """ + + + + async def test_register_array_context_manager(self) -> None: + """ + Walk the register map and check that register map context managers work correctly + """ + + +class msk_top_regs_alt_block_access(msk_top_regs_TestCase_AltBlockAccess): # type: ignore[valid-type,misc] + """ + tests for all the block access methods with the alternative callbacks, this is a simpler + version of the tests above + """ + + + async def test_register_array_context_manager(self) -> None: + """ + Walk the register map and check that register map context managers work correctly + """ + + + +if __name__ == '__main__': + + if sys.version_info < (3, 8): + asynctest.main() + else: + unittest.main() + + + + diff --git a/rdl/outputs/python/msk_top_regs/tests/test_sim_msk_top_regs.py b/rdl/outputs/python/msk_top_regs/tests/test_sim_msk_top_regs.py new file mode 100644 index 0000000..3cf4d4b --- /dev/null +++ b/rdl/outputs/python/msk_top_regs/tests/test_sim_msk_top_regs.py @@ -0,0 +1,8857 @@ + + + +""" +Unit Tests for the msk_top_regs register model Python Wrapper + +This code was generated from the PeakRDL-python package version 1.4.0 +""" + + +from typing import Union, cast + +import sys +import asyncio +import unittest +from unittest.mock import Mock + +import random + + +from ..sim_lib.register import Register,MemoryRegister +from ..sim_lib.field import Field + +from ._msk_top_regs_sim_test_base import msk_top_regs_SimTestCase, msk_top_regs_SimTestCase_BlockAccess +from ._msk_top_regs_sim_test_base import __name__ as base_name +from ._msk_top_regs_test_base import random_enum_reg_value + + +from ..lib import SystemRDLEnum + + +class msk_top_regs_single_access(msk_top_regs_SimTestCase): # type: ignore[valid-type,misc] + + async def test_register_read_and_write(self) -> None: + """ + Walk the register map and check every register can be read and written to correctly + """ + # test access operations (read and/or write) to register: + # msk_top_regs.Hash_ID_Low + with self.subTest(msg='register: msk_top_regs.Hash_ID_Low'): + sim_register = self.sim.register_by_full_name('msk_top_regs.Hash_ID_Low') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.Hash_ID_Low.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.Hash_ID_Low.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.Hash_ID_Low.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + + + # test access operations (read and/or write) to register: + # msk_top_regs.Hash_ID_High + with self.subTest(msg='register: msk_top_regs.Hash_ID_High'): + sim_register = self.sim.register_by_full_name('msk_top_regs.Hash_ID_High') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.Hash_ID_High.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.Hash_ID_High.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.Hash_ID_High.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + + + # test access operations (read and/or write) to register: + # msk_top_regs.MSK_Init + with self.subTest(msg='register: msk_top_regs.MSK_Init'): + sim_register = self.sim.register_by_full_name('msk_top_regs.MSK_Init') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.MSK_Init.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.MSK_Init.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.MSK_Init.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + # register write checks + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.MSK_Init.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.MSK_Init.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + register_write_callback.assert_called_once_with(value=random_value) + register_read_callback.assert_not_called() + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.MSK_Init.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + self.assertEqual(await self.dut.MSK_Init.read(), random_value) + + + + # test access operations (read and/or write) to register: + # msk_top_regs.MSK_Control + with self.subTest(msg='register: msk_top_regs.MSK_Control'): + sim_register = self.sim.register_by_full_name('msk_top_regs.MSK_Control') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.MSK_Control.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.MSK_Control.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.MSK_Control.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + # register write checks + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.MSK_Control.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.MSK_Control.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + register_write_callback.assert_called_once_with(value=random_value) + register_read_callback.assert_not_called() + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.MSK_Control.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + self.assertEqual(await self.dut.MSK_Control.read(), random_value) + + + + # test access operations (read and/or write) to register: + # msk_top_regs.MSK_Status + with self.subTest(msg='register: msk_top_regs.MSK_Status'): + sim_register = self.sim.register_by_full_name('msk_top_regs.MSK_Status') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.MSK_Status.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.MSK_Status.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.MSK_Status.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + + + # test access operations (read and/or write) to register: + # msk_top_regs.Tx_Bit_Count + with self.subTest(msg='register: msk_top_regs.Tx_Bit_Count'): + sim_register = self.sim.register_by_full_name('msk_top_regs.Tx_Bit_Count') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.Tx_Bit_Count.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.Tx_Bit_Count.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.Tx_Bit_Count.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + # register write checks + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.Tx_Bit_Count.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.Tx_Bit_Count.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + register_write_callback.assert_called_once_with(value=random_value) + register_read_callback.assert_not_called() + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.Tx_Bit_Count.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + self.assertEqual(await self.dut.Tx_Bit_Count.read(), random_value) + + + + # test access operations (read and/or write) to register: + # msk_top_regs.Tx_Enable_Count + with self.subTest(msg='register: msk_top_regs.Tx_Enable_Count'): + sim_register = self.sim.register_by_full_name('msk_top_regs.Tx_Enable_Count') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.Tx_Enable_Count.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.Tx_Enable_Count.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.Tx_Enable_Count.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + # register write checks + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.Tx_Enable_Count.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.Tx_Enable_Count.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + register_write_callback.assert_called_once_with(value=random_value) + register_read_callback.assert_not_called() + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.Tx_Enable_Count.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + self.assertEqual(await self.dut.Tx_Enable_Count.read(), random_value) + + + + # test access operations (read and/or write) to register: + # msk_top_regs.Fb_FreqWord + with self.subTest(msg='register: msk_top_regs.Fb_FreqWord'): + sim_register = self.sim.register_by_full_name('msk_top_regs.Fb_FreqWord') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.Fb_FreqWord.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.Fb_FreqWord.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.Fb_FreqWord.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + # register write checks + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.Fb_FreqWord.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.Fb_FreqWord.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + register_write_callback.assert_called_once_with(value=random_value) + register_read_callback.assert_not_called() + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.Fb_FreqWord.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + self.assertEqual(await self.dut.Fb_FreqWord.read(), random_value) + + + + # test access operations (read and/or write) to register: + # msk_top_regs.TX_F1_FreqWord + with self.subTest(msg='register: msk_top_regs.TX_F1_FreqWord'): + sim_register = self.sim.register_by_full_name('msk_top_regs.TX_F1_FreqWord') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.TX_F1_FreqWord.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.TX_F1_FreqWord.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.TX_F1_FreqWord.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + # register write checks + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.TX_F1_FreqWord.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.TX_F1_FreqWord.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + register_write_callback.assert_called_once_with(value=random_value) + register_read_callback.assert_not_called() + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.TX_F1_FreqWord.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + self.assertEqual(await self.dut.TX_F1_FreqWord.read(), random_value) + + + + # test access operations (read and/or write) to register: + # msk_top_regs.TX_F2_FreqWord + with self.subTest(msg='register: msk_top_regs.TX_F2_FreqWord'): + sim_register = self.sim.register_by_full_name('msk_top_regs.TX_F2_FreqWord') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.TX_F2_FreqWord.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.TX_F2_FreqWord.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.TX_F2_FreqWord.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + # register write checks + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.TX_F2_FreqWord.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.TX_F2_FreqWord.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + register_write_callback.assert_called_once_with(value=random_value) + register_read_callback.assert_not_called() + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.TX_F2_FreqWord.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + self.assertEqual(await self.dut.TX_F2_FreqWord.read(), random_value) + + + + # test access operations (read and/or write) to register: + # msk_top_regs.RX_F1_FreqWord + with self.subTest(msg='register: msk_top_regs.RX_F1_FreqWord'): + sim_register = self.sim.register_by_full_name('msk_top_regs.RX_F1_FreqWord') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.RX_F1_FreqWord.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.RX_F1_FreqWord.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.RX_F1_FreqWord.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + # register write checks + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.RX_F1_FreqWord.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.RX_F1_FreqWord.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + register_write_callback.assert_called_once_with(value=random_value) + register_read_callback.assert_not_called() + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.RX_F1_FreqWord.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + self.assertEqual(await self.dut.RX_F1_FreqWord.read(), random_value) + + + + # test access operations (read and/or write) to register: + # msk_top_regs.RX_F2_FreqWord + with self.subTest(msg='register: msk_top_regs.RX_F2_FreqWord'): + sim_register = self.sim.register_by_full_name('msk_top_regs.RX_F2_FreqWord') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.RX_F2_FreqWord.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.RX_F2_FreqWord.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.RX_F2_FreqWord.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + # register write checks + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.RX_F2_FreqWord.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.RX_F2_FreqWord.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + register_write_callback.assert_called_once_with(value=random_value) + register_read_callback.assert_not_called() + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.RX_F2_FreqWord.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + self.assertEqual(await self.dut.RX_F2_FreqWord.read(), random_value) + + + + # test access operations (read and/or write) to register: + # msk_top_regs.LPF_Config_0 + with self.subTest(msg='register: msk_top_regs.LPF_Config_0'): + sim_register = self.sim.register_by_full_name('msk_top_regs.LPF_Config_0') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.LPF_Config_0.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.LPF_Config_0.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.LPF_Config_0.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + # register write checks + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.LPF_Config_0.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.LPF_Config_0.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + register_write_callback.assert_called_once_with(value=random_value) + register_read_callback.assert_not_called() + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.LPF_Config_0.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + self.assertEqual(await self.dut.LPF_Config_0.read(), random_value) + + + + # test access operations (read and/or write) to register: + # msk_top_regs.LPF_Config_1 + with self.subTest(msg='register: msk_top_regs.LPF_Config_1'): + sim_register = self.sim.register_by_full_name('msk_top_regs.LPF_Config_1') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.LPF_Config_1.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.LPF_Config_1.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.LPF_Config_1.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + # register write checks + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.LPF_Config_1.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.LPF_Config_1.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + register_write_callback.assert_called_once_with(value=random_value) + register_read_callback.assert_not_called() + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.LPF_Config_1.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + self.assertEqual(await self.dut.LPF_Config_1.read(), random_value) + + + + # test access operations (read and/or write) to register: + # msk_top_regs.Tx_Data_Width + with self.subTest(msg='register: msk_top_regs.Tx_Data_Width'): + sim_register = self.sim.register_by_full_name('msk_top_regs.Tx_Data_Width') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.Tx_Data_Width.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.Tx_Data_Width.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.Tx_Data_Width.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + # register write checks + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.Tx_Data_Width.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.Tx_Data_Width.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + register_write_callback.assert_called_once_with(value=random_value) + register_read_callback.assert_not_called() + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.Tx_Data_Width.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + self.assertEqual(await self.dut.Tx_Data_Width.read(), random_value) + + + + # test access operations (read and/or write) to register: + # msk_top_regs.Rx_Data_Width + with self.subTest(msg='register: msk_top_regs.Rx_Data_Width'): + sim_register = self.sim.register_by_full_name('msk_top_regs.Rx_Data_Width') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.Rx_Data_Width.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.Rx_Data_Width.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.Rx_Data_Width.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + # register write checks + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.Rx_Data_Width.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.Rx_Data_Width.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + register_write_callback.assert_called_once_with(value=random_value) + register_read_callback.assert_not_called() + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.Rx_Data_Width.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + self.assertEqual(await self.dut.Rx_Data_Width.read(), random_value) + + + + # test access operations (read and/or write) to register: + # msk_top_regs.PRBS_Control + with self.subTest(msg='register: msk_top_regs.PRBS_Control'): + sim_register = self.sim.register_by_full_name('msk_top_regs.PRBS_Control') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.PRBS_Control.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.PRBS_Control.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.PRBS_Control.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + # register write checks + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.PRBS_Control.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.PRBS_Control.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + register_write_callback.assert_called_once_with(value=random_value) + register_read_callback.assert_not_called() + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.PRBS_Control.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + self.assertEqual(await self.dut.PRBS_Control.read(), random_value) + + + + # test access operations (read and/or write) to register: + # msk_top_regs.PRBS_Initial_State + with self.subTest(msg='register: msk_top_regs.PRBS_Initial_State'): + sim_register = self.sim.register_by_full_name('msk_top_regs.PRBS_Initial_State') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.PRBS_Initial_State.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.PRBS_Initial_State.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.PRBS_Initial_State.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + # register write checks + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.PRBS_Initial_State.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.PRBS_Initial_State.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + register_write_callback.assert_called_once_with(value=random_value) + register_read_callback.assert_not_called() + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.PRBS_Initial_State.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + self.assertEqual(await self.dut.PRBS_Initial_State.read(), random_value) + + + + # test access operations (read and/or write) to register: + # msk_top_regs.PRBS_Polynomial + with self.subTest(msg='register: msk_top_regs.PRBS_Polynomial'): + sim_register = self.sim.register_by_full_name('msk_top_regs.PRBS_Polynomial') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.PRBS_Polynomial.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.PRBS_Polynomial.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.PRBS_Polynomial.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + # register write checks + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.PRBS_Polynomial.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.PRBS_Polynomial.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + register_write_callback.assert_called_once_with(value=random_value) + register_read_callback.assert_not_called() + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.PRBS_Polynomial.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + self.assertEqual(await self.dut.PRBS_Polynomial.read(), random_value) + + + + # test access operations (read and/or write) to register: + # msk_top_regs.PRBS_Error_Mask + with self.subTest(msg='register: msk_top_regs.PRBS_Error_Mask'): + sim_register = self.sim.register_by_full_name('msk_top_regs.PRBS_Error_Mask') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.PRBS_Error_Mask.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.PRBS_Error_Mask.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.PRBS_Error_Mask.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + # register write checks + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.PRBS_Error_Mask.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.PRBS_Error_Mask.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + register_write_callback.assert_called_once_with(value=random_value) + register_read_callback.assert_not_called() + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.PRBS_Error_Mask.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + self.assertEqual(await self.dut.PRBS_Error_Mask.read(), random_value) + + + + # test access operations (read and/or write) to register: + # msk_top_regs.PRBS_Bit_Count + with self.subTest(msg='register: msk_top_regs.PRBS_Bit_Count'): + sim_register = self.sim.register_by_full_name('msk_top_regs.PRBS_Bit_Count') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.PRBS_Bit_Count.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.PRBS_Bit_Count.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.PRBS_Bit_Count.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + # register write checks + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.PRBS_Bit_Count.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.PRBS_Bit_Count.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + register_write_callback.assert_called_once_with(value=random_value) + register_read_callback.assert_not_called() + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.PRBS_Bit_Count.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + self.assertEqual(await self.dut.PRBS_Bit_Count.read(), random_value) + + + + # test access operations (read and/or write) to register: + # msk_top_regs.PRBS_Error_Count + with self.subTest(msg='register: msk_top_regs.PRBS_Error_Count'): + sim_register = self.sim.register_by_full_name('msk_top_regs.PRBS_Error_Count') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.PRBS_Error_Count.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.PRBS_Error_Count.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.PRBS_Error_Count.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + # register write checks + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.PRBS_Error_Count.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.PRBS_Error_Count.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + register_write_callback.assert_called_once_with(value=random_value) + register_read_callback.assert_not_called() + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.PRBS_Error_Count.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + self.assertEqual(await self.dut.PRBS_Error_Count.read(), random_value) + + + + # test access operations (read and/or write) to register: + # msk_top_regs.LPF_Accum_F1 + with self.subTest(msg='register: msk_top_regs.LPF_Accum_F1'): + sim_register = self.sim.register_by_full_name('msk_top_regs.LPF_Accum_F1') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.LPF_Accum_F1.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.LPF_Accum_F1.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.LPF_Accum_F1.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + # register write checks + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.LPF_Accum_F1.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.LPF_Accum_F1.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + register_write_callback.assert_called_once_with(value=random_value) + register_read_callback.assert_not_called() + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.LPF_Accum_F1.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + self.assertEqual(await self.dut.LPF_Accum_F1.read(), random_value) + + + + # test access operations (read and/or write) to register: + # msk_top_regs.LPF_Accum_F2 + with self.subTest(msg='register: msk_top_regs.LPF_Accum_F2'): + sim_register = self.sim.register_by_full_name('msk_top_regs.LPF_Accum_F2') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.LPF_Accum_F2.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.LPF_Accum_F2.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.LPF_Accum_F2.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + # register write checks + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.LPF_Accum_F2.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.LPF_Accum_F2.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + register_write_callback.assert_called_once_with(value=random_value) + register_read_callback.assert_not_called() + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.LPF_Accum_F2.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + self.assertEqual(await self.dut.LPF_Accum_F2.read(), random_value) + + + + # test access operations (read and/or write) to register: + # msk_top_regs.axis_xfer_count + with self.subTest(msg='register: msk_top_regs.axis_xfer_count'): + sim_register = self.sim.register_by_full_name('msk_top_regs.axis_xfer_count') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.axis_xfer_count.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.axis_xfer_count.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.axis_xfer_count.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + # register write checks + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.axis_xfer_count.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.axis_xfer_count.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + register_write_callback.assert_called_once_with(value=random_value) + register_read_callback.assert_not_called() + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.axis_xfer_count.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + self.assertEqual(await self.dut.axis_xfer_count.read(), random_value) + + + + # test access operations (read and/or write) to register: + # msk_top_regs.Rx_Sample_Discard + with self.subTest(msg='register: msk_top_regs.Rx_Sample_Discard'): + sim_register = self.sim.register_by_full_name('msk_top_regs.Rx_Sample_Discard') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.Rx_Sample_Discard.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.Rx_Sample_Discard.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.Rx_Sample_Discard.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + # register write checks + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.Rx_Sample_Discard.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.Rx_Sample_Discard.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + register_write_callback.assert_called_once_with(value=random_value) + register_read_callback.assert_not_called() + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.Rx_Sample_Discard.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + self.assertEqual(await self.dut.Rx_Sample_Discard.read(), random_value) + + + + # test access operations (read and/or write) to register: + # msk_top_regs.LPF_Config_2 + with self.subTest(msg='register: msk_top_regs.LPF_Config_2'): + sim_register = self.sim.register_by_full_name('msk_top_regs.LPF_Config_2') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.LPF_Config_2.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.LPF_Config_2.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.LPF_Config_2.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + # register write checks + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.LPF_Config_2.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.LPF_Config_2.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + register_write_callback.assert_called_once_with(value=random_value) + register_read_callback.assert_not_called() + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.LPF_Config_2.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + self.assertEqual(await self.dut.LPF_Config_2.read(), random_value) + + + + # test access operations (read and/or write) to register: + # msk_top_regs.f1_nco_adjust + with self.subTest(msg='register: msk_top_regs.f1_nco_adjust'): + sim_register = self.sim.register_by_full_name('msk_top_regs.f1_nco_adjust') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.f1_nco_adjust.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.f1_nco_adjust.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.f1_nco_adjust.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + # register write checks + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.f1_nco_adjust.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.f1_nco_adjust.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + register_write_callback.assert_called_once_with(value=random_value) + register_read_callback.assert_not_called() + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.f1_nco_adjust.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + self.assertEqual(await self.dut.f1_nco_adjust.read(), random_value) + + + + # test access operations (read and/or write) to register: + # msk_top_regs.f2_nco_adjust + with self.subTest(msg='register: msk_top_regs.f2_nco_adjust'): + sim_register = self.sim.register_by_full_name('msk_top_regs.f2_nco_adjust') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.f2_nco_adjust.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.f2_nco_adjust.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.f2_nco_adjust.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + # register write checks + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.f2_nco_adjust.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.f2_nco_adjust.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + register_write_callback.assert_called_once_with(value=random_value) + register_read_callback.assert_not_called() + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.f2_nco_adjust.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + self.assertEqual(await self.dut.f2_nco_adjust.read(), random_value) + + + + # test access operations (read and/or write) to register: + # msk_top_regs.f1_error + with self.subTest(msg='register: msk_top_regs.f1_error'): + sim_register = self.sim.register_by_full_name('msk_top_regs.f1_error') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.f1_error.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.f1_error.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.f1_error.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + # register write checks + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.f1_error.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.f1_error.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + register_write_callback.assert_called_once_with(value=random_value) + register_read_callback.assert_not_called() + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.f1_error.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + self.assertEqual(await self.dut.f1_error.read(), random_value) + + + + # test access operations (read and/or write) to register: + # msk_top_regs.f2_error + with self.subTest(msg='register: msk_top_regs.f2_error'): + sim_register = self.sim.register_by_full_name('msk_top_regs.f2_error') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.f2_error.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.f2_error.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.f2_error.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + # register write checks + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.f2_error.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.f2_error.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + register_write_callback.assert_called_once_with(value=random_value) + register_read_callback.assert_not_called() + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.f2_error.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + self.assertEqual(await self.dut.f2_error.read(), random_value) + + + + # test access operations (read and/or write) to register: + # msk_top_regs.Tx_Sync_Ctrl + with self.subTest(msg='register: msk_top_regs.Tx_Sync_Ctrl'): + sim_register = self.sim.register_by_full_name('msk_top_regs.Tx_Sync_Ctrl') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.Tx_Sync_Ctrl.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.Tx_Sync_Ctrl.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.Tx_Sync_Ctrl.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + # register write checks + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.Tx_Sync_Ctrl.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.Tx_Sync_Ctrl.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + register_write_callback.assert_called_once_with(value=random_value) + register_read_callback.assert_not_called() + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.Tx_Sync_Ctrl.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + self.assertEqual(await self.dut.Tx_Sync_Ctrl.read(), random_value) + + + + # test access operations (read and/or write) to register: + # msk_top_regs.Tx_Sync_Cnt + with self.subTest(msg='register: msk_top_regs.Tx_Sync_Cnt'): + sim_register = self.sim.register_by_full_name('msk_top_regs.Tx_Sync_Cnt') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.Tx_Sync_Cnt.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.Tx_Sync_Cnt.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.Tx_Sync_Cnt.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + # register write checks + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.Tx_Sync_Cnt.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.Tx_Sync_Cnt.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + register_write_callback.assert_called_once_with(value=random_value) + register_read_callback.assert_not_called() + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.Tx_Sync_Cnt.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + self.assertEqual(await self.dut.Tx_Sync_Cnt.read(), random_value) + + + + # test access operations (read and/or write) to register: + # msk_top_regs.lowpass_ema_alpha1 + with self.subTest(msg='register: msk_top_regs.lowpass_ema_alpha1'): + sim_register = self.sim.register_by_full_name('msk_top_regs.lowpass_ema_alpha1') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.lowpass_ema_alpha1.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.lowpass_ema_alpha1.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.lowpass_ema_alpha1.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + # register write checks + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.lowpass_ema_alpha1.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.lowpass_ema_alpha1.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + register_write_callback.assert_called_once_with(value=random_value) + register_read_callback.assert_not_called() + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.lowpass_ema_alpha1.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + self.assertEqual(await self.dut.lowpass_ema_alpha1.read(), random_value) + + + + # test access operations (read and/or write) to register: + # msk_top_regs.lowpass_ema_alpha2 + with self.subTest(msg='register: msk_top_regs.lowpass_ema_alpha2'): + sim_register = self.sim.register_by_full_name('msk_top_regs.lowpass_ema_alpha2') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.lowpass_ema_alpha2.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.lowpass_ema_alpha2.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.lowpass_ema_alpha2.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + # register write checks + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.lowpass_ema_alpha2.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.lowpass_ema_alpha2.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + register_write_callback.assert_called_once_with(value=random_value) + register_read_callback.assert_not_called() + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.lowpass_ema_alpha2.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + self.assertEqual(await self.dut.lowpass_ema_alpha2.read(), random_value) + + + + # test access operations (read and/or write) to register: + # msk_top_regs.rx_power + with self.subTest(msg='register: msk_top_regs.rx_power'): + sim_register = self.sim.register_by_full_name('msk_top_regs.rx_power') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.rx_power.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.rx_power.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.rx_power.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + # register write checks + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.rx_power.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.rx_power.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + register_write_callback.assert_called_once_with(value=random_value) + register_read_callback.assert_not_called() + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.rx_power.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + self.assertEqual(await self.dut.rx_power.read(), random_value) + + + + # test access operations (read and/or write) to register: + # msk_top_regs.tx_async_fifo_rd_wr_ptr + with self.subTest(msg='register: msk_top_regs.tx_async_fifo_rd_wr_ptr'): + sim_register = self.sim.register_by_full_name('msk_top_regs.tx_async_fifo_rd_wr_ptr') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.tx_async_fifo_rd_wr_ptr.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.tx_async_fifo_rd_wr_ptr.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.tx_async_fifo_rd_wr_ptr.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + # register write checks + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.tx_async_fifo_rd_wr_ptr.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.tx_async_fifo_rd_wr_ptr.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + register_write_callback.assert_called_once_with(value=random_value) + register_read_callback.assert_not_called() + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.tx_async_fifo_rd_wr_ptr.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + self.assertEqual(await self.dut.tx_async_fifo_rd_wr_ptr.read(), random_value) + + + + # test access operations (read and/or write) to register: + # msk_top_regs.rx_async_fifo_rd_wr_ptr + with self.subTest(msg='register: msk_top_regs.rx_async_fifo_rd_wr_ptr'): + sim_register = self.sim.register_by_full_name('msk_top_regs.rx_async_fifo_rd_wr_ptr') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.rx_async_fifo_rd_wr_ptr.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.rx_async_fifo_rd_wr_ptr.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.rx_async_fifo_rd_wr_ptr.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + # register write checks + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.rx_async_fifo_rd_wr_ptr.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.rx_async_fifo_rd_wr_ptr.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + register_write_callback.assert_called_once_with(value=random_value) + register_read_callback.assert_not_called() + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.rx_async_fifo_rd_wr_ptr.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + self.assertEqual(await self.dut.rx_async_fifo_rd_wr_ptr.read(), random_value) + + + + # test access operations (read and/or write) to register: + # msk_top_regs.rx_frame_sync_status + with self.subTest(msg='register: msk_top_regs.rx_frame_sync_status'): + sim_register = self.sim.register_by_full_name('msk_top_regs.rx_frame_sync_status') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + register_read_callback = Mock() + register_write_callback = Mock() + + # register read checks + # update the value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.rx_frame_sync_status.read(), random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = random_value + self.assertEqual(await self.dut.rx_frame_sync_status.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.value = random_value + sim_register.read_callback = None + sim_register.write_callback = None + self.assertEqual(await self.dut.rx_frame_sync_status.read(), random_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + + + + # register write checks + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.rx_frame_sync_status.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + # up to now the callback should not have been called + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.rx_frame_sync_status.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + register_write_callback.assert_called_once_with(value=random_value) + register_read_callback.assert_not_called() + register_write_callback.reset_mock() + register_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + await self.dut.rx_frame_sync_status.write(random_value) # type: ignore[union-attr] + self.assertEqual(sim_register.value, random_value) + self.assertEqual(await self.dut.rx_frame_sync_status.read(), random_value) + + + + + + async def test_field_read_and_write(self) -> None: + """ + Walk the register map and check every field can be read and written to correctly + """ + random_field_value: Union[int, SystemRDLEnum] + # test access operations (read and/or write) to register: + # msk_top_regs.Hash_ID_Low.hash_id_lo + with self.subTest(msg='field: msk_top_regs.Hash_ID_Low.hash_id_lo'): + sim_register = self.sim.register_by_full_name('msk_top_regs.Hash_ID_Low') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.Hash_ID_Low.hash_id_lo') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.Hash_ID_Low.hash_id_lo.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0x0) | (random_field_value << 0)) + + self.assertEqual(await self.dut.Hash_ID_Low.hash_id_lo.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.Hash_ID_Low.hash_id_lo.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.Hash_ID_Low.hash_id_lo.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + + + # test access operations (read and/or write) to register: + # msk_top_regs.Hash_ID_High.hash_id_hi + with self.subTest(msg='field: msk_top_regs.Hash_ID_High.hash_id_hi'): + sim_register = self.sim.register_by_full_name('msk_top_regs.Hash_ID_High') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.Hash_ID_High.hash_id_hi') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.Hash_ID_High.hash_id_hi.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0x0) | (random_field_value << 0)) + + self.assertEqual(await self.dut.Hash_ID_High.hash_id_hi.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.Hash_ID_High.hash_id_hi.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.Hash_ID_High.hash_id_hi.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + + + # test access operations (read and/or write) to register: + # msk_top_regs.MSK_Init.txrxinit + with self.subTest(msg='field: msk_top_regs.MSK_Init.txrxinit'): + sim_register = self.sim.register_by_full_name('msk_top_regs.MSK_Init') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.MSK_Init.txrxinit') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x1) >> 0 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.MSK_Init.txrxinit.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0x1+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0xFFFFFFFE) | (random_field_value << 0)) + + self.assertEqual(await self.dut.MSK_Init.txrxinit.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x1) >> 0 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.MSK_Init.txrxinit.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x1) >> 0 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.MSK_Init.txrxinit.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.MSK_Init.txrxinit.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFE) | (0x1 & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.MSK_Init.txrxinit.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFE) | (0x1 & (random_field_value << 0))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0xFFFFFFFE) | (0x1 & (random_field_value << 0))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.MSK_Init.txrxinit.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFE) | (0x1 & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.MSK_Init.txinit + with self.subTest(msg='field: msk_top_regs.MSK_Init.txinit'): + sim_register = self.sim.register_by_full_name('msk_top_regs.MSK_Init') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.MSK_Init.txinit') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x2) >> 1 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.MSK_Init.txinit.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0x1+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0xFFFFFFFD) | (random_field_value << 1)) + + self.assertEqual(await self.dut.MSK_Init.txinit.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x2) >> 1 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.MSK_Init.txinit.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x2) >> 1 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.MSK_Init.txinit.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.MSK_Init.txinit.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFD) | (0x2 & (random_field_value << 1))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.MSK_Init.txinit.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFD) | (0x2 & (random_field_value << 1))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0xFFFFFFFD) | (0x2 & (random_field_value << 1))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.MSK_Init.txinit.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFD) | (0x2 & (random_field_value << 1))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.MSK_Init.rxinit + with self.subTest(msg='field: msk_top_regs.MSK_Init.rxinit'): + sim_register = self.sim.register_by_full_name('msk_top_regs.MSK_Init') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.MSK_Init.rxinit') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x4) >> 2 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.MSK_Init.rxinit.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0x1+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0xFFFFFFFB) | (random_field_value << 2)) + + self.assertEqual(await self.dut.MSK_Init.rxinit.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x4) >> 2 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.MSK_Init.rxinit.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x4) >> 2 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.MSK_Init.rxinit.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.MSK_Init.rxinit.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFB) | (0x4 & (random_field_value << 2))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.MSK_Init.rxinit.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFB) | (0x4 & (random_field_value << 2))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0xFFFFFFFB) | (0x4 & (random_field_value << 2))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.MSK_Init.rxinit.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFB) | (0x4 & (random_field_value << 2))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.MSK_Control.ptt + with self.subTest(msg='field: msk_top_regs.MSK_Control.ptt'): + sim_register = self.sim.register_by_full_name('msk_top_regs.MSK_Control') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.MSK_Control.ptt') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x1) >> 0 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.MSK_Control.ptt.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0x1+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0xFFFFFFFE) | (random_field_value << 0)) + + self.assertEqual(await self.dut.MSK_Control.ptt.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x1) >> 0 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.MSK_Control.ptt.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x1) >> 0 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.MSK_Control.ptt.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.MSK_Control.ptt.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFE) | (0x1 & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.MSK_Control.ptt.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFE) | (0x1 & (random_field_value << 0))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0xFFFFFFFE) | (0x1 & (random_field_value << 0))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.MSK_Control.ptt.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFE) | (0x1 & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.MSK_Control.loopback_ena + with self.subTest(msg='field: msk_top_regs.MSK_Control.loopback_ena'): + sim_register = self.sim.register_by_full_name('msk_top_regs.MSK_Control') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.MSK_Control.loopback_ena') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x2) >> 1 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.MSK_Control.loopback_ena.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0x1+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0xFFFFFFFD) | (random_field_value << 1)) + + self.assertEqual(await self.dut.MSK_Control.loopback_ena.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x2) >> 1 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.MSK_Control.loopback_ena.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x2) >> 1 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.MSK_Control.loopback_ena.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.MSK_Control.loopback_ena.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFD) | (0x2 & (random_field_value << 1))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.MSK_Control.loopback_ena.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFD) | (0x2 & (random_field_value << 1))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0xFFFFFFFD) | (0x2 & (random_field_value << 1))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.MSK_Control.loopback_ena.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFD) | (0x2 & (random_field_value << 1))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.MSK_Control.rx_invert + with self.subTest(msg='field: msk_top_regs.MSK_Control.rx_invert'): + sim_register = self.sim.register_by_full_name('msk_top_regs.MSK_Control') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.MSK_Control.rx_invert') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x4) >> 2 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.MSK_Control.rx_invert.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0x1+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0xFFFFFFFB) | (random_field_value << 2)) + + self.assertEqual(await self.dut.MSK_Control.rx_invert.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x4) >> 2 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.MSK_Control.rx_invert.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x4) >> 2 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.MSK_Control.rx_invert.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.MSK_Control.rx_invert.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFB) | (0x4 & (random_field_value << 2))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.MSK_Control.rx_invert.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFB) | (0x4 & (random_field_value << 2))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0xFFFFFFFB) | (0x4 & (random_field_value << 2))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.MSK_Control.rx_invert.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFB) | (0x4 & (random_field_value << 2))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.MSK_Control.clear_counts + with self.subTest(msg='field: msk_top_regs.MSK_Control.clear_counts'): + sim_register = self.sim.register_by_full_name('msk_top_regs.MSK_Control') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.MSK_Control.clear_counts') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x8) >> 3 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.MSK_Control.clear_counts.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0x1+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0xFFFFFFF7) | (random_field_value << 3)) + + self.assertEqual(await self.dut.MSK_Control.clear_counts.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x8) >> 3 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.MSK_Control.clear_counts.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x8) >> 3 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.MSK_Control.clear_counts.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.MSK_Control.clear_counts.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFF7) | (0x8 & (random_field_value << 3))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.MSK_Control.clear_counts.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFF7) | (0x8 & (random_field_value << 3))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0xFFFFFFF7) | (0x8 & (random_field_value << 3))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.MSK_Control.clear_counts.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFF7) | (0x8 & (random_field_value << 3))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.MSK_Control.diff_encoder_loopback + with self.subTest(msg='field: msk_top_regs.MSK_Control.diff_encoder_loopback'): + sim_register = self.sim.register_by_full_name('msk_top_regs.MSK_Control') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.MSK_Control.diff_encoder_loopback') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x10) >> 4 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.MSK_Control.diff_encoder_loopback.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0x1+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0xFFFFFFEF) | (random_field_value << 4)) + + self.assertEqual(await self.dut.MSK_Control.diff_encoder_loopback.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x10) >> 4 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.MSK_Control.diff_encoder_loopback.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x10) >> 4 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.MSK_Control.diff_encoder_loopback.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.MSK_Control.diff_encoder_loopback.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFEF) | (0x10 & (random_field_value << 4))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.MSK_Control.diff_encoder_loopback.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFEF) | (0x10 & (random_field_value << 4))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0xFFFFFFEF) | (0x10 & (random_field_value << 4))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.MSK_Control.diff_encoder_loopback.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFEF) | (0x10 & (random_field_value << 4))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.MSK_Status.demod_sync_lock + with self.subTest(msg='field: msk_top_regs.MSK_Status.demod_sync_lock'): + sim_register = self.sim.register_by_full_name('msk_top_regs.MSK_Status') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.MSK_Status.demod_sync_lock') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x1) >> 0 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.MSK_Status.demod_sync_lock.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0x1+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0xFFFFFFFE) | (random_field_value << 0)) + + self.assertEqual(await self.dut.MSK_Status.demod_sync_lock.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x1) >> 0 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.MSK_Status.demod_sync_lock.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x1) >> 0 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.MSK_Status.demod_sync_lock.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + + + # test access operations (read and/or write) to register: + # msk_top_regs.MSK_Status.tx_enable + with self.subTest(msg='field: msk_top_regs.MSK_Status.tx_enable'): + sim_register = self.sim.register_by_full_name('msk_top_regs.MSK_Status') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.MSK_Status.tx_enable') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x2) >> 1 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.MSK_Status.tx_enable.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0x1+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0xFFFFFFFD) | (random_field_value << 1)) + + self.assertEqual(await self.dut.MSK_Status.tx_enable.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x2) >> 1 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.MSK_Status.tx_enable.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x2) >> 1 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.MSK_Status.tx_enable.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + + + # test access operations (read and/or write) to register: + # msk_top_regs.MSK_Status.rx_enable + with self.subTest(msg='field: msk_top_regs.MSK_Status.rx_enable'): + sim_register = self.sim.register_by_full_name('msk_top_regs.MSK_Status') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.MSK_Status.rx_enable') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x4) >> 2 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.MSK_Status.rx_enable.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0x1+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0xFFFFFFFB) | (random_field_value << 2)) + + self.assertEqual(await self.dut.MSK_Status.rx_enable.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x4) >> 2 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.MSK_Status.rx_enable.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x4) >> 2 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.MSK_Status.rx_enable.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + + + # test access operations (read and/or write) to register: + # msk_top_regs.MSK_Status.tx_axis_valid + with self.subTest(msg='field: msk_top_regs.MSK_Status.tx_axis_valid'): + sim_register = self.sim.register_by_full_name('msk_top_regs.MSK_Status') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.MSK_Status.tx_axis_valid') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x8) >> 3 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.MSK_Status.tx_axis_valid.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0x1+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0xFFFFFFF7) | (random_field_value << 3)) + + self.assertEqual(await self.dut.MSK_Status.tx_axis_valid.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x8) >> 3 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.MSK_Status.tx_axis_valid.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x8) >> 3 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.MSK_Status.tx_axis_valid.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + + + # test access operations (read and/or write) to register: + # msk_top_regs.Tx_Bit_Count.data + with self.subTest(msg='field: msk_top_regs.Tx_Bit_Count.data'): + sim_register = self.sim.register_by_full_name('msk_top_regs.Tx_Bit_Count') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.Tx_Bit_Count.data') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.Tx_Bit_Count.data.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0x0) | (random_field_value << 0)) + + self.assertEqual(await self.dut.Tx_Bit_Count.data.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.Tx_Bit_Count.data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.Tx_Bit_Count.data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.Tx_Bit_Count.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.Tx_Bit_Count.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.Tx_Bit_Count.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.Tx_Enable_Count.data + with self.subTest(msg='field: msk_top_regs.Tx_Enable_Count.data'): + sim_register = self.sim.register_by_full_name('msk_top_regs.Tx_Enable_Count') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.Tx_Enable_Count.data') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.Tx_Enable_Count.data.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0x0) | (random_field_value << 0)) + + self.assertEqual(await self.dut.Tx_Enable_Count.data.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.Tx_Enable_Count.data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.Tx_Enable_Count.data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.Tx_Enable_Count.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.Tx_Enable_Count.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.Tx_Enable_Count.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.Fb_FreqWord.config_data + with self.subTest(msg='field: msk_top_regs.Fb_FreqWord.config_data'): + sim_register = self.sim.register_by_full_name('msk_top_regs.Fb_FreqWord') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.Fb_FreqWord.config_data') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.Fb_FreqWord.config_data.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0x0) | (random_field_value << 0)) + + self.assertEqual(await self.dut.Fb_FreqWord.config_data.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.Fb_FreqWord.config_data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.Fb_FreqWord.config_data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.Fb_FreqWord.config_data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.Fb_FreqWord.config_data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.Fb_FreqWord.config_data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.TX_F1_FreqWord.config_data + with self.subTest(msg='field: msk_top_regs.TX_F1_FreqWord.config_data'): + sim_register = self.sim.register_by_full_name('msk_top_regs.TX_F1_FreqWord') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.TX_F1_FreqWord.config_data') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.TX_F1_FreqWord.config_data.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0x0) | (random_field_value << 0)) + + self.assertEqual(await self.dut.TX_F1_FreqWord.config_data.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.TX_F1_FreqWord.config_data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.TX_F1_FreqWord.config_data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.TX_F1_FreqWord.config_data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.TX_F1_FreqWord.config_data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.TX_F1_FreqWord.config_data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.TX_F2_FreqWord.config_data + with self.subTest(msg='field: msk_top_regs.TX_F2_FreqWord.config_data'): + sim_register = self.sim.register_by_full_name('msk_top_regs.TX_F2_FreqWord') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.TX_F2_FreqWord.config_data') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.TX_F2_FreqWord.config_data.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0x0) | (random_field_value << 0)) + + self.assertEqual(await self.dut.TX_F2_FreqWord.config_data.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.TX_F2_FreqWord.config_data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.TX_F2_FreqWord.config_data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.TX_F2_FreqWord.config_data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.TX_F2_FreqWord.config_data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.TX_F2_FreqWord.config_data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.RX_F1_FreqWord.config_data + with self.subTest(msg='field: msk_top_regs.RX_F1_FreqWord.config_data'): + sim_register = self.sim.register_by_full_name('msk_top_regs.RX_F1_FreqWord') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.RX_F1_FreqWord.config_data') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.RX_F1_FreqWord.config_data.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0x0) | (random_field_value << 0)) + + self.assertEqual(await self.dut.RX_F1_FreqWord.config_data.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.RX_F1_FreqWord.config_data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.RX_F1_FreqWord.config_data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.RX_F1_FreqWord.config_data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.RX_F1_FreqWord.config_data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.RX_F1_FreqWord.config_data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.RX_F2_FreqWord.config_data + with self.subTest(msg='field: msk_top_regs.RX_F2_FreqWord.config_data'): + sim_register = self.sim.register_by_full_name('msk_top_regs.RX_F2_FreqWord') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.RX_F2_FreqWord.config_data') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.RX_F2_FreqWord.config_data.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0x0) | (random_field_value << 0)) + + self.assertEqual(await self.dut.RX_F2_FreqWord.config_data.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.RX_F2_FreqWord.config_data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.RX_F2_FreqWord.config_data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.RX_F2_FreqWord.config_data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.RX_F2_FreqWord.config_data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.RX_F2_FreqWord.config_data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.LPF_Config_0.lpf_freeze + with self.subTest(msg='field: msk_top_regs.LPF_Config_0.lpf_freeze'): + sim_register = self.sim.register_by_full_name('msk_top_regs.LPF_Config_0') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.LPF_Config_0.lpf_freeze') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x1) >> 0 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.LPF_Config_0.lpf_freeze.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0x1+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0xFFFFFFFE) | (random_field_value << 0)) + + self.assertEqual(await self.dut.LPF_Config_0.lpf_freeze.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x1) >> 0 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.LPF_Config_0.lpf_freeze.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x1) >> 0 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.LPF_Config_0.lpf_freeze.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.LPF_Config_0.lpf_freeze.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFE) | (0x1 & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.LPF_Config_0.lpf_freeze.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFE) | (0x1 & (random_field_value << 0))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0xFFFFFFFE) | (0x1 & (random_field_value << 0))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.LPF_Config_0.lpf_freeze.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFE) | (0x1 & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.LPF_Config_0.lpf_zero + with self.subTest(msg='field: msk_top_regs.LPF_Config_0.lpf_zero'): + sim_register = self.sim.register_by_full_name('msk_top_regs.LPF_Config_0') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.LPF_Config_0.lpf_zero') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x2) >> 1 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.LPF_Config_0.lpf_zero.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0x1+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0xFFFFFFFD) | (random_field_value << 1)) + + self.assertEqual(await self.dut.LPF_Config_0.lpf_zero.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x2) >> 1 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.LPF_Config_0.lpf_zero.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x2) >> 1 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.LPF_Config_0.lpf_zero.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.LPF_Config_0.lpf_zero.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFD) | (0x2 & (random_field_value << 1))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.LPF_Config_0.lpf_zero.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFD) | (0x2 & (random_field_value << 1))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0xFFFFFFFD) | (0x2 & (random_field_value << 1))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.LPF_Config_0.lpf_zero.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFD) | (0x2 & (random_field_value << 1))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.LPF_Config_0.prbs_reserved + with self.subTest(msg='field: msk_top_regs.LPF_Config_0.prbs_reserved'): + sim_register = self.sim.register_by_full_name('msk_top_regs.LPF_Config_0') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.LPF_Config_0.prbs_reserved') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFC) >> 2 + + + sim_register.value = random_value + self.assertEqual(await self.dut.LPF_Config_0.prbs_reserved.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0x3F+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0xFFFFFF03) | (random_field_value << 2)) + + self.assertEqual(await self.dut.LPF_Config_0.prbs_reserved.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFC) >> 2 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.LPF_Config_0.prbs_reserved.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFC) >> 2 + + + sim_register.value = random_value + self.assertEqual(await self.dut.LPF_Config_0.prbs_reserved.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0x3F+1) + + await self.dut.LPF_Config_0.prbs_reserved.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFF03) | (0xFC & (random_field_value << 2))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0x3F+1) + + await self.dut.LPF_Config_0.prbs_reserved.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFF03) | (0xFC & (random_field_value << 2))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0xFFFFFF03) | (0xFC & (random_field_value << 2))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0x3F+1) + + await self.dut.LPF_Config_0.prbs_reserved.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFF03) | (0xFC & (random_field_value << 2))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.LPF_Config_0.lpf_alpha + with self.subTest(msg='field: msk_top_regs.LPF_Config_0.lpf_alpha'): + sim_register = self.sim.register_by_full_name('msk_top_regs.LPF_Config_0') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.LPF_Config_0.lpf_alpha') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFF00) >> 8 + + + sim_register.value = random_value + self.assertEqual(await self.dut.LPF_Config_0.lpf_alpha.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0xFFFFFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0xFF) | (random_field_value << 8)) + + self.assertEqual(await self.dut.LPF_Config_0.lpf_alpha.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFF00) >> 8 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.LPF_Config_0.lpf_alpha.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFF00) >> 8 + + + sim_register.value = random_value + self.assertEqual(await self.dut.LPF_Config_0.lpf_alpha.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0xFFFFFF+1) + + await self.dut.LPF_Config_0.lpf_alpha.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFF) | (0xFFFFFF00 & (random_field_value << 8))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0xFFFFFF+1) + + await self.dut.LPF_Config_0.lpf_alpha.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFF) | (0xFFFFFF00 & (random_field_value << 8))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0xFF) | (0xFFFFFF00 & (random_field_value << 8))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0xFFFFFF+1) + + await self.dut.LPF_Config_0.lpf_alpha.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFF) | (0xFFFFFF00 & (random_field_value << 8))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.LPF_Config_1.i_gain + with self.subTest(msg='field: msk_top_regs.LPF_Config_1.i_gain'): + sim_register = self.sim.register_by_full_name('msk_top_regs.LPF_Config_1') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.LPF_Config_1.i_gain') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.LPF_Config_1.i_gain.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0xFFFFFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0xFF000000) | (random_field_value << 0)) + + self.assertEqual(await self.dut.LPF_Config_1.i_gain.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFF) >> 0 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.LPF_Config_1.i_gain.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.LPF_Config_1.i_gain.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0xFFFFFF+1) + + await self.dut.LPF_Config_1.i_gain.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFF000000) | (0xFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0xFFFFFF+1) + + await self.dut.LPF_Config_1.i_gain.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFF000000) | (0xFFFFFF & (random_field_value << 0))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0xFF000000) | (0xFFFFFF & (random_field_value << 0))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0xFFFFFF+1) + + await self.dut.LPF_Config_1.i_gain.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFF000000) | (0xFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.LPF_Config_1.i_shift + with self.subTest(msg='field: msk_top_regs.LPF_Config_1.i_shift'): + sim_register = self.sim.register_by_full_name('msk_top_regs.LPF_Config_1') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.LPF_Config_1.i_shift') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFF000000) >> 24 + + + sim_register.value = random_value + self.assertEqual(await self.dut.LPF_Config_1.i_shift.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0xFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0xFFFFFF) | (random_field_value << 24)) + + self.assertEqual(await self.dut.LPF_Config_1.i_shift.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFF000000) >> 24 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.LPF_Config_1.i_shift.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFF000000) >> 24 + + + sim_register.value = random_value + self.assertEqual(await self.dut.LPF_Config_1.i_shift.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0xFF+1) + + await self.dut.LPF_Config_1.i_shift.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFF) | (0xFF000000 & (random_field_value << 24))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0xFF+1) + + await self.dut.LPF_Config_1.i_shift.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFF) | (0xFF000000 & (random_field_value << 24))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0xFFFFFF) | (0xFF000000 & (random_field_value << 24))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0xFF+1) + + await self.dut.LPF_Config_1.i_shift.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFF) | (0xFF000000 & (random_field_value << 24))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.Tx_Data_Width.data_width + with self.subTest(msg='field: msk_top_regs.Tx_Data_Width.data_width'): + sim_register = self.sim.register_by_full_name('msk_top_regs.Tx_Data_Width') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.Tx_Data_Width.data_width') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.Tx_Data_Width.data_width.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0xFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0xFFFFFF00) | (random_field_value << 0)) + + self.assertEqual(await self.dut.Tx_Data_Width.data_width.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFF) >> 0 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.Tx_Data_Width.data_width.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.Tx_Data_Width.data_width.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0xFF+1) + + await self.dut.Tx_Data_Width.data_width.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFF00) | (0xFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0xFF+1) + + await self.dut.Tx_Data_Width.data_width.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFF00) | (0xFF & (random_field_value << 0))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0xFFFFFF00) | (0xFF & (random_field_value << 0))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0xFF+1) + + await self.dut.Tx_Data_Width.data_width.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFF00) | (0xFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.Rx_Data_Width.data_width + with self.subTest(msg='field: msk_top_regs.Rx_Data_Width.data_width'): + sim_register = self.sim.register_by_full_name('msk_top_regs.Rx_Data_Width') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.Rx_Data_Width.data_width') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.Rx_Data_Width.data_width.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0xFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0xFFFFFF00) | (random_field_value << 0)) + + self.assertEqual(await self.dut.Rx_Data_Width.data_width.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFF) >> 0 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.Rx_Data_Width.data_width.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.Rx_Data_Width.data_width.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0xFF+1) + + await self.dut.Rx_Data_Width.data_width.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFF00) | (0xFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0xFF+1) + + await self.dut.Rx_Data_Width.data_width.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFF00) | (0xFF & (random_field_value << 0))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0xFFFFFF00) | (0xFF & (random_field_value << 0))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0xFF+1) + + await self.dut.Rx_Data_Width.data_width.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFF00) | (0xFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.PRBS_Control.prbs_sel + with self.subTest(msg='field: msk_top_regs.PRBS_Control.prbs_sel'): + sim_register = self.sim.register_by_full_name('msk_top_regs.PRBS_Control') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.PRBS_Control.prbs_sel') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x1) >> 0 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.PRBS_Control.prbs_sel.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0x1+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0xFFFFFFFE) | (random_field_value << 0)) + + self.assertEqual(await self.dut.PRBS_Control.prbs_sel.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x1) >> 0 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.PRBS_Control.prbs_sel.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x1) >> 0 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.PRBS_Control.prbs_sel.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.PRBS_Control.prbs_sel.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFE) | (0x1 & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.PRBS_Control.prbs_sel.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFE) | (0x1 & (random_field_value << 0))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0xFFFFFFFE) | (0x1 & (random_field_value << 0))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.PRBS_Control.prbs_sel.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFE) | (0x1 & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.PRBS_Control.prbs_error_insert + with self.subTest(msg='field: msk_top_regs.PRBS_Control.prbs_error_insert'): + sim_register = self.sim.register_by_full_name('msk_top_regs.PRBS_Control') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.PRBS_Control.prbs_error_insert') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.PRBS_Control.prbs_error_insert.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFD) | (0x2 & (random_field_value << 1))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.PRBS_Control.prbs_error_insert.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFD) | (0x2 & (random_field_value << 1))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0xFFFFFFFD) | (0x2 & (random_field_value << 1))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.PRBS_Control.prbs_error_insert.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFD) | (0x2 & (random_field_value << 1))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.PRBS_Control.prbs_clear + with self.subTest(msg='field: msk_top_regs.PRBS_Control.prbs_clear'): + sim_register = self.sim.register_by_full_name('msk_top_regs.PRBS_Control') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.PRBS_Control.prbs_clear') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.PRBS_Control.prbs_clear.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFB) | (0x4 & (random_field_value << 2))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.PRBS_Control.prbs_clear.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFB) | (0x4 & (random_field_value << 2))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0xFFFFFFFB) | (0x4 & (random_field_value << 2))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.PRBS_Control.prbs_clear.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFB) | (0x4 & (random_field_value << 2))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.PRBS_Control.prbs_manual_sync + with self.subTest(msg='field: msk_top_regs.PRBS_Control.prbs_manual_sync'): + sim_register = self.sim.register_by_full_name('msk_top_regs.PRBS_Control') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.PRBS_Control.prbs_manual_sync') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.PRBS_Control.prbs_manual_sync.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFF7) | (0x8 & (random_field_value << 3))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.PRBS_Control.prbs_manual_sync.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFF7) | (0x8 & (random_field_value << 3))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0xFFFFFFF7) | (0x8 & (random_field_value << 3))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.PRBS_Control.prbs_manual_sync.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFF7) | (0x8 & (random_field_value << 3))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.PRBS_Control.prbs_reserved + with self.subTest(msg='field: msk_top_regs.PRBS_Control.prbs_reserved'): + sim_register = self.sim.register_by_full_name('msk_top_regs.PRBS_Control') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.PRBS_Control.prbs_reserved') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFF0) >> 4 + + + sim_register.value = random_value + self.assertEqual(await self.dut.PRBS_Control.prbs_reserved.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0xFFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0xFFFF000F) | (random_field_value << 4)) + + self.assertEqual(await self.dut.PRBS_Control.prbs_reserved.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFF0) >> 4 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.PRBS_Control.prbs_reserved.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFF0) >> 4 + + + sim_register.value = random_value + self.assertEqual(await self.dut.PRBS_Control.prbs_reserved.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0xFFF+1) + + await self.dut.PRBS_Control.prbs_reserved.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFF000F) | (0xFFF0 & (random_field_value << 4))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0xFFF+1) + + await self.dut.PRBS_Control.prbs_reserved.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFF000F) | (0xFFF0 & (random_field_value << 4))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0xFFFF000F) | (0xFFF0 & (random_field_value << 4))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0xFFF+1) + + await self.dut.PRBS_Control.prbs_reserved.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFF000F) | (0xFFF0 & (random_field_value << 4))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.PRBS_Control.prbs_sync_threshold + with self.subTest(msg='field: msk_top_regs.PRBS_Control.prbs_sync_threshold'): + sim_register = self.sim.register_by_full_name('msk_top_regs.PRBS_Control') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.PRBS_Control.prbs_sync_threshold') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFF0000) >> 16 + + + sim_register.value = random_value + self.assertEqual(await self.dut.PRBS_Control.prbs_sync_threshold.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0xFFFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0xFFFF) | (random_field_value << 16)) + + self.assertEqual(await self.dut.PRBS_Control.prbs_sync_threshold.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFF0000) >> 16 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.PRBS_Control.prbs_sync_threshold.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFF0000) >> 16 + + + sim_register.value = random_value + self.assertEqual(await self.dut.PRBS_Control.prbs_sync_threshold.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0xFFFF+1) + + await self.dut.PRBS_Control.prbs_sync_threshold.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFF) | (0xFFFF0000 & (random_field_value << 16))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0xFFFF+1) + + await self.dut.PRBS_Control.prbs_sync_threshold.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFF) | (0xFFFF0000 & (random_field_value << 16))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0xFFFF) | (0xFFFF0000 & (random_field_value << 16))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0xFFFF+1) + + await self.dut.PRBS_Control.prbs_sync_threshold.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFF) | (0xFFFF0000 & (random_field_value << 16))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.PRBS_Initial_State.config_data + with self.subTest(msg='field: msk_top_regs.PRBS_Initial_State.config_data'): + sim_register = self.sim.register_by_full_name('msk_top_regs.PRBS_Initial_State') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.PRBS_Initial_State.config_data') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.PRBS_Initial_State.config_data.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0x0) | (random_field_value << 0)) + + self.assertEqual(await self.dut.PRBS_Initial_State.config_data.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.PRBS_Initial_State.config_data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.PRBS_Initial_State.config_data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.PRBS_Initial_State.config_data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.PRBS_Initial_State.config_data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.PRBS_Initial_State.config_data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.PRBS_Polynomial.config_data + with self.subTest(msg='field: msk_top_regs.PRBS_Polynomial.config_data'): + sim_register = self.sim.register_by_full_name('msk_top_regs.PRBS_Polynomial') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.PRBS_Polynomial.config_data') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.PRBS_Polynomial.config_data.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0x0) | (random_field_value << 0)) + + self.assertEqual(await self.dut.PRBS_Polynomial.config_data.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.PRBS_Polynomial.config_data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.PRBS_Polynomial.config_data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.PRBS_Polynomial.config_data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.PRBS_Polynomial.config_data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.PRBS_Polynomial.config_data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.PRBS_Error_Mask.config_data + with self.subTest(msg='field: msk_top_regs.PRBS_Error_Mask.config_data'): + sim_register = self.sim.register_by_full_name('msk_top_regs.PRBS_Error_Mask') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.PRBS_Error_Mask.config_data') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.PRBS_Error_Mask.config_data.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0x0) | (random_field_value << 0)) + + self.assertEqual(await self.dut.PRBS_Error_Mask.config_data.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.PRBS_Error_Mask.config_data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.PRBS_Error_Mask.config_data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.PRBS_Error_Mask.config_data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.PRBS_Error_Mask.config_data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.PRBS_Error_Mask.config_data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.PRBS_Bit_Count.data + with self.subTest(msg='field: msk_top_regs.PRBS_Bit_Count.data'): + sim_register = self.sim.register_by_full_name('msk_top_regs.PRBS_Bit_Count') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.PRBS_Bit_Count.data') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.PRBS_Bit_Count.data.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0x0) | (random_field_value << 0)) + + self.assertEqual(await self.dut.PRBS_Bit_Count.data.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.PRBS_Bit_Count.data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.PRBS_Bit_Count.data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.PRBS_Bit_Count.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.PRBS_Bit_Count.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.PRBS_Bit_Count.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.PRBS_Error_Count.data + with self.subTest(msg='field: msk_top_regs.PRBS_Error_Count.data'): + sim_register = self.sim.register_by_full_name('msk_top_regs.PRBS_Error_Count') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.PRBS_Error_Count.data') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.PRBS_Error_Count.data.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0x0) | (random_field_value << 0)) + + self.assertEqual(await self.dut.PRBS_Error_Count.data.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.PRBS_Error_Count.data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.PRBS_Error_Count.data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.PRBS_Error_Count.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.PRBS_Error_Count.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.PRBS_Error_Count.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.LPF_Accum_F1.data + with self.subTest(msg='field: msk_top_regs.LPF_Accum_F1.data'): + sim_register = self.sim.register_by_full_name('msk_top_regs.LPF_Accum_F1') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.LPF_Accum_F1.data') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.LPF_Accum_F1.data.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0x0) | (random_field_value << 0)) + + self.assertEqual(await self.dut.LPF_Accum_F1.data.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.LPF_Accum_F1.data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.LPF_Accum_F1.data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.LPF_Accum_F1.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.LPF_Accum_F1.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.LPF_Accum_F1.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.LPF_Accum_F2.data + with self.subTest(msg='field: msk_top_regs.LPF_Accum_F2.data'): + sim_register = self.sim.register_by_full_name('msk_top_regs.LPF_Accum_F2') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.LPF_Accum_F2.data') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.LPF_Accum_F2.data.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0x0) | (random_field_value << 0)) + + self.assertEqual(await self.dut.LPF_Accum_F2.data.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.LPF_Accum_F2.data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.LPF_Accum_F2.data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.LPF_Accum_F2.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.LPF_Accum_F2.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.LPF_Accum_F2.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.axis_xfer_count.data + with self.subTest(msg='field: msk_top_regs.axis_xfer_count.data'): + sim_register = self.sim.register_by_full_name('msk_top_regs.axis_xfer_count') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.axis_xfer_count.data') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.axis_xfer_count.data.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0x0) | (random_field_value << 0)) + + self.assertEqual(await self.dut.axis_xfer_count.data.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.axis_xfer_count.data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.axis_xfer_count.data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.axis_xfer_count.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.axis_xfer_count.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.axis_xfer_count.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.Rx_Sample_Discard.rx_sample_discard + with self.subTest(msg='field: msk_top_regs.Rx_Sample_Discard.rx_sample_discard'): + sim_register = self.sim.register_by_full_name('msk_top_regs.Rx_Sample_Discard') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.Rx_Sample_Discard.rx_sample_discard') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.Rx_Sample_Discard.rx_sample_discard.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0xFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0xFFFFFF00) | (random_field_value << 0)) + + self.assertEqual(await self.dut.Rx_Sample_Discard.rx_sample_discard.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFF) >> 0 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.Rx_Sample_Discard.rx_sample_discard.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.Rx_Sample_Discard.rx_sample_discard.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0xFF+1) + + await self.dut.Rx_Sample_Discard.rx_sample_discard.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFF00) | (0xFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0xFF+1) + + await self.dut.Rx_Sample_Discard.rx_sample_discard.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFF00) | (0xFF & (random_field_value << 0))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0xFFFFFF00) | (0xFF & (random_field_value << 0))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0xFF+1) + + await self.dut.Rx_Sample_Discard.rx_sample_discard.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFF00) | (0xFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.Rx_Sample_Discard.rx_nco_discard + with self.subTest(msg='field: msk_top_regs.Rx_Sample_Discard.rx_nco_discard'): + sim_register = self.sim.register_by_full_name('msk_top_regs.Rx_Sample_Discard') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.Rx_Sample_Discard.rx_nco_discard') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFF00) >> 8 + + + sim_register.value = random_value + self.assertEqual(await self.dut.Rx_Sample_Discard.rx_nco_discard.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0xFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0xFFFF00FF) | (random_field_value << 8)) + + self.assertEqual(await self.dut.Rx_Sample_Discard.rx_nco_discard.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFF00) >> 8 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.Rx_Sample_Discard.rx_nco_discard.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFF00) >> 8 + + + sim_register.value = random_value + self.assertEqual(await self.dut.Rx_Sample_Discard.rx_nco_discard.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0xFF+1) + + await self.dut.Rx_Sample_Discard.rx_nco_discard.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFF00FF) | (0xFF00 & (random_field_value << 8))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0xFF+1) + + await self.dut.Rx_Sample_Discard.rx_nco_discard.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFF00FF) | (0xFF00 & (random_field_value << 8))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0xFFFF00FF) | (0xFF00 & (random_field_value << 8))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0xFF+1) + + await self.dut.Rx_Sample_Discard.rx_nco_discard.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFF00FF) | (0xFF00 & (random_field_value << 8))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.LPF_Config_2.p_gain + with self.subTest(msg='field: msk_top_regs.LPF_Config_2.p_gain'): + sim_register = self.sim.register_by_full_name('msk_top_regs.LPF_Config_2') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.LPF_Config_2.p_gain') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.LPF_Config_2.p_gain.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0xFFFFFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0xFF000000) | (random_field_value << 0)) + + self.assertEqual(await self.dut.LPF_Config_2.p_gain.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFF) >> 0 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.LPF_Config_2.p_gain.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.LPF_Config_2.p_gain.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0xFFFFFF+1) + + await self.dut.LPF_Config_2.p_gain.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFF000000) | (0xFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0xFFFFFF+1) + + await self.dut.LPF_Config_2.p_gain.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFF000000) | (0xFFFFFF & (random_field_value << 0))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0xFF000000) | (0xFFFFFF & (random_field_value << 0))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0xFFFFFF+1) + + await self.dut.LPF_Config_2.p_gain.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFF000000) | (0xFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.LPF_Config_2.p_shift + with self.subTest(msg='field: msk_top_regs.LPF_Config_2.p_shift'): + sim_register = self.sim.register_by_full_name('msk_top_regs.LPF_Config_2') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.LPF_Config_2.p_shift') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFF000000) >> 24 + + + sim_register.value = random_value + self.assertEqual(await self.dut.LPF_Config_2.p_shift.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0xFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0xFFFFFF) | (random_field_value << 24)) + + self.assertEqual(await self.dut.LPF_Config_2.p_shift.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFF000000) >> 24 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.LPF_Config_2.p_shift.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFF000000) >> 24 + + + sim_register.value = random_value + self.assertEqual(await self.dut.LPF_Config_2.p_shift.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0xFF+1) + + await self.dut.LPF_Config_2.p_shift.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFF) | (0xFF000000 & (random_field_value << 24))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0xFF+1) + + await self.dut.LPF_Config_2.p_shift.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFF) | (0xFF000000 & (random_field_value << 24))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0xFFFFFF) | (0xFF000000 & (random_field_value << 24))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0xFF+1) + + await self.dut.LPF_Config_2.p_shift.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFF) | (0xFF000000 & (random_field_value << 24))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.f1_nco_adjust.data + with self.subTest(msg='field: msk_top_regs.f1_nco_adjust.data'): + sim_register = self.sim.register_by_full_name('msk_top_regs.f1_nco_adjust') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.f1_nco_adjust.data') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.f1_nco_adjust.data.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0x0) | (random_field_value << 0)) + + self.assertEqual(await self.dut.f1_nco_adjust.data.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.f1_nco_adjust.data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.f1_nco_adjust.data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.f1_nco_adjust.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.f1_nco_adjust.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.f1_nco_adjust.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.f2_nco_adjust.data + with self.subTest(msg='field: msk_top_regs.f2_nco_adjust.data'): + sim_register = self.sim.register_by_full_name('msk_top_regs.f2_nco_adjust') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.f2_nco_adjust.data') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.f2_nco_adjust.data.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0x0) | (random_field_value << 0)) + + self.assertEqual(await self.dut.f2_nco_adjust.data.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.f2_nco_adjust.data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.f2_nco_adjust.data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.f2_nco_adjust.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.f2_nco_adjust.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.f2_nco_adjust.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.f1_error.data + with self.subTest(msg='field: msk_top_regs.f1_error.data'): + sim_register = self.sim.register_by_full_name('msk_top_regs.f1_error') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.f1_error.data') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.f1_error.data.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0x0) | (random_field_value << 0)) + + self.assertEqual(await self.dut.f1_error.data.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.f1_error.data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.f1_error.data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.f1_error.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.f1_error.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.f1_error.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.f2_error.data + with self.subTest(msg='field: msk_top_regs.f2_error.data'): + sim_register = self.sim.register_by_full_name('msk_top_regs.f2_error') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.f2_error.data') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.f2_error.data.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0x0) | (random_field_value << 0)) + + self.assertEqual(await self.dut.f2_error.data.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.f2_error.data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.f2_error.data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.f2_error.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.f2_error.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.f2_error.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.Tx_Sync_Ctrl.tx_sync_ena + with self.subTest(msg='field: msk_top_regs.Tx_Sync_Ctrl.tx_sync_ena'): + sim_register = self.sim.register_by_full_name('msk_top_regs.Tx_Sync_Ctrl') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.Tx_Sync_Ctrl.tx_sync_ena') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x1) >> 0 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.Tx_Sync_Ctrl.tx_sync_ena.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0x1+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0xFFFFFFFE) | (random_field_value << 0)) + + self.assertEqual(await self.dut.Tx_Sync_Ctrl.tx_sync_ena.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x1) >> 0 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.Tx_Sync_Ctrl.tx_sync_ena.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x1) >> 0 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.Tx_Sync_Ctrl.tx_sync_ena.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.Tx_Sync_Ctrl.tx_sync_ena.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFE) | (0x1 & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.Tx_Sync_Ctrl.tx_sync_ena.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFE) | (0x1 & (random_field_value << 0))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0xFFFFFFFE) | (0x1 & (random_field_value << 0))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.Tx_Sync_Ctrl.tx_sync_ena.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFE) | (0x1 & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.Tx_Sync_Ctrl.tx_sync_force + with self.subTest(msg='field: msk_top_regs.Tx_Sync_Ctrl.tx_sync_force'): + sim_register = self.sim.register_by_full_name('msk_top_regs.Tx_Sync_Ctrl') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.Tx_Sync_Ctrl.tx_sync_force') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x2) >> 1 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.Tx_Sync_Ctrl.tx_sync_force.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0x1+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0xFFFFFFFD) | (random_field_value << 1)) + + self.assertEqual(await self.dut.Tx_Sync_Ctrl.tx_sync_force.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x2) >> 1 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.Tx_Sync_Ctrl.tx_sync_force.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x2) >> 1 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.Tx_Sync_Ctrl.tx_sync_force.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.Tx_Sync_Ctrl.tx_sync_force.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFD) | (0x2 & (random_field_value << 1))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.Tx_Sync_Ctrl.tx_sync_force.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFD) | (0x2 & (random_field_value << 1))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0xFFFFFFFD) | (0x2 & (random_field_value << 1))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0x1+1) + + await self.dut.Tx_Sync_Ctrl.tx_sync_force.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFFFFFD) | (0x2 & (random_field_value << 1))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.Tx_Sync_Cnt.tx_sync_cnt + with self.subTest(msg='field: msk_top_regs.Tx_Sync_Cnt.tx_sync_cnt'): + sim_register = self.sim.register_by_full_name('msk_top_regs.Tx_Sync_Cnt') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.Tx_Sync_Cnt.tx_sync_cnt') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.Tx_Sync_Cnt.tx_sync_cnt.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0xFFFFFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0xFF000000) | (random_field_value << 0)) + + self.assertEqual(await self.dut.Tx_Sync_Cnt.tx_sync_cnt.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFF) >> 0 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.Tx_Sync_Cnt.tx_sync_cnt.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.Tx_Sync_Cnt.tx_sync_cnt.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0xFFFFFF+1) + + await self.dut.Tx_Sync_Cnt.tx_sync_cnt.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFF000000) | (0xFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0xFFFFFF+1) + + await self.dut.Tx_Sync_Cnt.tx_sync_cnt.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFF000000) | (0xFFFFFF & (random_field_value << 0))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0xFF000000) | (0xFFFFFF & (random_field_value << 0))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0xFFFFFF+1) + + await self.dut.Tx_Sync_Cnt.tx_sync_cnt.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFF000000) | (0xFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.lowpass_ema_alpha1.alpha + with self.subTest(msg='field: msk_top_regs.lowpass_ema_alpha1.alpha'): + sim_register = self.sim.register_by_full_name('msk_top_regs.lowpass_ema_alpha1') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.lowpass_ema_alpha1.alpha') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x3FFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.lowpass_ema_alpha1.alpha.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0x3FFFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0xFFFC0000) | (random_field_value << 0)) + + self.assertEqual(await self.dut.lowpass_ema_alpha1.alpha.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x3FFFF) >> 0 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.lowpass_ema_alpha1.alpha.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x3FFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.lowpass_ema_alpha1.alpha.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0x3FFFF+1) + + await self.dut.lowpass_ema_alpha1.alpha.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFC0000) | (0x3FFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0x3FFFF+1) + + await self.dut.lowpass_ema_alpha1.alpha.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFC0000) | (0x3FFFF & (random_field_value << 0))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0xFFFC0000) | (0x3FFFF & (random_field_value << 0))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0x3FFFF+1) + + await self.dut.lowpass_ema_alpha1.alpha.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFC0000) | (0x3FFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.lowpass_ema_alpha2.alpha + with self.subTest(msg='field: msk_top_regs.lowpass_ema_alpha2.alpha'): + sim_register = self.sim.register_by_full_name('msk_top_regs.lowpass_ema_alpha2') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.lowpass_ema_alpha2.alpha') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x3FFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.lowpass_ema_alpha2.alpha.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0x3FFFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0xFFFC0000) | (random_field_value << 0)) + + self.assertEqual(await self.dut.lowpass_ema_alpha2.alpha.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x3FFFF) >> 0 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.lowpass_ema_alpha2.alpha.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x3FFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.lowpass_ema_alpha2.alpha.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0x3FFFF+1) + + await self.dut.lowpass_ema_alpha2.alpha.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFC0000) | (0x3FFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0x3FFFF+1) + + await self.dut.lowpass_ema_alpha2.alpha.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFC0000) | (0x3FFFF & (random_field_value << 0))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0xFFFC0000) | (0x3FFFF & (random_field_value << 0))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0x3FFFF+1) + + await self.dut.lowpass_ema_alpha2.alpha.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFFFC0000) | (0x3FFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.rx_power.data + with self.subTest(msg='field: msk_top_regs.rx_power.data'): + sim_register = self.sim.register_by_full_name('msk_top_regs.rx_power') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.rx_power.data') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x7FFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.rx_power.data.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0x7FFFFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0xFF800000) | (random_field_value << 0)) + + self.assertEqual(await self.dut.rx_power.data.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x7FFFFF) >> 0 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.rx_power.data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x7FFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.rx_power.data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0x7FFFFF+1) + + await self.dut.rx_power.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFF800000) | (0x7FFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0x7FFFFF+1) + + await self.dut.rx_power.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFF800000) | (0x7FFFFF & (random_field_value << 0))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0xFF800000) | (0x7FFFFF & (random_field_value << 0))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0x7FFFFF+1) + + await self.dut.rx_power.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFF800000) | (0x7FFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.tx_async_fifo_rd_wr_ptr.data + with self.subTest(msg='field: msk_top_regs.tx_async_fifo_rd_wr_ptr.data'): + sim_register = self.sim.register_by_full_name('msk_top_regs.tx_async_fifo_rd_wr_ptr') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.tx_async_fifo_rd_wr_ptr.data') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.tx_async_fifo_rd_wr_ptr.data.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0x0) | (random_field_value << 0)) + + self.assertEqual(await self.dut.tx_async_fifo_rd_wr_ptr.data.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.tx_async_fifo_rd_wr_ptr.data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.tx_async_fifo_rd_wr_ptr.data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.tx_async_fifo_rd_wr_ptr.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.tx_async_fifo_rd_wr_ptr.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.tx_async_fifo_rd_wr_ptr.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.rx_async_fifo_rd_wr_ptr.data + with self.subTest(msg='field: msk_top_regs.rx_async_fifo_rd_wr_ptr.data'): + sim_register = self.sim.register_by_full_name('msk_top_regs.rx_async_fifo_rd_wr_ptr') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.rx_async_fifo_rd_wr_ptr.data') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.rx_async_fifo_rd_wr_ptr.data.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0x0) | (random_field_value << 0)) + + self.assertEqual(await self.dut.rx_async_fifo_rd_wr_ptr.data.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.rx_async_fifo_rd_wr_ptr.data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFFFFFFFF) >> 0 + + + sim_register.value = random_value + self.assertEqual(await self.dut.rx_async_fifo_rd_wr_ptr.data.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.rx_async_fifo_rd_wr_ptr.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.rx_async_fifo_rd_wr_ptr.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0xFFFFFFFF+1) + + await self.dut.rx_async_fifo_rd_wr_ptr.data.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x0) | (0xFFFFFFFF & (random_field_value << 0))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.rx_frame_sync_status.frame_sync_locked + with self.subTest(msg='field: msk_top_regs.rx_frame_sync_status.frame_sync_locked'): + sim_register = self.sim.register_by_full_name('msk_top_regs.rx_frame_sync_status') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.rx_frame_sync_status.frame_sync_locked') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x1) >> 0 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.rx_frame_sync_status.frame_sync_locked.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0x1+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0xFFFFFFFE) | (random_field_value << 0)) + + self.assertEqual(await self.dut.rx_frame_sync_status.frame_sync_locked.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x1) >> 0 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.rx_frame_sync_status.frame_sync_locked.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x1) >> 0 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.rx_frame_sync_status.frame_sync_locked.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + + + # test access operations (read and/or write) to register: + # msk_top_regs.rx_frame_sync_status.frame_buffer_overflow + with self.subTest(msg='field: msk_top_regs.rx_frame_sync_status.frame_buffer_overflow'): + sim_register = self.sim.register_by_full_name('msk_top_regs.rx_frame_sync_status') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.rx_frame_sync_status.frame_buffer_overflow') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x2) >> 1 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.rx_frame_sync_status.frame_buffer_overflow.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0x1+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0xFFFFFFFD) | (random_field_value << 1)) + + self.assertEqual(await self.dut.rx_frame_sync_status.frame_buffer_overflow.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x2) >> 1 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.rx_frame_sync_status.frame_buffer_overflow.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x2) >> 1 + + random_field_value = self._reverse_bits(value=random_field_value, number_bits=1) + + + sim_register.value = random_value + self.assertEqual(await self.dut.rx_frame_sync_status.frame_buffer_overflow.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + + + # test access operations (read and/or write) to register: + # msk_top_regs.rx_frame_sync_status.frames_received + with self.subTest(msg='field: msk_top_regs.rx_frame_sync_status.frames_received'): + sim_register = self.sim.register_by_full_name('msk_top_regs.rx_frame_sync_status') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.rx_frame_sync_status.frames_received') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x3FFFFFC) >> 2 + + + sim_register.value = random_value + self.assertEqual(await self.dut.rx_frame_sync_status.frames_received.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0xFFFFFF+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0xFC000003) | (random_field_value << 2)) + + self.assertEqual(await self.dut.rx_frame_sync_status.frames_received.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x3FFFFFC) >> 2 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.rx_frame_sync_status.frames_received.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0x3FFFFFC) >> 2 + + + sim_register.value = random_value + self.assertEqual(await self.dut.rx_frame_sync_status.frames_received.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0xFFFFFF+1) + + await self.dut.rx_frame_sync_status.frames_received.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFC000003) | (0x3FFFFFC & (random_field_value << 2))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0xFFFFFF+1) + + await self.dut.rx_frame_sync_status.frames_received.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFC000003) | (0x3FFFFFC & (random_field_value << 2))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0xFC000003) | (0x3FFFFFC & (random_field_value << 2))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0xFFFFFF+1) + + await self.dut.rx_frame_sync_status.frames_received.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0xFC000003) | (0x3FFFFFC & (random_field_value << 2))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # test access operations (read and/or write) to register: + # msk_top_regs.rx_frame_sync_status.frame_sync_errors + with self.subTest(msg='field: msk_top_regs.rx_frame_sync_status.frame_sync_errors'): + sim_register = self.sim.register_by_full_name('msk_top_regs.rx_frame_sync_status') + self.assertIsInstance(sim_register, (Register,MemoryRegister)) + sim_field = self.sim.field_by_full_name('msk_top_regs.rx_frame_sync_status.frame_sync_errors') + self.assertIsInstance(sim_field, Field) + register_read_callback = Mock() + register_write_callback = Mock() + field_read_callback = Mock() + field_write_callback = Mock() + + # register read checks + # update the register value via the backdoor in the simulator + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFC000000) >> 26 + + + sim_register.value = random_value + self.assertEqual(await self.dut.rx_frame_sync_status.frame_sync_errors.read(), random_field_value) + # update the field value via the backdoor in the simulator + previous_register_value = random_value + random_field_value = random.randrange(0, 0x3F+1) + sim_field.value = random_field_value + self.assertEqual(sim_register.value, (previous_register_value & 0x3FFFFFF) | (random_field_value << 26)) + + self.assertEqual(await self.dut.rx_frame_sync_status.frame_sync_errors.read(), random_field_value) + # hook up the call backs to check they work correctly + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFC000000) >> 26 + + + sim_register.value = random_value + sim_register.read_callback = register_read_callback + sim_register.write_callback = register_write_callback + sim_field.read_callback = field_read_callback + sim_field.write_callback = field_write_callback + self.assertEqual(await self.dut.rx_frame_sync_status.frame_sync_errors.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_called_once_with(value=random_value) + field_write_callback.assert_not_called() + field_read_callback.assert_called_once_with(value=random_field_value) + + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.read_callback = None + sim_register.write_callback = None + sim_field.read_callback = None + sim_field.write_callback = None + random_value = random.randrange(0, 0xFFFFFFFF+1) + random_field_value = (random_value & 0xFC000000) >> 26 + + + sim_register.value = random_value + self.assertEqual(await self.dut.rx_frame_sync_status.frame_sync_errors.read(), random_field_value) + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + # register write checks + # update the register value via the backdoor in the simulator, then perform a field + # write and make sure it is updated + inital_reg_random_value = random.randrange(0, 0xFFFFFFFF+1) + sim_register.value = inital_reg_random_value + + random_field_value = random.randrange(0, 0x3F+1) + + await self.dut.rx_frame_sync_status.frame_sync_errors.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x3FFFFFF) | (0xFC000000 & (random_field_value << 26))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # hook up the call backs + sim_register.read_callback = None + sim_register.write_callback = register_write_callback + sim_field.read_callback = None + sim_field.write_callback = field_write_callback + random_field_value = random.randrange(0, 0x3F+1) + + await self.dut.rx_frame_sync_status.frame_sync_errors.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x3FFFFFF) | (0xFC000000 & (random_field_value << 26))) + register_write_callback.assert_called_once_with(value=(reg_random_value & 0x3FFFFFF) | (0xFC000000 & (random_field_value << 26))) + field_write_callback.assert_called_once_with(value=random_field_value) + + register_read_callback.assert_not_called() + field_read_callback.assert_not_called() + reg_random_value = sim_register.value + # revert the callbacks and check again + register_write_callback.reset_mock() + register_read_callback.reset_mock() + field_write_callback.reset_mock() + field_read_callback.reset_mock() + sim_register.write_callback = None + sim_field.write_callback = None + random_field_value = random.randrange(0, 0x3F+1) + + await self.dut.rx_frame_sync_status.frame_sync_errors.write(random_field_value) # type: ignore[arg-type] + self.assertEqual(sim_register.value, (inital_reg_random_value & 0x3FFFFFF) | (0xFC000000 & (random_field_value << 26))) + + register_write_callback.assert_not_called() + register_read_callback.assert_not_called() + field_write_callback.assert_not_called() + field_read_callback.assert_not_called() + + + + + + + + + +class msk_top_regs_block_access(msk_top_regs_SimTestCase_BlockAccess): # type: ignore[valid-type,misc] + """ + tests for all the block access methods + """ + + + +if __name__ == '__main__': + + if sys.version_info < (3, 8): + asynctest.main() + else: + unittest.main() + + + + diff --git a/rdl/outputs/rtl/msk_top_regs.vhd b/rdl/outputs/rtl/msk_top_regs.vhd new file mode 100644 index 0000000..952a997 --- /dev/null +++ b/rdl/outputs/rtl/msk_top_regs.vhd @@ -0,0 +1,3102 @@ +-- Generated by PeakRDL-regblock-vhdl - A free and open-source VHDL generator +-- https://github.com/SystemRDL/PeakRDL-regblock-vhdl +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use ieee.fixed_pkg.all; + +use work.msk_top_regs_pkg.all; +use work.axi4lite_intf_pkg.all; +use work.reg_utils.all; + +entity msk_top_regs is + port ( + clk : in std_logic; + rst : in std_logic; + + s_axil_i : in axi4lite_slave_in_intf( + AWADDR(7 downto 0), + WDATA(31 downto 0), + WSTRB(3 downto 0), + ARADDR(7 downto 0) + ); + s_axil_o : out axi4lite_slave_out_intf( + RDATA(31 downto 0) + ); + + hwif_in : in msk_top_regs_in_t; + hwif_out : out msk_top_regs_out_t + ); +end entity msk_top_regs; + +architecture rtl of msk_top_regs is + ---------------------------------------------------------------------------- + -- CPU Bus interface signals + ---------------------------------------------------------------------------- + signal cpuif_req : std_logic; + signal cpuif_req_is_wr : std_logic; + signal cpuif_addr : std_logic_vector(7 downto 0); + signal cpuif_wr_data : std_logic_vector(31 downto 0); + signal cpuif_wr_biten : std_logic_vector(31 downto 0); + signal cpuif_req_stall_wr : std_logic; + signal cpuif_req_stall_rd : std_logic; + + signal cpuif_rd_ack : std_logic; + signal cpuif_rd_err : std_logic; + signal cpuif_rd_data : std_logic_vector(31 downto 0); + + signal cpuif_wr_ack : std_logic; + signal cpuif_wr_err : std_logic; + + signal cpuif_req_masked : std_logic; + + signal axil_n_in_flight : unsigned(1 downto 0); + signal axil_prev_was_rd : std_logic; + signal axil_arvalid : std_logic; + signal axil_araddr : std_logic_vector(7 downto 0); + signal axil_ar_accept : std_logic; + signal axil_awvalid : std_logic; + signal axil_awaddr : std_logic_vector(7 downto 0); + signal axil_wvalid : std_logic; + signal axil_wdata : std_logic_vector(31 downto 0); + signal axil_wstrb : std_logic_vector(3 downto 0); + signal axil_aw_accept : std_logic; + signal axil_resp_acked : std_logic; + type axil_resp_buffer_t is record + is_wr : std_logic; + err : std_logic; + rdata : std_logic_vector(31 downto 0); + end record axil_resp_buffer_t; + type axil_resp_buffer_array_t is array (integer range <>) of axil_resp_buffer_t; + signal axil_resp_buffer : axil_resp_buffer_array_t(1 downto 0); + signal axil_resp_wptr : unsigned(1 downto 0); + signal axil_resp_rptr : unsigned(1 downto 0); + + ---------------------------------------------------------------------------- + -- Address Decode Signals + ---------------------------------------------------------------------------- + type decoded_reg_strb_t is record + Hash_ID_Low : std_logic; + Hash_ID_High : std_logic; + MSK_Init : std_logic; + MSK_Control : std_logic; + MSK_Status : std_logic; + Tx_Bit_Count : std_logic; + Tx_Enable_Count : std_logic; + Fb_FreqWord : std_logic; + TX_F1_FreqWord : std_logic; + TX_F2_FreqWord : std_logic; + RX_F1_FreqWord : std_logic; + RX_F2_FreqWord : std_logic; + LPF_Config_0 : std_logic; + LPF_Config_1 : std_logic; + Tx_Data_Width : std_logic; + Rx_Data_Width : std_logic; + PRBS_Control : std_logic; + PRBS_Initial_State : std_logic; + PRBS_Polynomial : std_logic; + PRBS_Error_Mask : std_logic; + PRBS_Bit_Count : std_logic; + PRBS_Error_Count : std_logic; + LPF_Accum_F1 : std_logic; + LPF_Accum_F2 : std_logic; + axis_xfer_count : std_logic; + Rx_Sample_Discard : std_logic; + LPF_Config_2 : std_logic; + f1_nco_adjust : std_logic; + f2_nco_adjust : std_logic; + f1_error : std_logic; + f2_error : std_logic; + Tx_Sync_Ctrl : std_logic; + Tx_Sync_Cnt : std_logic; + lowpass_ema_alpha1 : std_logic; + lowpass_ema_alpha2 : std_logic; + rx_power : std_logic; + tx_async_fifo_rd_wr_ptr : std_logic; + rx_async_fifo_rd_wr_ptr : std_logic; + rx_frame_sync_status : std_logic; + end record; + signal decoded_reg_strb : decoded_reg_strb_t; + signal decoded_req : std_logic; + signal decoded_req_is_wr : std_logic; + signal decoded_wr_data : std_logic_vector(31 downto 0); + signal decoded_wr_biten : std_logic_vector(31 downto 0); + + ---------------------------------------------------------------------------- + -- Field Logic Signals + ---------------------------------------------------------------------------- + -- Field Combinational Signals + type \msk_top_regs.MSK_Init.txrxinit_combo_t\ is record + next_q : std_logic; + load_next : std_logic; + end record; + + type \msk_top_regs.MSK_Init.txinit_combo_t\ is record + next_q : std_logic; + load_next : std_logic; + end record; + + type \msk_top_regs.MSK_Init.rxinit_combo_t\ is record + next_q : std_logic; + load_next : std_logic; + end record; + + type \msk_top_regs.MSK_Init_combo_t\ is record + txrxinit : \msk_top_regs.MSK_Init.txrxinit_combo_t\; + txinit : \msk_top_regs.MSK_Init.txinit_combo_t\; + rxinit : \msk_top_regs.MSK_Init.rxinit_combo_t\; + end record; + + type \msk_top_regs.MSK_Control.ptt_combo_t\ is record + next_q : std_logic; + load_next : std_logic; + end record; + + type \msk_top_regs.MSK_Control.loopback_ena_combo_t\ is record + next_q : std_logic; + load_next : std_logic; + end record; + + type \msk_top_regs.MSK_Control.rx_invert_combo_t\ is record + next_q : std_logic; + load_next : std_logic; + end record; + + type \msk_top_regs.MSK_Control.clear_counts_combo_t\ is record + next_q : std_logic; + load_next : std_logic; + end record; + + type \msk_top_regs.MSK_Control.diff_encoder_loopback_combo_t\ is record + next_q : std_logic; + load_next : std_logic; + end record; + + type \msk_top_regs.MSK_Control_combo_t\ is record + ptt : \msk_top_regs.MSK_Control.ptt_combo_t\; + loopback_ena : \msk_top_regs.MSK_Control.loopback_ena_combo_t\; + rx_invert : \msk_top_regs.MSK_Control.rx_invert_combo_t\; + clear_counts : \msk_top_regs.MSK_Control.clear_counts_combo_t\; + diff_encoder_loopback : \msk_top_regs.MSK_Control.diff_encoder_loopback_combo_t\; + end record; + + type \msk_top_regs.Tx_Bit_Count.data_combo_t\ is record + next_q : std_logic_vector(31 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.Tx_Bit_Count_combo_t\ is record + data : \msk_top_regs.Tx_Bit_Count.data_combo_t\; + end record; + + type \msk_top_regs.Tx_Enable_Count.data_combo_t\ is record + next_q : std_logic_vector(31 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.Tx_Enable_Count_combo_t\ is record + data : \msk_top_regs.Tx_Enable_Count.data_combo_t\; + end record; + + type \msk_top_regs.Fb_FreqWord.config_data_combo_t\ is record + next_q : std_logic_vector(31 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.Fb_FreqWord_combo_t\ is record + config_data : \msk_top_regs.Fb_FreqWord.config_data_combo_t\; + end record; + + type \msk_top_regs.TX_F1_FreqWord.config_data_combo_t\ is record + next_q : std_logic_vector(31 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.TX_F1_FreqWord_combo_t\ is record + config_data : \msk_top_regs.TX_F1_FreqWord.config_data_combo_t\; + end record; + + type \msk_top_regs.TX_F2_FreqWord.config_data_combo_t\ is record + next_q : std_logic_vector(31 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.TX_F2_FreqWord_combo_t\ is record + config_data : \msk_top_regs.TX_F2_FreqWord.config_data_combo_t\; + end record; + + type \msk_top_regs.RX_F1_FreqWord.config_data_combo_t\ is record + next_q : std_logic_vector(31 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.RX_F1_FreqWord_combo_t\ is record + config_data : \msk_top_regs.RX_F1_FreqWord.config_data_combo_t\; + end record; + + type \msk_top_regs.RX_F2_FreqWord.config_data_combo_t\ is record + next_q : std_logic_vector(31 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.RX_F2_FreqWord_combo_t\ is record + config_data : \msk_top_regs.RX_F2_FreqWord.config_data_combo_t\; + end record; + + type \msk_top_regs.LPF_Config_0.lpf_freeze_combo_t\ is record + next_q : std_logic; + load_next : std_logic; + end record; + + type \msk_top_regs.LPF_Config_0.lpf_zero_combo_t\ is record + next_q : std_logic; + load_next : std_logic; + end record; + + type \msk_top_regs.LPF_Config_0.prbs_reserved_combo_t\ is record + next_q : std_logic_vector(5 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.LPF_Config_0.lpf_alpha_combo_t\ is record + next_q : std_logic_vector(23 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.LPF_Config_0_combo_t\ is record + lpf_freeze : \msk_top_regs.LPF_Config_0.lpf_freeze_combo_t\; + lpf_zero : \msk_top_regs.LPF_Config_0.lpf_zero_combo_t\; + prbs_reserved : \msk_top_regs.LPF_Config_0.prbs_reserved_combo_t\; + lpf_alpha : \msk_top_regs.LPF_Config_0.lpf_alpha_combo_t\; + end record; + + type \msk_top_regs.LPF_Config_1.i_gain_combo_t\ is record + next_q : std_logic_vector(23 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.LPF_Config_1.i_shift_combo_t\ is record + next_q : std_logic_vector(7 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.LPF_Config_1_combo_t\ is record + i_gain : \msk_top_regs.LPF_Config_1.i_gain_combo_t\; + i_shift : \msk_top_regs.LPF_Config_1.i_shift_combo_t\; + end record; + + type \msk_top_regs.Tx_Data_Width.data_width_combo_t\ is record + next_q : std_logic_vector(7 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.Tx_Data_Width_combo_t\ is record + data_width : \msk_top_regs.Tx_Data_Width.data_width_combo_t\; + end record; + + type \msk_top_regs.Rx_Data_Width.data_width_combo_t\ is record + next_q : std_logic_vector(7 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.Rx_Data_Width_combo_t\ is record + data_width : \msk_top_regs.Rx_Data_Width.data_width_combo_t\; + end record; + + type \msk_top_regs.PRBS_Control.prbs_sel_combo_t\ is record + next_q : std_logic; + load_next : std_logic; + end record; + + type \msk_top_regs.PRBS_Control.prbs_error_insert_combo_t\ is record + next_q : std_logic; + load_next : std_logic; + end record; + + type \msk_top_regs.PRBS_Control.prbs_clear_combo_t\ is record + next_q : std_logic; + load_next : std_logic; + end record; + + type \msk_top_regs.PRBS_Control.prbs_manual_sync_combo_t\ is record + next_q : std_logic; + load_next : std_logic; + end record; + + type \msk_top_regs.PRBS_Control.prbs_reserved_combo_t\ is record + next_q : std_logic_vector(11 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.PRBS_Control.prbs_sync_threshold_combo_t\ is record + next_q : std_logic_vector(15 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.PRBS_Control_combo_t\ is record + prbs_sel : \msk_top_regs.PRBS_Control.prbs_sel_combo_t\; + prbs_error_insert : \msk_top_regs.PRBS_Control.prbs_error_insert_combo_t\; + prbs_clear : \msk_top_regs.PRBS_Control.prbs_clear_combo_t\; + prbs_manual_sync : \msk_top_regs.PRBS_Control.prbs_manual_sync_combo_t\; + prbs_reserved : \msk_top_regs.PRBS_Control.prbs_reserved_combo_t\; + prbs_sync_threshold : \msk_top_regs.PRBS_Control.prbs_sync_threshold_combo_t\; + end record; + + type \msk_top_regs.PRBS_Initial_State.config_data_combo_t\ is record + next_q : std_logic_vector(31 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.PRBS_Initial_State_combo_t\ is record + config_data : \msk_top_regs.PRBS_Initial_State.config_data_combo_t\; + end record; + + type \msk_top_regs.PRBS_Polynomial.config_data_combo_t\ is record + next_q : std_logic_vector(31 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.PRBS_Polynomial_combo_t\ is record + config_data : \msk_top_regs.PRBS_Polynomial.config_data_combo_t\; + end record; + + type \msk_top_regs.PRBS_Error_Mask.config_data_combo_t\ is record + next_q : std_logic_vector(31 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.PRBS_Error_Mask_combo_t\ is record + config_data : \msk_top_regs.PRBS_Error_Mask.config_data_combo_t\; + end record; + + type \msk_top_regs.PRBS_Bit_Count.data_combo_t\ is record + next_q : std_logic_vector(31 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.PRBS_Bit_Count_combo_t\ is record + data : \msk_top_regs.PRBS_Bit_Count.data_combo_t\; + end record; + + type \msk_top_regs.PRBS_Error_Count.data_combo_t\ is record + next_q : std_logic_vector(31 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.PRBS_Error_Count_combo_t\ is record + data : \msk_top_regs.PRBS_Error_Count.data_combo_t\; + end record; + + type \msk_top_regs.LPF_Accum_F1.data_combo_t\ is record + next_q : std_logic_vector(31 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.LPF_Accum_F1_combo_t\ is record + data : \msk_top_regs.LPF_Accum_F1.data_combo_t\; + end record; + + type \msk_top_regs.LPF_Accum_F2.data_combo_t\ is record + next_q : std_logic_vector(31 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.LPF_Accum_F2_combo_t\ is record + data : \msk_top_regs.LPF_Accum_F2.data_combo_t\; + end record; + + type \msk_top_regs.axis_xfer_count.data_combo_t\ is record + next_q : std_logic_vector(31 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.axis_xfer_count_combo_t\ is record + data : \msk_top_regs.axis_xfer_count.data_combo_t\; + end record; + + type \msk_top_regs.Rx_Sample_Discard.rx_sample_discard_combo_t\ is record + next_q : std_logic_vector(7 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.Rx_Sample_Discard.rx_nco_discard_combo_t\ is record + next_q : std_logic_vector(7 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.Rx_Sample_Discard_combo_t\ is record + rx_sample_discard : \msk_top_regs.Rx_Sample_Discard.rx_sample_discard_combo_t\; + rx_nco_discard : \msk_top_regs.Rx_Sample_Discard.rx_nco_discard_combo_t\; + end record; + + type \msk_top_regs.LPF_Config_2.p_gain_combo_t\ is record + next_q : std_logic_vector(23 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.LPF_Config_2.p_shift_combo_t\ is record + next_q : std_logic_vector(7 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.LPF_Config_2_combo_t\ is record + p_gain : \msk_top_regs.LPF_Config_2.p_gain_combo_t\; + p_shift : \msk_top_regs.LPF_Config_2.p_shift_combo_t\; + end record; + + type \msk_top_regs.f1_nco_adjust.data_combo_t\ is record + next_q : std_logic_vector(31 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.f1_nco_adjust_combo_t\ is record + data : \msk_top_regs.f1_nco_adjust.data_combo_t\; + end record; + + type \msk_top_regs.f2_nco_adjust.data_combo_t\ is record + next_q : std_logic_vector(31 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.f2_nco_adjust_combo_t\ is record + data : \msk_top_regs.f2_nco_adjust.data_combo_t\; + end record; + + type \msk_top_regs.f1_error.data_combo_t\ is record + next_q : std_logic_vector(31 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.f1_error_combo_t\ is record + data : \msk_top_regs.f1_error.data_combo_t\; + end record; + + type \msk_top_regs.f2_error.data_combo_t\ is record + next_q : std_logic_vector(31 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.f2_error_combo_t\ is record + data : \msk_top_regs.f2_error.data_combo_t\; + end record; + + type \msk_top_regs.Tx_Sync_Ctrl.tx_sync_ena_combo_t\ is record + next_q : std_logic; + load_next : std_logic; + end record; + + type \msk_top_regs.Tx_Sync_Ctrl.tx_sync_force_combo_t\ is record + next_q : std_logic; + load_next : std_logic; + end record; + + type \msk_top_regs.Tx_Sync_Ctrl_combo_t\ is record + tx_sync_ena : \msk_top_regs.Tx_Sync_Ctrl.tx_sync_ena_combo_t\; + tx_sync_force : \msk_top_regs.Tx_Sync_Ctrl.tx_sync_force_combo_t\; + end record; + + type \msk_top_regs.Tx_Sync_Cnt.tx_sync_cnt_combo_t\ is record + next_q : std_logic_vector(23 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.Tx_Sync_Cnt_combo_t\ is record + tx_sync_cnt : \msk_top_regs.Tx_Sync_Cnt.tx_sync_cnt_combo_t\; + end record; + + type \msk_top_regs.lowpass_ema_alpha1.alpha_combo_t\ is record + next_q : std_logic_vector(17 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.lowpass_ema_alpha1_combo_t\ is record + alpha : \msk_top_regs.lowpass_ema_alpha1.alpha_combo_t\; + end record; + + type \msk_top_regs.lowpass_ema_alpha2.alpha_combo_t\ is record + next_q : std_logic_vector(17 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.lowpass_ema_alpha2_combo_t\ is record + alpha : \msk_top_regs.lowpass_ema_alpha2.alpha_combo_t\; + end record; + + type \msk_top_regs.rx_power.data_combo_t\ is record + next_q : std_logic_vector(22 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.rx_power_combo_t\ is record + data : \msk_top_regs.rx_power.data_combo_t\; + end record; + + type \msk_top_regs.tx_async_fifo_rd_wr_ptr.data_combo_t\ is record + next_q : std_logic_vector(31 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.tx_async_fifo_rd_wr_ptr_combo_t\ is record + data : \msk_top_regs.tx_async_fifo_rd_wr_ptr.data_combo_t\; + end record; + + type \msk_top_regs.rx_async_fifo_rd_wr_ptr.data_combo_t\ is record + next_q : std_logic_vector(31 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.rx_async_fifo_rd_wr_ptr_combo_t\ is record + data : \msk_top_regs.rx_async_fifo_rd_wr_ptr.data_combo_t\; + end record; + + type \msk_top_regs.rx_frame_sync_status.frame_buffer_overflow_combo_t\ is record + next_q : std_logic; + load_next : std_logic; + end record; + + type \msk_top_regs.rx_frame_sync_status.frames_received_combo_t\ is record + next_q : std_logic_vector(23 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.rx_frame_sync_status.frame_sync_errors_combo_t\ is record + next_q : std_logic_vector(5 downto 0); + load_next : std_logic; + end record; + + type \msk_top_regs.rx_frame_sync_status_combo_t\ is record + frame_buffer_overflow : \msk_top_regs.rx_frame_sync_status.frame_buffer_overflow_combo_t\; + frames_received : \msk_top_regs.rx_frame_sync_status.frames_received_combo_t\; + frame_sync_errors : \msk_top_regs.rx_frame_sync_status.frame_sync_errors_combo_t\; + end record; + + type field_combo_t is record + MSK_Init : \msk_top_regs.MSK_Init_combo_t\; + MSK_Control : \msk_top_regs.MSK_Control_combo_t\; + Tx_Bit_Count : \msk_top_regs.Tx_Bit_Count_combo_t\; + Tx_Enable_Count : \msk_top_regs.Tx_Enable_Count_combo_t\; + Fb_FreqWord : \msk_top_regs.Fb_FreqWord_combo_t\; + TX_F1_FreqWord : \msk_top_regs.TX_F1_FreqWord_combo_t\; + TX_F2_FreqWord : \msk_top_regs.TX_F2_FreqWord_combo_t\; + RX_F1_FreqWord : \msk_top_regs.RX_F1_FreqWord_combo_t\; + RX_F2_FreqWord : \msk_top_regs.RX_F2_FreqWord_combo_t\; + LPF_Config_0 : \msk_top_regs.LPF_Config_0_combo_t\; + LPF_Config_1 : \msk_top_regs.LPF_Config_1_combo_t\; + Tx_Data_Width : \msk_top_regs.Tx_Data_Width_combo_t\; + Rx_Data_Width : \msk_top_regs.Rx_Data_Width_combo_t\; + PRBS_Control : \msk_top_regs.PRBS_Control_combo_t\; + PRBS_Initial_State : \msk_top_regs.PRBS_Initial_State_combo_t\; + PRBS_Polynomial : \msk_top_regs.PRBS_Polynomial_combo_t\; + PRBS_Error_Mask : \msk_top_regs.PRBS_Error_Mask_combo_t\; + PRBS_Bit_Count : \msk_top_regs.PRBS_Bit_Count_combo_t\; + PRBS_Error_Count : \msk_top_regs.PRBS_Error_Count_combo_t\; + LPF_Accum_F1 : \msk_top_regs.LPF_Accum_F1_combo_t\; + LPF_Accum_F2 : \msk_top_regs.LPF_Accum_F2_combo_t\; + axis_xfer_count : \msk_top_regs.axis_xfer_count_combo_t\; + Rx_Sample_Discard : \msk_top_regs.Rx_Sample_Discard_combo_t\; + LPF_Config_2 : \msk_top_regs.LPF_Config_2_combo_t\; + f1_nco_adjust : \msk_top_regs.f1_nco_adjust_combo_t\; + f2_nco_adjust : \msk_top_regs.f2_nco_adjust_combo_t\; + f1_error : \msk_top_regs.f1_error_combo_t\; + f2_error : \msk_top_regs.f2_error_combo_t\; + Tx_Sync_Ctrl : \msk_top_regs.Tx_Sync_Ctrl_combo_t\; + Tx_Sync_Cnt : \msk_top_regs.Tx_Sync_Cnt_combo_t\; + lowpass_ema_alpha1 : \msk_top_regs.lowpass_ema_alpha1_combo_t\; + lowpass_ema_alpha2 : \msk_top_regs.lowpass_ema_alpha2_combo_t\; + rx_power : \msk_top_regs.rx_power_combo_t\; + tx_async_fifo_rd_wr_ptr : \msk_top_regs.tx_async_fifo_rd_wr_ptr_combo_t\; + rx_async_fifo_rd_wr_ptr : \msk_top_regs.rx_async_fifo_rd_wr_ptr_combo_t\; + rx_frame_sync_status : \msk_top_regs.rx_frame_sync_status_combo_t\; + end record; + signal field_combo : field_combo_t; + + -- Field Storage Signals + type \msk_top_regs.MSK_Init.txrxinit_storage_t\ is record + value : std_logic; + end record; + + type \msk_top_regs.MSK_Init.txinit_storage_t\ is record + value : std_logic; + end record; + + type \msk_top_regs.MSK_Init.rxinit_storage_t\ is record + value : std_logic; + end record; + + type \msk_top_regs.MSK_Init_storage_t\ is record + txrxinit : \msk_top_regs.MSK_Init.txrxinit_storage_t\; + txinit : \msk_top_regs.MSK_Init.txinit_storage_t\; + rxinit : \msk_top_regs.MSK_Init.rxinit_storage_t\; + end record; + + type \msk_top_regs.MSK_Control.ptt_storage_t\ is record + value : std_logic; + end record; + + type \msk_top_regs.MSK_Control.loopback_ena_storage_t\ is record + value : std_logic; + end record; + + type \msk_top_regs.MSK_Control.rx_invert_storage_t\ is record + value : std_logic; + end record; + + type \msk_top_regs.MSK_Control.clear_counts_storage_t\ is record + value : std_logic; + end record; + + type \msk_top_regs.MSK_Control.diff_encoder_loopback_storage_t\ is record + value : std_logic; + end record; + + type \msk_top_regs.MSK_Control_storage_t\ is record + ptt : \msk_top_regs.MSK_Control.ptt_storage_t\; + loopback_ena : \msk_top_regs.MSK_Control.loopback_ena_storage_t\; + rx_invert : \msk_top_regs.MSK_Control.rx_invert_storage_t\; + clear_counts : \msk_top_regs.MSK_Control.clear_counts_storage_t\; + diff_encoder_loopback : \msk_top_regs.MSK_Control.diff_encoder_loopback_storage_t\; + end record; + + type \msk_top_regs.Tx_Bit_Count.data_storage_t\ is record + value : std_logic_vector(31 downto 0); + end record; + + type \msk_top_regs.Tx_Bit_Count_storage_t\ is record + data : \msk_top_regs.Tx_Bit_Count.data_storage_t\; + end record; + + type \msk_top_regs.Tx_Enable_Count.data_storage_t\ is record + value : std_logic_vector(31 downto 0); + end record; + + type \msk_top_regs.Tx_Enable_Count_storage_t\ is record + data : \msk_top_regs.Tx_Enable_Count.data_storage_t\; + end record; + + type \msk_top_regs.Fb_FreqWord.config_data_storage_t\ is record + value : std_logic_vector(31 downto 0); + end record; + + type \msk_top_regs.Fb_FreqWord_storage_t\ is record + config_data : \msk_top_regs.Fb_FreqWord.config_data_storage_t\; + end record; + + type \msk_top_regs.TX_F1_FreqWord.config_data_storage_t\ is record + value : std_logic_vector(31 downto 0); + end record; + + type \msk_top_regs.TX_F1_FreqWord_storage_t\ is record + config_data : \msk_top_regs.TX_F1_FreqWord.config_data_storage_t\; + end record; + + type \msk_top_regs.TX_F2_FreqWord.config_data_storage_t\ is record + value : std_logic_vector(31 downto 0); + end record; + + type \msk_top_regs.TX_F2_FreqWord_storage_t\ is record + config_data : \msk_top_regs.TX_F2_FreqWord.config_data_storage_t\; + end record; + + type \msk_top_regs.RX_F1_FreqWord.config_data_storage_t\ is record + value : std_logic_vector(31 downto 0); + end record; + + type \msk_top_regs.RX_F1_FreqWord_storage_t\ is record + config_data : \msk_top_regs.RX_F1_FreqWord.config_data_storage_t\; + end record; + + type \msk_top_regs.RX_F2_FreqWord.config_data_storage_t\ is record + value : std_logic_vector(31 downto 0); + end record; + + type \msk_top_regs.RX_F2_FreqWord_storage_t\ is record + config_data : \msk_top_regs.RX_F2_FreqWord.config_data_storage_t\; + end record; + + type \msk_top_regs.LPF_Config_0.lpf_freeze_storage_t\ is record + value : std_logic; + end record; + + type \msk_top_regs.LPF_Config_0.lpf_zero_storage_t\ is record + value : std_logic; + end record; + + type \msk_top_regs.LPF_Config_0.prbs_reserved_storage_t\ is record + value : std_logic_vector(5 downto 0); + end record; + + type \msk_top_regs.LPF_Config_0.lpf_alpha_storage_t\ is record + value : std_logic_vector(23 downto 0); + end record; + + type \msk_top_regs.LPF_Config_0_storage_t\ is record + lpf_freeze : \msk_top_regs.LPF_Config_0.lpf_freeze_storage_t\; + lpf_zero : \msk_top_regs.LPF_Config_0.lpf_zero_storage_t\; + prbs_reserved : \msk_top_regs.LPF_Config_0.prbs_reserved_storage_t\; + lpf_alpha : \msk_top_regs.LPF_Config_0.lpf_alpha_storage_t\; + end record; + + type \msk_top_regs.LPF_Config_1.i_gain_storage_t\ is record + value : std_logic_vector(23 downto 0); + end record; + + type \msk_top_regs.LPF_Config_1.i_shift_storage_t\ is record + value : std_logic_vector(7 downto 0); + end record; + + type \msk_top_regs.LPF_Config_1_storage_t\ is record + i_gain : \msk_top_regs.LPF_Config_1.i_gain_storage_t\; + i_shift : \msk_top_regs.LPF_Config_1.i_shift_storage_t\; + end record; + + type \msk_top_regs.Tx_Data_Width.data_width_storage_t\ is record + value : std_logic_vector(7 downto 0); + end record; + + type \msk_top_regs.Tx_Data_Width_storage_t\ is record + data_width : \msk_top_regs.Tx_Data_Width.data_width_storage_t\; + end record; + + type \msk_top_regs.Rx_Data_Width.data_width_storage_t\ is record + value : std_logic_vector(7 downto 0); + end record; + + type \msk_top_regs.Rx_Data_Width_storage_t\ is record + data_width : \msk_top_regs.Rx_Data_Width.data_width_storage_t\; + end record; + + type \msk_top_regs.PRBS_Control.prbs_sel_storage_t\ is record + value : std_logic; + end record; + + type \msk_top_regs.PRBS_Control.prbs_error_insert_storage_t\ is record + value : std_logic; + end record; + + type \msk_top_regs.PRBS_Control.prbs_clear_storage_t\ is record + value : std_logic; + end record; + + type \msk_top_regs.PRBS_Control.prbs_manual_sync_storage_t\ is record + value : std_logic; + end record; + + type \msk_top_regs.PRBS_Control.prbs_reserved_storage_t\ is record + value : std_logic_vector(11 downto 0); + end record; + + type \msk_top_regs.PRBS_Control.prbs_sync_threshold_storage_t\ is record + value : std_logic_vector(15 downto 0); + end record; + + type \msk_top_regs.PRBS_Control_storage_t\ is record + prbs_sel : \msk_top_regs.PRBS_Control.prbs_sel_storage_t\; + prbs_error_insert : \msk_top_regs.PRBS_Control.prbs_error_insert_storage_t\; + prbs_clear : \msk_top_regs.PRBS_Control.prbs_clear_storage_t\; + prbs_manual_sync : \msk_top_regs.PRBS_Control.prbs_manual_sync_storage_t\; + prbs_reserved : \msk_top_regs.PRBS_Control.prbs_reserved_storage_t\; + prbs_sync_threshold : \msk_top_regs.PRBS_Control.prbs_sync_threshold_storage_t\; + end record; + + type \msk_top_regs.PRBS_Initial_State.config_data_storage_t\ is record + value : std_logic_vector(31 downto 0); + end record; + + type \msk_top_regs.PRBS_Initial_State_storage_t\ is record + config_data : \msk_top_regs.PRBS_Initial_State.config_data_storage_t\; + end record; + + type \msk_top_regs.PRBS_Polynomial.config_data_storage_t\ is record + value : std_logic_vector(31 downto 0); + end record; + + type \msk_top_regs.PRBS_Polynomial_storage_t\ is record + config_data : \msk_top_regs.PRBS_Polynomial.config_data_storage_t\; + end record; + + type \msk_top_regs.PRBS_Error_Mask.config_data_storage_t\ is record + value : std_logic_vector(31 downto 0); + end record; + + type \msk_top_regs.PRBS_Error_Mask_storage_t\ is record + config_data : \msk_top_regs.PRBS_Error_Mask.config_data_storage_t\; + end record; + + type \msk_top_regs.PRBS_Bit_Count.data_storage_t\ is record + value : std_logic_vector(31 downto 0); + end record; + + type \msk_top_regs.PRBS_Bit_Count_storage_t\ is record + data : \msk_top_regs.PRBS_Bit_Count.data_storage_t\; + end record; + + type \msk_top_regs.PRBS_Error_Count.data_storage_t\ is record + value : std_logic_vector(31 downto 0); + end record; + + type \msk_top_regs.PRBS_Error_Count_storage_t\ is record + data : \msk_top_regs.PRBS_Error_Count.data_storage_t\; + end record; + + type \msk_top_regs.LPF_Accum_F1.data_storage_t\ is record + value : std_logic_vector(31 downto 0); + end record; + + type \msk_top_regs.LPF_Accum_F1_storage_t\ is record + data : \msk_top_regs.LPF_Accum_F1.data_storage_t\; + end record; + + type \msk_top_regs.LPF_Accum_F2.data_storage_t\ is record + value : std_logic_vector(31 downto 0); + end record; + + type \msk_top_regs.LPF_Accum_F2_storage_t\ is record + data : \msk_top_regs.LPF_Accum_F2.data_storage_t\; + end record; + + type \msk_top_regs.axis_xfer_count.data_storage_t\ is record + value : std_logic_vector(31 downto 0); + end record; + + type \msk_top_regs.axis_xfer_count_storage_t\ is record + data : \msk_top_regs.axis_xfer_count.data_storage_t\; + end record; + + type \msk_top_regs.Rx_Sample_Discard.rx_sample_discard_storage_t\ is record + value : std_logic_vector(7 downto 0); + end record; + + type \msk_top_regs.Rx_Sample_Discard.rx_nco_discard_storage_t\ is record + value : std_logic_vector(7 downto 0); + end record; + + type \msk_top_regs.Rx_Sample_Discard_storage_t\ is record + rx_sample_discard : \msk_top_regs.Rx_Sample_Discard.rx_sample_discard_storage_t\; + rx_nco_discard : \msk_top_regs.Rx_Sample_Discard.rx_nco_discard_storage_t\; + end record; + + type \msk_top_regs.LPF_Config_2.p_gain_storage_t\ is record + value : std_logic_vector(23 downto 0); + end record; + + type \msk_top_regs.LPF_Config_2.p_shift_storage_t\ is record + value : std_logic_vector(7 downto 0); + end record; + + type \msk_top_regs.LPF_Config_2_storage_t\ is record + p_gain : \msk_top_regs.LPF_Config_2.p_gain_storage_t\; + p_shift : \msk_top_regs.LPF_Config_2.p_shift_storage_t\; + end record; + + type \msk_top_regs.f1_nco_adjust.data_storage_t\ is record + value : std_logic_vector(31 downto 0); + end record; + + type \msk_top_regs.f1_nco_adjust_storage_t\ is record + data : \msk_top_regs.f1_nco_adjust.data_storage_t\; + end record; + + type \msk_top_regs.f2_nco_adjust.data_storage_t\ is record + value : std_logic_vector(31 downto 0); + end record; + + type \msk_top_regs.f2_nco_adjust_storage_t\ is record + data : \msk_top_regs.f2_nco_adjust.data_storage_t\; + end record; + + type \msk_top_regs.f1_error.data_storage_t\ is record + value : std_logic_vector(31 downto 0); + end record; + + type \msk_top_regs.f1_error_storage_t\ is record + data : \msk_top_regs.f1_error.data_storage_t\; + end record; + + type \msk_top_regs.f2_error.data_storage_t\ is record + value : std_logic_vector(31 downto 0); + end record; + + type \msk_top_regs.f2_error_storage_t\ is record + data : \msk_top_regs.f2_error.data_storage_t\; + end record; + + type \msk_top_regs.Tx_Sync_Ctrl.tx_sync_ena_storage_t\ is record + value : std_logic; + end record; + + type \msk_top_regs.Tx_Sync_Ctrl.tx_sync_force_storage_t\ is record + value : std_logic; + end record; + + type \msk_top_regs.Tx_Sync_Ctrl_storage_t\ is record + tx_sync_ena : \msk_top_regs.Tx_Sync_Ctrl.tx_sync_ena_storage_t\; + tx_sync_force : \msk_top_regs.Tx_Sync_Ctrl.tx_sync_force_storage_t\; + end record; + + type \msk_top_regs.Tx_Sync_Cnt.tx_sync_cnt_storage_t\ is record + value : std_logic_vector(23 downto 0); + end record; + + type \msk_top_regs.Tx_Sync_Cnt_storage_t\ is record + tx_sync_cnt : \msk_top_regs.Tx_Sync_Cnt.tx_sync_cnt_storage_t\; + end record; + + type \msk_top_regs.lowpass_ema_alpha1.alpha_storage_t\ is record + value : std_logic_vector(17 downto 0); + end record; + + type \msk_top_regs.lowpass_ema_alpha1_storage_t\ is record + alpha : \msk_top_regs.lowpass_ema_alpha1.alpha_storage_t\; + end record; + + type \msk_top_regs.lowpass_ema_alpha2.alpha_storage_t\ is record + value : std_logic_vector(17 downto 0); + end record; + + type \msk_top_regs.lowpass_ema_alpha2_storage_t\ is record + alpha : \msk_top_regs.lowpass_ema_alpha2.alpha_storage_t\; + end record; + + type \msk_top_regs.rx_power.data_storage_t\ is record + value : std_logic_vector(22 downto 0); + end record; + + type \msk_top_regs.rx_power_storage_t\ is record + data : \msk_top_regs.rx_power.data_storage_t\; + end record; + + type \msk_top_regs.tx_async_fifo_rd_wr_ptr.data_storage_t\ is record + value : std_logic_vector(31 downto 0); + end record; + + type \msk_top_regs.tx_async_fifo_rd_wr_ptr_storage_t\ is record + data : \msk_top_regs.tx_async_fifo_rd_wr_ptr.data_storage_t\; + end record; + + type \msk_top_regs.rx_async_fifo_rd_wr_ptr.data_storage_t\ is record + value : std_logic_vector(31 downto 0); + end record; + + type \msk_top_regs.rx_async_fifo_rd_wr_ptr_storage_t\ is record + data : \msk_top_regs.rx_async_fifo_rd_wr_ptr.data_storage_t\; + end record; + + type \msk_top_regs.rx_frame_sync_status.frame_buffer_overflow_storage_t\ is record + value : std_logic; + end record; + + type \msk_top_regs.rx_frame_sync_status.frames_received_storage_t\ is record + value : std_logic_vector(23 downto 0); + end record; + + type \msk_top_regs.rx_frame_sync_status.frame_sync_errors_storage_t\ is record + value : std_logic_vector(5 downto 0); + end record; + + type \msk_top_regs.rx_frame_sync_status_storage_t\ is record + frame_buffer_overflow : \msk_top_regs.rx_frame_sync_status.frame_buffer_overflow_storage_t\; + frames_received : \msk_top_regs.rx_frame_sync_status.frames_received_storage_t\; + frame_sync_errors : \msk_top_regs.rx_frame_sync_status.frame_sync_errors_storage_t\; + end record; + + type field_storage_t is record + MSK_Init : \msk_top_regs.MSK_Init_storage_t\; + MSK_Control : \msk_top_regs.MSK_Control_storage_t\; + Tx_Bit_Count : \msk_top_regs.Tx_Bit_Count_storage_t\; + Tx_Enable_Count : \msk_top_regs.Tx_Enable_Count_storage_t\; + Fb_FreqWord : \msk_top_regs.Fb_FreqWord_storage_t\; + TX_F1_FreqWord : \msk_top_regs.TX_F1_FreqWord_storage_t\; + TX_F2_FreqWord : \msk_top_regs.TX_F2_FreqWord_storage_t\; + RX_F1_FreqWord : \msk_top_regs.RX_F1_FreqWord_storage_t\; + RX_F2_FreqWord : \msk_top_regs.RX_F2_FreqWord_storage_t\; + LPF_Config_0 : \msk_top_regs.LPF_Config_0_storage_t\; + LPF_Config_1 : \msk_top_regs.LPF_Config_1_storage_t\; + Tx_Data_Width : \msk_top_regs.Tx_Data_Width_storage_t\; + Rx_Data_Width : \msk_top_regs.Rx_Data_Width_storage_t\; + PRBS_Control : \msk_top_regs.PRBS_Control_storage_t\; + PRBS_Initial_State : \msk_top_regs.PRBS_Initial_State_storage_t\; + PRBS_Polynomial : \msk_top_regs.PRBS_Polynomial_storage_t\; + PRBS_Error_Mask : \msk_top_regs.PRBS_Error_Mask_storage_t\; + PRBS_Bit_Count : \msk_top_regs.PRBS_Bit_Count_storage_t\; + PRBS_Error_Count : \msk_top_regs.PRBS_Error_Count_storage_t\; + LPF_Accum_F1 : \msk_top_regs.LPF_Accum_F1_storage_t\; + LPF_Accum_F2 : \msk_top_regs.LPF_Accum_F2_storage_t\; + axis_xfer_count : \msk_top_regs.axis_xfer_count_storage_t\; + Rx_Sample_Discard : \msk_top_regs.Rx_Sample_Discard_storage_t\; + LPF_Config_2 : \msk_top_regs.LPF_Config_2_storage_t\; + f1_nco_adjust : \msk_top_regs.f1_nco_adjust_storage_t\; + f2_nco_adjust : \msk_top_regs.f2_nco_adjust_storage_t\; + f1_error : \msk_top_regs.f1_error_storage_t\; + f2_error : \msk_top_regs.f2_error_storage_t\; + Tx_Sync_Ctrl : \msk_top_regs.Tx_Sync_Ctrl_storage_t\; + Tx_Sync_Cnt : \msk_top_regs.Tx_Sync_Cnt_storage_t\; + lowpass_ema_alpha1 : \msk_top_regs.lowpass_ema_alpha1_storage_t\; + lowpass_ema_alpha2 : \msk_top_regs.lowpass_ema_alpha2_storage_t\; + rx_power : \msk_top_regs.rx_power_storage_t\; + tx_async_fifo_rd_wr_ptr : \msk_top_regs.tx_async_fifo_rd_wr_ptr_storage_t\; + rx_async_fifo_rd_wr_ptr : \msk_top_regs.rx_async_fifo_rd_wr_ptr_storage_t\; + rx_frame_sync_status : \msk_top_regs.rx_frame_sync_status_storage_t\; + end record; + signal field_storage : field_storage_t; + + ---------------------------------------------------------------------------- + -- Readback Signals + ---------------------------------------------------------------------------- + signal readback_err : std_logic; + signal readback_done : std_logic; + signal readback_data : std_logic_vector(31 downto 0); + signal readback_array : std_logic_vector_array1(0 to 38)(31 downto 0); + +begin + + ---------------------------------------------------------------------------- + -- CPU Bus interface + ---------------------------------------------------------------------------- + -- pragma translate_off + cpuif_generics: process begin + assert_bad_addr_width: assert s_axil_i.ARADDR'length >= MSK_TOP_REGS_MIN_ADDR_WIDTH + report "Interface address width of " & integer'image(s_axil_i.ARADDR'length) & " is too small. Shall be at least " & integer'image(MSK_TOP_REGS_MIN_ADDR_WIDTH) & " bits" + severity failure; + assert_bad_data_width: assert s_axil_i.WDATA'length = MSK_TOP_REGS_DATA_WIDTH + report "Interface data width of " & integer'image(s_axil_i.WDATA'length) & " is incorrect. Shall be " & integer'image(MSK_TOP_REGS_DATA_WIDTH) & " bits" + severity failure; + wait; + end process; + -- pragma translate_on + + + -- Max Outstanding Transactions: 2 + -- Transaction request acceptance + process(clk) begin + if false then -- async reset + axil_prev_was_rd <= '0'; + axil_arvalid <= '0'; + axil_araddr <= (others => '0'); + axil_awvalid <= '0'; + axil_awaddr <= (others => '0'); + axil_wvalid <= '0'; + axil_wdata <= (others => '0'); + axil_wstrb <= (others => '0'); + axil_n_in_flight <= (others => '0'); + elsif rising_edge(clk) then + if rst then -- sync reset + axil_prev_was_rd <= '0'; + axil_arvalid <= '0'; + axil_araddr <= (others => '0'); + axil_awvalid <= '0'; + axil_awaddr <= (others => '0'); + axil_wvalid <= '0'; + axil_wdata <= (others => '0'); + axil_wstrb <= (others => '0'); + axil_n_in_flight <= (others => '0'); + else + -- AR* acceptance register + if axil_ar_accept then + axil_prev_was_rd <= '1'; + axil_arvalid <= '0'; + end if; + if s_axil_i.ARVALID and s_axil_o.ARREADY then + axil_arvalid <= '1'; + axil_araddr <= s_axil_i.ARADDR; + end if; + + -- AW* & W* acceptance registers + if axil_aw_accept then + axil_prev_was_rd <= '0'; + axil_awvalid <= '0'; + axil_wvalid <= '0'; + end if; + if s_axil_i.AWVALID and s_axil_o.AWREADY then + axil_awvalid <= '1'; + axil_awaddr <= s_axil_i.AWADDR; + end if; + if s_axil_i.WVALID and s_axil_o.WREADY then + axil_wvalid <= '1'; + axil_wdata <= s_axil_i.WDATA; + axil_wstrb <= s_axil_i.WSTRB; + end if; + + -- Keep track of in-flight transactions + if (axil_ar_accept or axil_aw_accept) and not axil_resp_acked then + axil_n_in_flight <= axil_n_in_flight + 1; + elsif not (axil_ar_accept or axil_aw_accept) and axil_resp_acked then + axil_n_in_flight <= axil_n_in_flight - 1; + end if; + end if; + end if; + end process; + + process(all) begin + s_axil_o.ARREADY <= not axil_arvalid or axil_ar_accept; + s_axil_o.AWREADY <= not axil_awvalid or axil_aw_accept; + s_axil_o.WREADY <= not axil_wvalid or axil_aw_accept; + end process; + + -- Request dispatch + process(all) begin + cpuif_wr_data <= axil_wdata; + for i in axil_wstrb'RANGE loop + cpuif_wr_biten(i*8 + 7 downto i*8) <= (others => axil_wstrb(i)); + end loop; + cpuif_req <= '0'; + cpuif_req_is_wr <= '0'; + cpuif_addr <= (others => '0'); + axil_ar_accept <= '0'; + axil_aw_accept <= '0'; + + if axil_n_in_flight < to_unsigned(2, 2) then + -- Can safely issue more transactions without overwhelming response buffer + if axil_arvalid and not axil_prev_was_rd then + cpuif_req <= '1'; + cpuif_req_is_wr <= '0'; + cpuif_addr <= (7 downto 2 => axil_araddr(7 downto 2), others => '0'); + if not cpuif_req_stall_rd then + axil_ar_accept <= '1'; + end if; + elsif axil_awvalid and axil_wvalid then + cpuif_req <= '1'; + cpuif_req_is_wr <= '1'; + cpuif_addr <= (7 downto 2 => axil_awaddr(7 downto 2), others => '0'); + if not cpuif_req_stall_wr then + axil_aw_accept <= '1'; + end if; + elsif axil_arvalid then + cpuif_req <= '1'; + cpuif_req_is_wr <= '0'; + cpuif_addr <= (7 downto 2 => axil_araddr(7 downto 2), others => '0'); + if not cpuif_req_stall_rd then + axil_ar_accept <= '1'; + end if; + end if; + end if; + end process; + -- AXI4-Lite Response Logic + process(clk) begin + if false then -- async reset + for i in axil_resp_buffer'RANGE loop + axil_resp_buffer(i).is_wr <= '0'; + axil_resp_buffer(i).err <= '0'; + axil_resp_buffer(i).rdata <= (others => '0'); + end loop; + axil_resp_wptr <= (others => '0'); + axil_resp_rptr <= (others => '0'); + elsif rising_edge(clk) then + if rst then -- sync reset + for i in axil_resp_buffer'RANGE loop + axil_resp_buffer(i).is_wr <= '0'; + axil_resp_buffer(i).err <= '0'; + axil_resp_buffer(i).rdata <= (others => '0'); + end loop; + axil_resp_wptr <= (others => '0'); + axil_resp_rptr <= (others => '0'); + else + -- Store responses in buffer until AXI response channel accepts them + if cpuif_rd_ack or cpuif_wr_ack then + if cpuif_rd_ack then + axil_resp_buffer(to_integer(axil_resp_wptr(0 downto 0))).is_wr <= '0'; + axil_resp_buffer(to_integer(axil_resp_wptr(0 downto 0))).err <= cpuif_rd_err; + axil_resp_buffer(to_integer(axil_resp_wptr(0 downto 0))).rdata <= cpuif_rd_data; + + elsif cpuif_wr_ack then + axil_resp_buffer(to_integer(axil_resp_wptr(0 downto 0))).is_wr <= '1'; + axil_resp_buffer(to_integer(axil_resp_wptr(0 downto 0))).err <= cpuif_wr_err; + end if; + axil_resp_wptr <= axil_resp_wptr + 1; + end if; + + -- Advance read pointer when acknowledged + if axil_resp_acked then + axil_resp_rptr <= axil_resp_rptr + 1; + end if; + end if; + end if; + end process; + + process(all) begin + axil_resp_acked <= '0'; + s_axil_o.BVALID <= '0'; + s_axil_o.RVALID <= '0'; + if axil_resp_rptr /= axil_resp_wptr then + if axil_resp_buffer(to_integer(axil_resp_rptr(0 downto 0))).is_wr then + s_axil_o.BVALID <= '1'; + if s_axil_i.BREADY then + axil_resp_acked <= '1'; + end if; + else + s_axil_o.RVALID <= '1'; + if s_axil_i.RREADY then + axil_resp_acked <= '1'; + end if; + end if; + end if; + + s_axil_o.RDATA <= axil_resp_buffer(to_integer(axil_resp_rptr(0 downto 0))).rdata; + if axil_resp_buffer(to_integer(axil_resp_rptr(0 downto 0))).err then + s_axil_o.BRESP <= "10"; + s_axil_o.RRESP <= "10"; + else + s_axil_o.BRESP <= "00"; + s_axil_o.RRESP <= "00"; + end if; + end process; + + -- Read & write latencies are balanced. Stalls not required + cpuif_req_stall_rd <= '0'; + cpuif_req_stall_wr <= '0'; + cpuif_req_masked <= cpuif_req + and not (not cpuif_req_is_wr and cpuif_req_stall_rd) + and not (cpuif_req_is_wr and cpuif_req_stall_wr); + + ---------------------------------------------------------------------------- + -- Address Decode + ---------------------------------------------------------------------------- + process(all) + -- overload "=" in this scope to avoid lots of type casts + function "="(L: std_logic_vector; R: integer) return std_logic is + variable result : std_logic; + begin + result := '1' when unsigned(L) = R else '0'; + return result; + end; + begin + decoded_reg_strb.Hash_ID_Low <= cpuif_req_masked and (cpuif_addr = 16#0#); + decoded_reg_strb.Hash_ID_High <= cpuif_req_masked and (cpuif_addr = 16#4#); + decoded_reg_strb.MSK_Init <= cpuif_req_masked and (cpuif_addr = 16#8#); + decoded_reg_strb.MSK_Control <= cpuif_req_masked and (cpuif_addr = 16#C#); + decoded_reg_strb.MSK_Status <= cpuif_req_masked and (cpuif_addr = 16#10#); + decoded_reg_strb.Tx_Bit_Count <= cpuif_req_masked and (cpuif_addr = 16#14#); + decoded_reg_strb.Tx_Enable_Count <= cpuif_req_masked and (cpuif_addr = 16#18#); + decoded_reg_strb.Fb_FreqWord <= cpuif_req_masked and (cpuif_addr = 16#1C#); + decoded_reg_strb.TX_F1_FreqWord <= cpuif_req_masked and (cpuif_addr = 16#20#); + decoded_reg_strb.TX_F2_FreqWord <= cpuif_req_masked and (cpuif_addr = 16#24#); + decoded_reg_strb.RX_F1_FreqWord <= cpuif_req_masked and (cpuif_addr = 16#28#); + decoded_reg_strb.RX_F2_FreqWord <= cpuif_req_masked and (cpuif_addr = 16#2C#); + decoded_reg_strb.LPF_Config_0 <= cpuif_req_masked and (cpuif_addr = 16#30#); + decoded_reg_strb.LPF_Config_1 <= cpuif_req_masked and (cpuif_addr = 16#34#); + decoded_reg_strb.Tx_Data_Width <= cpuif_req_masked and (cpuif_addr = 16#38#); + decoded_reg_strb.Rx_Data_Width <= cpuif_req_masked and (cpuif_addr = 16#3C#); + decoded_reg_strb.PRBS_Control <= cpuif_req_masked and (cpuif_addr = 16#40#); + decoded_reg_strb.PRBS_Initial_State <= cpuif_req_masked and (cpuif_addr = 16#44#); + decoded_reg_strb.PRBS_Polynomial <= cpuif_req_masked and (cpuif_addr = 16#48#); + decoded_reg_strb.PRBS_Error_Mask <= cpuif_req_masked and (cpuif_addr = 16#4C#); + decoded_reg_strb.PRBS_Bit_Count <= cpuif_req_masked and (cpuif_addr = 16#50#); + decoded_reg_strb.PRBS_Error_Count <= cpuif_req_masked and (cpuif_addr = 16#54#); + decoded_reg_strb.LPF_Accum_F1 <= cpuif_req_masked and (cpuif_addr = 16#58#); + decoded_reg_strb.LPF_Accum_F2 <= cpuif_req_masked and (cpuif_addr = 16#5C#); + decoded_reg_strb.axis_xfer_count <= cpuif_req_masked and (cpuif_addr = 16#60#); + decoded_reg_strb.Rx_Sample_Discard <= cpuif_req_masked and (cpuif_addr = 16#64#); + decoded_reg_strb.LPF_Config_2 <= cpuif_req_masked and (cpuif_addr = 16#68#); + decoded_reg_strb.f1_nco_adjust <= cpuif_req_masked and (cpuif_addr = 16#6C#); + decoded_reg_strb.f2_nco_adjust <= cpuif_req_masked and (cpuif_addr = 16#70#); + decoded_reg_strb.f1_error <= cpuif_req_masked and (cpuif_addr = 16#74#); + decoded_reg_strb.f2_error <= cpuif_req_masked and (cpuif_addr = 16#78#); + decoded_reg_strb.Tx_Sync_Ctrl <= cpuif_req_masked and (cpuif_addr = 16#7C#); + decoded_reg_strb.Tx_Sync_Cnt <= cpuif_req_masked and (cpuif_addr = 16#80#); + decoded_reg_strb.lowpass_ema_alpha1 <= cpuif_req_masked and (cpuif_addr = 16#84#); + decoded_reg_strb.lowpass_ema_alpha2 <= cpuif_req_masked and (cpuif_addr = 16#88#); + decoded_reg_strb.rx_power <= cpuif_req_masked and (cpuif_addr = 16#8C#); + decoded_reg_strb.tx_async_fifo_rd_wr_ptr <= cpuif_req_masked and (cpuif_addr = 16#90#); + decoded_reg_strb.rx_async_fifo_rd_wr_ptr <= cpuif_req_masked and (cpuif_addr = 16#94#); + decoded_reg_strb.rx_frame_sync_status <= cpuif_req_masked and (cpuif_addr = 16#98#); + end process; + + -- Pass down signals to next stage + process(all) begin + decoded_req <= cpuif_req_masked; + decoded_req_is_wr <= cpuif_req_is_wr; + decoded_wr_data <= cpuif_wr_data; + decoded_wr_biten <= cpuif_wr_biten; + end process; + + ---------------------------------------------------------------------------- + -- Field logic + ---------------------------------------------------------------------------- + + -- Field: msk_top_regs.MSK_Init.txrxinit + process(all) + variable next_c: std_logic; + variable load_next_c: std_logic; + begin + next_c := field_storage.MSK_Init.txrxinit.value; + load_next_c := '0'; + if decoded_reg_strb.MSK_Init and decoded_req_is_wr then -- SW write + next_c := (field_storage.MSK_Init.txrxinit.value and not decoded_wr_biten(0)) or (decoded_wr_data(0) and decoded_wr_biten(0)); + load_next_c := '1'; + end if; + field_combo.MSK_Init.txrxinit.next_q <= next_c; + field_combo.MSK_Init.txrxinit.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.MSK_Init.txrxinit.value <= '1'; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.MSK_Init.txrxinit.value <= '1'; + else + if field_combo.MSK_Init.txrxinit.load_next then + field_storage.MSK_Init.txrxinit.value <= field_combo.MSK_Init.txrxinit.next_q; + end if; + end if; + end if; + end process; + hwif_out.MSK_Init.txrxinit.value <= field_storage.MSK_Init.txrxinit.value; + + -- Field: msk_top_regs.MSK_Init.txinit + process(all) + variable next_c: std_logic; + variable load_next_c: std_logic; + begin + next_c := field_storage.MSK_Init.txinit.value; + load_next_c := '0'; + if decoded_reg_strb.MSK_Init and decoded_req_is_wr then -- SW write + next_c := (field_storage.MSK_Init.txinit.value and not decoded_wr_biten(1)) or (decoded_wr_data(1) and decoded_wr_biten(1)); + load_next_c := '1'; + end if; + field_combo.MSK_Init.txinit.next_q <= next_c; + field_combo.MSK_Init.txinit.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.MSK_Init.txinit.value <= '1'; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.MSK_Init.txinit.value <= '1'; + else + if field_combo.MSK_Init.txinit.load_next then + field_storage.MSK_Init.txinit.value <= field_combo.MSK_Init.txinit.next_q; + end if; + end if; + end if; + end process; + hwif_out.MSK_Init.txinit.value <= field_storage.MSK_Init.txinit.value; + + -- Field: msk_top_regs.MSK_Init.rxinit + process(all) + variable next_c: std_logic; + variable load_next_c: std_logic; + begin + next_c := field_storage.MSK_Init.rxinit.value; + load_next_c := '0'; + if decoded_reg_strb.MSK_Init and decoded_req_is_wr then -- SW write + next_c := (field_storage.MSK_Init.rxinit.value and not decoded_wr_biten(2)) or (decoded_wr_data(2) and decoded_wr_biten(2)); + load_next_c := '1'; + end if; + field_combo.MSK_Init.rxinit.next_q <= next_c; + field_combo.MSK_Init.rxinit.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.MSK_Init.rxinit.value <= '1'; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.MSK_Init.rxinit.value <= '1'; + else + if field_combo.MSK_Init.rxinit.load_next then + field_storage.MSK_Init.rxinit.value <= field_combo.MSK_Init.rxinit.next_q; + end if; + end if; + end if; + end process; + hwif_out.MSK_Init.rxinit.value <= field_storage.MSK_Init.rxinit.value; + + -- Field: msk_top_regs.MSK_Control.ptt + process(all) + variable next_c: std_logic; + variable load_next_c: std_logic; + begin + next_c := field_storage.MSK_Control.ptt.value; + load_next_c := '0'; + if decoded_reg_strb.MSK_Control and decoded_req_is_wr then -- SW write + next_c := (field_storage.MSK_Control.ptt.value and not decoded_wr_biten(0)) or (decoded_wr_data(0) and decoded_wr_biten(0)); + load_next_c := '1'; + end if; + field_combo.MSK_Control.ptt.next_q <= next_c; + field_combo.MSK_Control.ptt.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.MSK_Control.ptt.value <= '0'; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.MSK_Control.ptt.value <= '0'; + else + if field_combo.MSK_Control.ptt.load_next then + field_storage.MSK_Control.ptt.value <= field_combo.MSK_Control.ptt.next_q; + end if; + end if; + end if; + end process; + hwif_out.MSK_Control.ptt.value <= field_storage.MSK_Control.ptt.value; + + -- Field: msk_top_regs.MSK_Control.loopback_ena + process(all) + variable next_c: std_logic; + variable load_next_c: std_logic; + begin + next_c := field_storage.MSK_Control.loopback_ena.value; + load_next_c := '0'; + if decoded_reg_strb.MSK_Control and decoded_req_is_wr then -- SW write + next_c := (field_storage.MSK_Control.loopback_ena.value and not decoded_wr_biten(1)) or (decoded_wr_data(1) and decoded_wr_biten(1)); + load_next_c := '1'; + end if; + field_combo.MSK_Control.loopback_ena.next_q <= next_c; + field_combo.MSK_Control.loopback_ena.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.MSK_Control.loopback_ena.value <= '0'; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.MSK_Control.loopback_ena.value <= '0'; + else + if field_combo.MSK_Control.loopback_ena.load_next then + field_storage.MSK_Control.loopback_ena.value <= field_combo.MSK_Control.loopback_ena.next_q; + end if; + end if; + end if; + end process; + hwif_out.MSK_Control.loopback_ena.value <= field_storage.MSK_Control.loopback_ena.value; + + -- Field: msk_top_regs.MSK_Control.rx_invert + process(all) + variable next_c: std_logic; + variable load_next_c: std_logic; + begin + next_c := field_storage.MSK_Control.rx_invert.value; + load_next_c := '0'; + if decoded_reg_strb.MSK_Control and decoded_req_is_wr then -- SW write + next_c := (field_storage.MSK_Control.rx_invert.value and not decoded_wr_biten(2)) or (decoded_wr_data(2) and decoded_wr_biten(2)); + load_next_c := '1'; + end if; + field_combo.MSK_Control.rx_invert.next_q <= next_c; + field_combo.MSK_Control.rx_invert.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.MSK_Control.rx_invert.value <= '0'; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.MSK_Control.rx_invert.value <= '0'; + else + if field_combo.MSK_Control.rx_invert.load_next then + field_storage.MSK_Control.rx_invert.value <= field_combo.MSK_Control.rx_invert.next_q; + end if; + end if; + end if; + end process; + hwif_out.MSK_Control.rx_invert.value <= field_storage.MSK_Control.rx_invert.value; + + -- Field: msk_top_regs.MSK_Control.clear_counts + process(all) + variable next_c: std_logic; + variable load_next_c: std_logic; + begin + next_c := field_storage.MSK_Control.clear_counts.value; + load_next_c := '0'; + if decoded_reg_strb.MSK_Control and decoded_req_is_wr then -- SW write + next_c := (field_storage.MSK_Control.clear_counts.value and not decoded_wr_biten(3)) or (decoded_wr_data(3) and decoded_wr_biten(3)); + load_next_c := '1'; + else -- singlepulse clears back to 0 + next_c := '0'; + load_next_c := '1'; + end if; + field_combo.MSK_Control.clear_counts.next_q <= next_c; + field_combo.MSK_Control.clear_counts.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.MSK_Control.clear_counts.value <= '0'; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.MSK_Control.clear_counts.value <= '0'; + else + if field_combo.MSK_Control.clear_counts.load_next then + field_storage.MSK_Control.clear_counts.value <= field_combo.MSK_Control.clear_counts.next_q; + end if; + end if; + end if; + end process; + hwif_out.MSK_Control.clear_counts.value <= field_storage.MSK_Control.clear_counts.value; + + -- Field: msk_top_regs.MSK_Control.diff_encoder_loopback + process(all) + variable next_c: std_logic; + variable load_next_c: std_logic; + begin + next_c := field_storage.MSK_Control.diff_encoder_loopback.value; + load_next_c := '0'; + if decoded_reg_strb.MSK_Control and decoded_req_is_wr then -- SW write + next_c := (field_storage.MSK_Control.diff_encoder_loopback.value and not decoded_wr_biten(4)) or (decoded_wr_data(4) and decoded_wr_biten(4)); + load_next_c := '1'; + end if; + field_combo.MSK_Control.diff_encoder_loopback.next_q <= next_c; + field_combo.MSK_Control.diff_encoder_loopback.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.MSK_Control.diff_encoder_loopback.value <= '0'; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.MSK_Control.diff_encoder_loopback.value <= '0'; + else + if field_combo.MSK_Control.diff_encoder_loopback.load_next then + field_storage.MSK_Control.diff_encoder_loopback.value <= field_combo.MSK_Control.diff_encoder_loopback.next_q; + end if; + end if; + end if; + end process; + hwif_out.MSK_Control.diff_encoder_loopback.value <= field_storage.MSK_Control.diff_encoder_loopback.value; + + -- Field: msk_top_regs.Tx_Bit_Count.data + process(all) + variable next_c: std_logic_vector(31 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.Tx_Bit_Count.data.value; + load_next_c := '0'; + if decoded_reg_strb.Tx_Bit_Count and decoded_req_is_wr then -- SW write + next_c := (field_storage.Tx_Bit_Count.data.value and not decoded_wr_biten(31 downto 0)) or (decoded_wr_data(31 downto 0) and decoded_wr_biten(31 downto 0)); + load_next_c := '1'; + elsif hwif_in.Tx_Bit_Count.data.we then -- HW Write - we + next_c := hwif_in.Tx_Bit_Count.data.next_q; + load_next_c := '1'; + end if; + field_combo.Tx_Bit_Count.data.next_q <= next_c; + field_combo.Tx_Bit_Count.data.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.Tx_Bit_Count.data.value <= 32x"0"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.Tx_Bit_Count.data.value <= 32x"0"; + else + if field_combo.Tx_Bit_Count.data.load_next then + field_storage.Tx_Bit_Count.data.value <= field_combo.Tx_Bit_Count.data.next_q; + end if; + end if; + end if; + end process; + hwif_out.Tx_Bit_Count.data.swmod <= decoded_reg_strb.Tx_Bit_Count and decoded_req_is_wr and or_reduce(decoded_wr_biten(31 downto 0)); + + -- Field: msk_top_regs.Tx_Enable_Count.data + process(all) + variable next_c: std_logic_vector(31 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.Tx_Enable_Count.data.value; + load_next_c := '0'; + if decoded_reg_strb.Tx_Enable_Count and decoded_req_is_wr then -- SW write + next_c := (field_storage.Tx_Enable_Count.data.value and not decoded_wr_biten(31 downto 0)) or (decoded_wr_data(31 downto 0) and decoded_wr_biten(31 downto 0)); + load_next_c := '1'; + elsif hwif_in.Tx_Enable_Count.data.we then -- HW Write - we + next_c := hwif_in.Tx_Enable_Count.data.next_q; + load_next_c := '1'; + end if; + field_combo.Tx_Enable_Count.data.next_q <= next_c; + field_combo.Tx_Enable_Count.data.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.Tx_Enable_Count.data.value <= 32x"0"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.Tx_Enable_Count.data.value <= 32x"0"; + else + if field_combo.Tx_Enable_Count.data.load_next then + field_storage.Tx_Enable_Count.data.value <= field_combo.Tx_Enable_Count.data.next_q; + end if; + end if; + end if; + end process; + hwif_out.Tx_Enable_Count.data.swmod <= decoded_reg_strb.Tx_Enable_Count and decoded_req_is_wr and or_reduce(decoded_wr_biten(31 downto 0)); + + -- Field: msk_top_regs.Fb_FreqWord.config_data + process(all) + variable next_c: std_logic_vector(31 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.Fb_FreqWord.config_data.value; + load_next_c := '0'; + if decoded_reg_strb.Fb_FreqWord and decoded_req_is_wr then -- SW write + next_c := (field_storage.Fb_FreqWord.config_data.value and not decoded_wr_biten(31 downto 0)) or (decoded_wr_data(31 downto 0) and decoded_wr_biten(31 downto 0)); + load_next_c := '1'; + end if; + field_combo.Fb_FreqWord.config_data.next_q <= next_c; + field_combo.Fb_FreqWord.config_data.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.Fb_FreqWord.config_data.value <= 32x"0"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.Fb_FreqWord.config_data.value <= 32x"0"; + else + if field_combo.Fb_FreqWord.config_data.load_next then + field_storage.Fb_FreqWord.config_data.value <= field_combo.Fb_FreqWord.config_data.next_q; + end if; + end if; + end if; + end process; + hwif_out.Fb_FreqWord.config_data.value <= field_storage.Fb_FreqWord.config_data.value; + + -- Field: msk_top_regs.TX_F1_FreqWord.config_data + process(all) + variable next_c: std_logic_vector(31 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.TX_F1_FreqWord.config_data.value; + load_next_c := '0'; + if decoded_reg_strb.TX_F1_FreqWord and decoded_req_is_wr then -- SW write + next_c := (field_storage.TX_F1_FreqWord.config_data.value and not decoded_wr_biten(31 downto 0)) or (decoded_wr_data(31 downto 0) and decoded_wr_biten(31 downto 0)); + load_next_c := '1'; + end if; + field_combo.TX_F1_FreqWord.config_data.next_q <= next_c; + field_combo.TX_F1_FreqWord.config_data.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.TX_F1_FreqWord.config_data.value <= 32x"0"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.TX_F1_FreqWord.config_data.value <= 32x"0"; + else + if field_combo.TX_F1_FreqWord.config_data.load_next then + field_storage.TX_F1_FreqWord.config_data.value <= field_combo.TX_F1_FreqWord.config_data.next_q; + end if; + end if; + end if; + end process; + hwif_out.TX_F1_FreqWord.config_data.value <= field_storage.TX_F1_FreqWord.config_data.value; + + -- Field: msk_top_regs.TX_F2_FreqWord.config_data + process(all) + variable next_c: std_logic_vector(31 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.TX_F2_FreqWord.config_data.value; + load_next_c := '0'; + if decoded_reg_strb.TX_F2_FreqWord and decoded_req_is_wr then -- SW write + next_c := (field_storage.TX_F2_FreqWord.config_data.value and not decoded_wr_biten(31 downto 0)) or (decoded_wr_data(31 downto 0) and decoded_wr_biten(31 downto 0)); + load_next_c := '1'; + end if; + field_combo.TX_F2_FreqWord.config_data.next_q <= next_c; + field_combo.TX_F2_FreqWord.config_data.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.TX_F2_FreqWord.config_data.value <= 32x"0"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.TX_F2_FreqWord.config_data.value <= 32x"0"; + else + if field_combo.TX_F2_FreqWord.config_data.load_next then + field_storage.TX_F2_FreqWord.config_data.value <= field_combo.TX_F2_FreqWord.config_data.next_q; + end if; + end if; + end if; + end process; + hwif_out.TX_F2_FreqWord.config_data.value <= field_storage.TX_F2_FreqWord.config_data.value; + + -- Field: msk_top_regs.RX_F1_FreqWord.config_data + process(all) + variable next_c: std_logic_vector(31 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.RX_F1_FreqWord.config_data.value; + load_next_c := '0'; + if decoded_reg_strb.RX_F1_FreqWord and decoded_req_is_wr then -- SW write + next_c := (field_storage.RX_F1_FreqWord.config_data.value and not decoded_wr_biten(31 downto 0)) or (decoded_wr_data(31 downto 0) and decoded_wr_biten(31 downto 0)); + load_next_c := '1'; + end if; + field_combo.RX_F1_FreqWord.config_data.next_q <= next_c; + field_combo.RX_F1_FreqWord.config_data.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.RX_F1_FreqWord.config_data.value <= 32x"0"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.RX_F1_FreqWord.config_data.value <= 32x"0"; + else + if field_combo.RX_F1_FreqWord.config_data.load_next then + field_storage.RX_F1_FreqWord.config_data.value <= field_combo.RX_F1_FreqWord.config_data.next_q; + end if; + end if; + end if; + end process; + hwif_out.RX_F1_FreqWord.config_data.value <= field_storage.RX_F1_FreqWord.config_data.value; + + -- Field: msk_top_regs.RX_F2_FreqWord.config_data + process(all) + variable next_c: std_logic_vector(31 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.RX_F2_FreqWord.config_data.value; + load_next_c := '0'; + if decoded_reg_strb.RX_F2_FreqWord and decoded_req_is_wr then -- SW write + next_c := (field_storage.RX_F2_FreqWord.config_data.value and not decoded_wr_biten(31 downto 0)) or (decoded_wr_data(31 downto 0) and decoded_wr_biten(31 downto 0)); + load_next_c := '1'; + end if; + field_combo.RX_F2_FreqWord.config_data.next_q <= next_c; + field_combo.RX_F2_FreqWord.config_data.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.RX_F2_FreqWord.config_data.value <= 32x"0"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.RX_F2_FreqWord.config_data.value <= 32x"0"; + else + if field_combo.RX_F2_FreqWord.config_data.load_next then + field_storage.RX_F2_FreqWord.config_data.value <= field_combo.RX_F2_FreqWord.config_data.next_q; + end if; + end if; + end if; + end process; + hwif_out.RX_F2_FreqWord.config_data.value <= field_storage.RX_F2_FreqWord.config_data.value; + + -- Field: msk_top_regs.LPF_Config_0.lpf_freeze + process(all) + variable next_c: std_logic; + variable load_next_c: std_logic; + begin + next_c := field_storage.LPF_Config_0.lpf_freeze.value; + load_next_c := '0'; + if decoded_reg_strb.LPF_Config_0 and decoded_req_is_wr then -- SW write + next_c := (field_storage.LPF_Config_0.lpf_freeze.value and not decoded_wr_biten(0)) or (decoded_wr_data(0) and decoded_wr_biten(0)); + load_next_c := '1'; + end if; + field_combo.LPF_Config_0.lpf_freeze.next_q <= next_c; + field_combo.LPF_Config_0.lpf_freeze.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.LPF_Config_0.lpf_freeze.value <= '0'; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.LPF_Config_0.lpf_freeze.value <= '0'; + else + if field_combo.LPF_Config_0.lpf_freeze.load_next then + field_storage.LPF_Config_0.lpf_freeze.value <= field_combo.LPF_Config_0.lpf_freeze.next_q; + end if; + end if; + end if; + end process; + hwif_out.LPF_Config_0.lpf_freeze.value <= field_storage.LPF_Config_0.lpf_freeze.value; + + -- Field: msk_top_regs.LPF_Config_0.lpf_zero + process(all) + variable next_c: std_logic; + variable load_next_c: std_logic; + begin + next_c := field_storage.LPF_Config_0.lpf_zero.value; + load_next_c := '0'; + if decoded_reg_strb.LPF_Config_0 and decoded_req_is_wr then -- SW write + next_c := (field_storage.LPF_Config_0.lpf_zero.value and not decoded_wr_biten(1)) or (decoded_wr_data(1) and decoded_wr_biten(1)); + load_next_c := '1'; + end if; + field_combo.LPF_Config_0.lpf_zero.next_q <= next_c; + field_combo.LPF_Config_0.lpf_zero.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.LPF_Config_0.lpf_zero.value <= '0'; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.LPF_Config_0.lpf_zero.value <= '0'; + else + if field_combo.LPF_Config_0.lpf_zero.load_next then + field_storage.LPF_Config_0.lpf_zero.value <= field_combo.LPF_Config_0.lpf_zero.next_q; + end if; + end if; + end if; + end process; + hwif_out.LPF_Config_0.lpf_zero.value <= field_storage.LPF_Config_0.lpf_zero.value; + + -- Field: msk_top_regs.LPF_Config_0.prbs_reserved + process(all) + variable next_c: std_logic_vector(5 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.LPF_Config_0.prbs_reserved.value; + load_next_c := '0'; + if decoded_reg_strb.LPF_Config_0 and decoded_req_is_wr then -- SW write + next_c := (field_storage.LPF_Config_0.prbs_reserved.value and not decoded_wr_biten(7 downto 2)) or (decoded_wr_data(7 downto 2) and decoded_wr_biten(7 downto 2)); + load_next_c := '1'; + end if; + field_combo.LPF_Config_0.prbs_reserved.next_q <= next_c; + field_combo.LPF_Config_0.prbs_reserved.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.LPF_Config_0.prbs_reserved.value <= 6x"0"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.LPF_Config_0.prbs_reserved.value <= 6x"0"; + else + if field_combo.LPF_Config_0.prbs_reserved.load_next then + field_storage.LPF_Config_0.prbs_reserved.value <= field_combo.LPF_Config_0.prbs_reserved.next_q; + end if; + end if; + end if; + end process; + hwif_out.LPF_Config_0.prbs_reserved.value <= field_storage.LPF_Config_0.prbs_reserved.value; + + -- Field: msk_top_regs.LPF_Config_0.lpf_alpha + process(all) + variable next_c: std_logic_vector(23 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.LPF_Config_0.lpf_alpha.value; + load_next_c := '0'; + if decoded_reg_strb.LPF_Config_0 and decoded_req_is_wr then -- SW write + next_c := (field_storage.LPF_Config_0.lpf_alpha.value and not decoded_wr_biten(31 downto 8)) or (decoded_wr_data(31 downto 8) and decoded_wr_biten(31 downto 8)); + load_next_c := '1'; + end if; + field_combo.LPF_Config_0.lpf_alpha.next_q <= next_c; + field_combo.LPF_Config_0.lpf_alpha.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.LPF_Config_0.lpf_alpha.value <= 24x"0"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.LPF_Config_0.lpf_alpha.value <= 24x"0"; + else + if field_combo.LPF_Config_0.lpf_alpha.load_next then + field_storage.LPF_Config_0.lpf_alpha.value <= field_combo.LPF_Config_0.lpf_alpha.next_q; + end if; + end if; + end if; + end process; + hwif_out.LPF_Config_0.lpf_alpha.value <= field_storage.LPF_Config_0.lpf_alpha.value; + + -- Field: msk_top_regs.LPF_Config_1.i_gain + process(all) + variable next_c: std_logic_vector(23 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.LPF_Config_1.i_gain.value; + load_next_c := '0'; + if decoded_reg_strb.LPF_Config_1 and decoded_req_is_wr then -- SW write + next_c := (field_storage.LPF_Config_1.i_gain.value and not decoded_wr_biten(23 downto 0)) or (decoded_wr_data(23 downto 0) and decoded_wr_biten(23 downto 0)); + load_next_c := '1'; + end if; + field_combo.LPF_Config_1.i_gain.next_q <= next_c; + field_combo.LPF_Config_1.i_gain.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.LPF_Config_1.i_gain.value <= 24x"0"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.LPF_Config_1.i_gain.value <= 24x"0"; + else + if field_combo.LPF_Config_1.i_gain.load_next then + field_storage.LPF_Config_1.i_gain.value <= field_combo.LPF_Config_1.i_gain.next_q; + end if; + end if; + end if; + end process; + hwif_out.LPF_Config_1.i_gain.value <= field_storage.LPF_Config_1.i_gain.value; + + -- Field: msk_top_regs.LPF_Config_1.i_shift + process(all) + variable next_c: std_logic_vector(7 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.LPF_Config_1.i_shift.value; + load_next_c := '0'; + if decoded_reg_strb.LPF_Config_1 and decoded_req_is_wr then -- SW write + next_c := (field_storage.LPF_Config_1.i_shift.value and not decoded_wr_biten(31 downto 24)) or (decoded_wr_data(31 downto 24) and decoded_wr_biten(31 downto 24)); + load_next_c := '1'; + end if; + field_combo.LPF_Config_1.i_shift.next_q <= next_c; + field_combo.LPF_Config_1.i_shift.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.LPF_Config_1.i_shift.value <= 8x"0"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.LPF_Config_1.i_shift.value <= 8x"0"; + else + if field_combo.LPF_Config_1.i_shift.load_next then + field_storage.LPF_Config_1.i_shift.value <= field_combo.LPF_Config_1.i_shift.next_q; + end if; + end if; + end if; + end process; + hwif_out.LPF_Config_1.i_shift.value <= field_storage.LPF_Config_1.i_shift.value; + + -- Field: msk_top_regs.Tx_Data_Width.data_width + process(all) + variable next_c: std_logic_vector(7 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.Tx_Data_Width.data_width.value; + load_next_c := '0'; + if decoded_reg_strb.Tx_Data_Width and decoded_req_is_wr then -- SW write + next_c := (field_storage.Tx_Data_Width.data_width.value and not decoded_wr_biten(7 downto 0)) or (decoded_wr_data(7 downto 0) and decoded_wr_biten(7 downto 0)); + load_next_c := '1'; + end if; + field_combo.Tx_Data_Width.data_width.next_q <= next_c; + field_combo.Tx_Data_Width.data_width.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.Tx_Data_Width.data_width.value <= 8x"8"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.Tx_Data_Width.data_width.value <= 8x"8"; + else + if field_combo.Tx_Data_Width.data_width.load_next then + field_storage.Tx_Data_Width.data_width.value <= field_combo.Tx_Data_Width.data_width.next_q; + end if; + end if; + end if; + end process; + hwif_out.Tx_Data_Width.data_width.value <= field_storage.Tx_Data_Width.data_width.value; + + -- Field: msk_top_regs.Rx_Data_Width.data_width + process(all) + variable next_c: std_logic_vector(7 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.Rx_Data_Width.data_width.value; + load_next_c := '0'; + if decoded_reg_strb.Rx_Data_Width and decoded_req_is_wr then -- SW write + next_c := (field_storage.Rx_Data_Width.data_width.value and not decoded_wr_biten(7 downto 0)) or (decoded_wr_data(7 downto 0) and decoded_wr_biten(7 downto 0)); + load_next_c := '1'; + end if; + field_combo.Rx_Data_Width.data_width.next_q <= next_c; + field_combo.Rx_Data_Width.data_width.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.Rx_Data_Width.data_width.value <= 8x"8"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.Rx_Data_Width.data_width.value <= 8x"8"; + else + if field_combo.Rx_Data_Width.data_width.load_next then + field_storage.Rx_Data_Width.data_width.value <= field_combo.Rx_Data_Width.data_width.next_q; + end if; + end if; + end if; + end process; + hwif_out.Rx_Data_Width.data_width.value <= field_storage.Rx_Data_Width.data_width.value; + + -- Field: msk_top_regs.PRBS_Control.prbs_sel + process(all) + variable next_c: std_logic; + variable load_next_c: std_logic; + begin + next_c := field_storage.PRBS_Control.prbs_sel.value; + load_next_c := '0'; + if decoded_reg_strb.PRBS_Control and decoded_req_is_wr then -- SW write + next_c := (field_storage.PRBS_Control.prbs_sel.value and not decoded_wr_biten(0)) or (decoded_wr_data(0) and decoded_wr_biten(0)); + load_next_c := '1'; + end if; + field_combo.PRBS_Control.prbs_sel.next_q <= next_c; + field_combo.PRBS_Control.prbs_sel.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.PRBS_Control.prbs_sel.value <= '0'; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.PRBS_Control.prbs_sel.value <= '0'; + else + if field_combo.PRBS_Control.prbs_sel.load_next then + field_storage.PRBS_Control.prbs_sel.value <= field_combo.PRBS_Control.prbs_sel.next_q; + end if; + end if; + end if; + end process; + hwif_out.PRBS_Control.prbs_sel.value <= field_storage.PRBS_Control.prbs_sel.value; + + -- Field: msk_top_regs.PRBS_Control.prbs_error_insert + process(all) + variable next_c: std_logic; + variable load_next_c: std_logic; + begin + next_c := field_storage.PRBS_Control.prbs_error_insert.value; + load_next_c := '0'; + if decoded_reg_strb.PRBS_Control and decoded_req_is_wr then -- SW write + next_c := (field_storage.PRBS_Control.prbs_error_insert.value and not decoded_wr_biten(1)) or (decoded_wr_data(1) and decoded_wr_biten(1)); + load_next_c := '1'; + else -- singlepulse clears back to 0 + next_c := '0'; + load_next_c := '1'; + end if; + field_combo.PRBS_Control.prbs_error_insert.next_q <= next_c; + field_combo.PRBS_Control.prbs_error_insert.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.PRBS_Control.prbs_error_insert.value <= '0'; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.PRBS_Control.prbs_error_insert.value <= '0'; + else + if field_combo.PRBS_Control.prbs_error_insert.load_next then + field_storage.PRBS_Control.prbs_error_insert.value <= field_combo.PRBS_Control.prbs_error_insert.next_q; + end if; + end if; + end if; + end process; + hwif_out.PRBS_Control.prbs_error_insert.value <= field_storage.PRBS_Control.prbs_error_insert.value; + + -- Field: msk_top_regs.PRBS_Control.prbs_clear + process(all) + variable next_c: std_logic; + variable load_next_c: std_logic; + begin + next_c := field_storage.PRBS_Control.prbs_clear.value; + load_next_c := '0'; + if decoded_reg_strb.PRBS_Control and decoded_req_is_wr then -- SW write + next_c := (field_storage.PRBS_Control.prbs_clear.value and not decoded_wr_biten(2)) or (decoded_wr_data(2) and decoded_wr_biten(2)); + load_next_c := '1'; + else -- singlepulse clears back to 0 + next_c := '0'; + load_next_c := '1'; + end if; + field_combo.PRBS_Control.prbs_clear.next_q <= next_c; + field_combo.PRBS_Control.prbs_clear.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.PRBS_Control.prbs_clear.value <= '0'; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.PRBS_Control.prbs_clear.value <= '0'; + else + if field_combo.PRBS_Control.prbs_clear.load_next then + field_storage.PRBS_Control.prbs_clear.value <= field_combo.PRBS_Control.prbs_clear.next_q; + end if; + end if; + end if; + end process; + hwif_out.PRBS_Control.prbs_clear.value <= field_storage.PRBS_Control.prbs_clear.value; + + -- Field: msk_top_regs.PRBS_Control.prbs_manual_sync + process(all) + variable next_c: std_logic; + variable load_next_c: std_logic; + begin + next_c := field_storage.PRBS_Control.prbs_manual_sync.value; + load_next_c := '0'; + if decoded_reg_strb.PRBS_Control and decoded_req_is_wr then -- SW write + next_c := (field_storage.PRBS_Control.prbs_manual_sync.value and not decoded_wr_biten(3)) or (decoded_wr_data(3) and decoded_wr_biten(3)); + load_next_c := '1'; + else -- singlepulse clears back to 0 + next_c := '0'; + load_next_c := '1'; + end if; + field_combo.PRBS_Control.prbs_manual_sync.next_q <= next_c; + field_combo.PRBS_Control.prbs_manual_sync.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.PRBS_Control.prbs_manual_sync.value <= '0'; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.PRBS_Control.prbs_manual_sync.value <= '0'; + else + if field_combo.PRBS_Control.prbs_manual_sync.load_next then + field_storage.PRBS_Control.prbs_manual_sync.value <= field_combo.PRBS_Control.prbs_manual_sync.next_q; + end if; + end if; + end if; + end process; + hwif_out.PRBS_Control.prbs_manual_sync.value <= field_storage.PRBS_Control.prbs_manual_sync.value; + + -- Field: msk_top_regs.PRBS_Control.prbs_reserved + process(all) + variable next_c: std_logic_vector(11 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.PRBS_Control.prbs_reserved.value; + load_next_c := '0'; + if decoded_reg_strb.PRBS_Control and decoded_req_is_wr then -- SW write + next_c := (field_storage.PRBS_Control.prbs_reserved.value and not decoded_wr_biten(15 downto 4)) or (decoded_wr_data(15 downto 4) and decoded_wr_biten(15 downto 4)); + load_next_c := '1'; + end if; + field_combo.PRBS_Control.prbs_reserved.next_q <= next_c; + field_combo.PRBS_Control.prbs_reserved.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.PRBS_Control.prbs_reserved.value <= 12x"0"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.PRBS_Control.prbs_reserved.value <= 12x"0"; + else + if field_combo.PRBS_Control.prbs_reserved.load_next then + field_storage.PRBS_Control.prbs_reserved.value <= field_combo.PRBS_Control.prbs_reserved.next_q; + end if; + end if; + end if; + end process; + hwif_out.PRBS_Control.prbs_reserved.value <= field_storage.PRBS_Control.prbs_reserved.value; + + -- Field: msk_top_regs.PRBS_Control.prbs_sync_threshold + process(all) + variable next_c: std_logic_vector(15 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.PRBS_Control.prbs_sync_threshold.value; + load_next_c := '0'; + if decoded_reg_strb.PRBS_Control and decoded_req_is_wr then -- SW write + next_c := (field_storage.PRBS_Control.prbs_sync_threshold.value and not decoded_wr_biten(31 downto 16)) or (decoded_wr_data(31 downto 16) and decoded_wr_biten(31 downto 16)); + load_next_c := '1'; + end if; + field_combo.PRBS_Control.prbs_sync_threshold.next_q <= next_c; + field_combo.PRBS_Control.prbs_sync_threshold.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.PRBS_Control.prbs_sync_threshold.value <= 16x"0"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.PRBS_Control.prbs_sync_threshold.value <= 16x"0"; + else + if field_combo.PRBS_Control.prbs_sync_threshold.load_next then + field_storage.PRBS_Control.prbs_sync_threshold.value <= field_combo.PRBS_Control.prbs_sync_threshold.next_q; + end if; + end if; + end if; + end process; + hwif_out.PRBS_Control.prbs_sync_threshold.value <= field_storage.PRBS_Control.prbs_sync_threshold.value; + + -- Field: msk_top_regs.PRBS_Initial_State.config_data + process(all) + variable next_c: std_logic_vector(31 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.PRBS_Initial_State.config_data.value; + load_next_c := '0'; + if decoded_reg_strb.PRBS_Initial_State and decoded_req_is_wr then -- SW write + next_c := (field_storage.PRBS_Initial_State.config_data.value and not decoded_wr_biten(31 downto 0)) or (decoded_wr_data(31 downto 0) and decoded_wr_biten(31 downto 0)); + load_next_c := '1'; + end if; + field_combo.PRBS_Initial_State.config_data.next_q <= next_c; + field_combo.PRBS_Initial_State.config_data.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.PRBS_Initial_State.config_data.value <= 32x"0"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.PRBS_Initial_State.config_data.value <= 32x"0"; + else + if field_combo.PRBS_Initial_State.config_data.load_next then + field_storage.PRBS_Initial_State.config_data.value <= field_combo.PRBS_Initial_State.config_data.next_q; + end if; + end if; + end if; + end process; + hwif_out.PRBS_Initial_State.config_data.value <= field_storage.PRBS_Initial_State.config_data.value; + + -- Field: msk_top_regs.PRBS_Polynomial.config_data + process(all) + variable next_c: std_logic_vector(31 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.PRBS_Polynomial.config_data.value; + load_next_c := '0'; + if decoded_reg_strb.PRBS_Polynomial and decoded_req_is_wr then -- SW write + next_c := (field_storage.PRBS_Polynomial.config_data.value and not decoded_wr_biten(31 downto 0)) or (decoded_wr_data(31 downto 0) and decoded_wr_biten(31 downto 0)); + load_next_c := '1'; + end if; + field_combo.PRBS_Polynomial.config_data.next_q <= next_c; + field_combo.PRBS_Polynomial.config_data.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.PRBS_Polynomial.config_data.value <= 32x"0"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.PRBS_Polynomial.config_data.value <= 32x"0"; + else + if field_combo.PRBS_Polynomial.config_data.load_next then + field_storage.PRBS_Polynomial.config_data.value <= field_combo.PRBS_Polynomial.config_data.next_q; + end if; + end if; + end if; + end process; + hwif_out.PRBS_Polynomial.config_data.value <= field_storage.PRBS_Polynomial.config_data.value; + + -- Field: msk_top_regs.PRBS_Error_Mask.config_data + process(all) + variable next_c: std_logic_vector(31 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.PRBS_Error_Mask.config_data.value; + load_next_c := '0'; + if decoded_reg_strb.PRBS_Error_Mask and decoded_req_is_wr then -- SW write + next_c := (field_storage.PRBS_Error_Mask.config_data.value and not decoded_wr_biten(31 downto 0)) or (decoded_wr_data(31 downto 0) and decoded_wr_biten(31 downto 0)); + load_next_c := '1'; + end if; + field_combo.PRBS_Error_Mask.config_data.next_q <= next_c; + field_combo.PRBS_Error_Mask.config_data.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.PRBS_Error_Mask.config_data.value <= 32x"0"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.PRBS_Error_Mask.config_data.value <= 32x"0"; + else + if field_combo.PRBS_Error_Mask.config_data.load_next then + field_storage.PRBS_Error_Mask.config_data.value <= field_combo.PRBS_Error_Mask.config_data.next_q; + end if; + end if; + end if; + end process; + hwif_out.PRBS_Error_Mask.config_data.value <= field_storage.PRBS_Error_Mask.config_data.value; + + -- Field: msk_top_regs.PRBS_Bit_Count.data + process(all) + variable next_c: std_logic_vector(31 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.PRBS_Bit_Count.data.value; + load_next_c := '0'; + if decoded_reg_strb.PRBS_Bit_Count and decoded_req_is_wr then -- SW write + next_c := (field_storage.PRBS_Bit_Count.data.value and not decoded_wr_biten(31 downto 0)) or (decoded_wr_data(31 downto 0) and decoded_wr_biten(31 downto 0)); + load_next_c := '1'; + elsif hwif_in.PRBS_Bit_Count.data.we then -- HW Write - we + next_c := hwif_in.PRBS_Bit_Count.data.next_q; + load_next_c := '1'; + end if; + field_combo.PRBS_Bit_Count.data.next_q <= next_c; + field_combo.PRBS_Bit_Count.data.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.PRBS_Bit_Count.data.value <= 32x"0"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.PRBS_Bit_Count.data.value <= 32x"0"; + else + if field_combo.PRBS_Bit_Count.data.load_next then + field_storage.PRBS_Bit_Count.data.value <= field_combo.PRBS_Bit_Count.data.next_q; + end if; + end if; + end if; + end process; + hwif_out.PRBS_Bit_Count.data.swmod <= decoded_reg_strb.PRBS_Bit_Count and decoded_req_is_wr and or_reduce(decoded_wr_biten(31 downto 0)); + + -- Field: msk_top_regs.PRBS_Error_Count.data + process(all) + variable next_c: std_logic_vector(31 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.PRBS_Error_Count.data.value; + load_next_c := '0'; + if decoded_reg_strb.PRBS_Error_Count and decoded_req_is_wr then -- SW write + next_c := (field_storage.PRBS_Error_Count.data.value and not decoded_wr_biten(31 downto 0)) or (decoded_wr_data(31 downto 0) and decoded_wr_biten(31 downto 0)); + load_next_c := '1'; + elsif hwif_in.PRBS_Error_Count.data.we then -- HW Write - we + next_c := hwif_in.PRBS_Error_Count.data.next_q; + load_next_c := '1'; + end if; + field_combo.PRBS_Error_Count.data.next_q <= next_c; + field_combo.PRBS_Error_Count.data.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.PRBS_Error_Count.data.value <= 32x"0"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.PRBS_Error_Count.data.value <= 32x"0"; + else + if field_combo.PRBS_Error_Count.data.load_next then + field_storage.PRBS_Error_Count.data.value <= field_combo.PRBS_Error_Count.data.next_q; + end if; + end if; + end if; + end process; + hwif_out.PRBS_Error_Count.data.swmod <= decoded_reg_strb.PRBS_Error_Count and decoded_req_is_wr and or_reduce(decoded_wr_biten(31 downto 0)); + + -- Field: msk_top_regs.LPF_Accum_F1.data + process(all) + variable next_c: std_logic_vector(31 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.LPF_Accum_F1.data.value; + load_next_c := '0'; + if decoded_reg_strb.LPF_Accum_F1 and decoded_req_is_wr then -- SW write + next_c := (field_storage.LPF_Accum_F1.data.value and not decoded_wr_biten(31 downto 0)) or (decoded_wr_data(31 downto 0) and decoded_wr_biten(31 downto 0)); + load_next_c := '1'; + elsif hwif_in.LPF_Accum_F1.data.we then -- HW Write - we + next_c := hwif_in.LPF_Accum_F1.data.next_q; + load_next_c := '1'; + end if; + field_combo.LPF_Accum_F1.data.next_q <= next_c; + field_combo.LPF_Accum_F1.data.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.LPF_Accum_F1.data.value <= 32x"0"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.LPF_Accum_F1.data.value <= 32x"0"; + else + if field_combo.LPF_Accum_F1.data.load_next then + field_storage.LPF_Accum_F1.data.value <= field_combo.LPF_Accum_F1.data.next_q; + end if; + end if; + end if; + end process; + hwif_out.LPF_Accum_F1.data.swmod <= decoded_reg_strb.LPF_Accum_F1 and decoded_req_is_wr and or_reduce(decoded_wr_biten(31 downto 0)); + + -- Field: msk_top_regs.LPF_Accum_F2.data + process(all) + variable next_c: std_logic_vector(31 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.LPF_Accum_F2.data.value; + load_next_c := '0'; + if decoded_reg_strb.LPF_Accum_F2 and decoded_req_is_wr then -- SW write + next_c := (field_storage.LPF_Accum_F2.data.value and not decoded_wr_biten(31 downto 0)) or (decoded_wr_data(31 downto 0) and decoded_wr_biten(31 downto 0)); + load_next_c := '1'; + elsif hwif_in.LPF_Accum_F2.data.we then -- HW Write - we + next_c := hwif_in.LPF_Accum_F2.data.next_q; + load_next_c := '1'; + end if; + field_combo.LPF_Accum_F2.data.next_q <= next_c; + field_combo.LPF_Accum_F2.data.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.LPF_Accum_F2.data.value <= 32x"0"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.LPF_Accum_F2.data.value <= 32x"0"; + else + if field_combo.LPF_Accum_F2.data.load_next then + field_storage.LPF_Accum_F2.data.value <= field_combo.LPF_Accum_F2.data.next_q; + end if; + end if; + end if; + end process; + hwif_out.LPF_Accum_F2.data.swmod <= decoded_reg_strb.LPF_Accum_F2 and decoded_req_is_wr and or_reduce(decoded_wr_biten(31 downto 0)); + + -- Field: msk_top_regs.axis_xfer_count.data + process(all) + variable next_c: std_logic_vector(31 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.axis_xfer_count.data.value; + load_next_c := '0'; + if decoded_reg_strb.axis_xfer_count and decoded_req_is_wr then -- SW write + next_c := (field_storage.axis_xfer_count.data.value and not decoded_wr_biten(31 downto 0)) or (decoded_wr_data(31 downto 0) and decoded_wr_biten(31 downto 0)); + load_next_c := '1'; + elsif hwif_in.axis_xfer_count.data.we then -- HW Write - we + next_c := hwif_in.axis_xfer_count.data.next_q; + load_next_c := '1'; + end if; + field_combo.axis_xfer_count.data.next_q <= next_c; + field_combo.axis_xfer_count.data.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.axis_xfer_count.data.value <= 32x"0"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.axis_xfer_count.data.value <= 32x"0"; + else + if field_combo.axis_xfer_count.data.load_next then + field_storage.axis_xfer_count.data.value <= field_combo.axis_xfer_count.data.next_q; + end if; + end if; + end if; + end process; + hwif_out.axis_xfer_count.data.swmod <= decoded_reg_strb.axis_xfer_count and decoded_req_is_wr and or_reduce(decoded_wr_biten(31 downto 0)); + + -- Field: msk_top_regs.Rx_Sample_Discard.rx_sample_discard + process(all) + variable next_c: std_logic_vector(7 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.Rx_Sample_Discard.rx_sample_discard.value; + load_next_c := '0'; + if decoded_reg_strb.Rx_Sample_Discard and decoded_req_is_wr then -- SW write + next_c := (field_storage.Rx_Sample_Discard.rx_sample_discard.value and not decoded_wr_biten(7 downto 0)) or (decoded_wr_data(7 downto 0) and decoded_wr_biten(7 downto 0)); + load_next_c := '1'; + end if; + field_combo.Rx_Sample_Discard.rx_sample_discard.next_q <= next_c; + field_combo.Rx_Sample_Discard.rx_sample_discard.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.Rx_Sample_Discard.rx_sample_discard.value <= 8x"0"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.Rx_Sample_Discard.rx_sample_discard.value <= 8x"0"; + else + if field_combo.Rx_Sample_Discard.rx_sample_discard.load_next then + field_storage.Rx_Sample_Discard.rx_sample_discard.value <= field_combo.Rx_Sample_Discard.rx_sample_discard.next_q; + end if; + end if; + end if; + end process; + hwif_out.Rx_Sample_Discard.rx_sample_discard.value <= field_storage.Rx_Sample_Discard.rx_sample_discard.value; + + -- Field: msk_top_regs.Rx_Sample_Discard.rx_nco_discard + process(all) + variable next_c: std_logic_vector(7 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.Rx_Sample_Discard.rx_nco_discard.value; + load_next_c := '0'; + if decoded_reg_strb.Rx_Sample_Discard and decoded_req_is_wr then -- SW write + next_c := (field_storage.Rx_Sample_Discard.rx_nco_discard.value and not decoded_wr_biten(15 downto 8)) or (decoded_wr_data(15 downto 8) and decoded_wr_biten(15 downto 8)); + load_next_c := '1'; + end if; + field_combo.Rx_Sample_Discard.rx_nco_discard.next_q <= next_c; + field_combo.Rx_Sample_Discard.rx_nco_discard.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.Rx_Sample_Discard.rx_nco_discard.value <= 8x"0"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.Rx_Sample_Discard.rx_nco_discard.value <= 8x"0"; + else + if field_combo.Rx_Sample_Discard.rx_nco_discard.load_next then + field_storage.Rx_Sample_Discard.rx_nco_discard.value <= field_combo.Rx_Sample_Discard.rx_nco_discard.next_q; + end if; + end if; + end if; + end process; + hwif_out.Rx_Sample_Discard.rx_nco_discard.value <= field_storage.Rx_Sample_Discard.rx_nco_discard.value; + + -- Field: msk_top_regs.LPF_Config_2.p_gain + process(all) + variable next_c: std_logic_vector(23 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.LPF_Config_2.p_gain.value; + load_next_c := '0'; + if decoded_reg_strb.LPF_Config_2 and decoded_req_is_wr then -- SW write + next_c := (field_storage.LPF_Config_2.p_gain.value and not decoded_wr_biten(23 downto 0)) or (decoded_wr_data(23 downto 0) and decoded_wr_biten(23 downto 0)); + load_next_c := '1'; + end if; + field_combo.LPF_Config_2.p_gain.next_q <= next_c; + field_combo.LPF_Config_2.p_gain.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.LPF_Config_2.p_gain.value <= 24x"0"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.LPF_Config_2.p_gain.value <= 24x"0"; + else + if field_combo.LPF_Config_2.p_gain.load_next then + field_storage.LPF_Config_2.p_gain.value <= field_combo.LPF_Config_2.p_gain.next_q; + end if; + end if; + end if; + end process; + hwif_out.LPF_Config_2.p_gain.value <= field_storage.LPF_Config_2.p_gain.value; + + -- Field: msk_top_regs.LPF_Config_2.p_shift + process(all) + variable next_c: std_logic_vector(7 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.LPF_Config_2.p_shift.value; + load_next_c := '0'; + if decoded_reg_strb.LPF_Config_2 and decoded_req_is_wr then -- SW write + next_c := (field_storage.LPF_Config_2.p_shift.value and not decoded_wr_biten(31 downto 24)) or (decoded_wr_data(31 downto 24) and decoded_wr_biten(31 downto 24)); + load_next_c := '1'; + end if; + field_combo.LPF_Config_2.p_shift.next_q <= next_c; + field_combo.LPF_Config_2.p_shift.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.LPF_Config_2.p_shift.value <= 8x"0"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.LPF_Config_2.p_shift.value <= 8x"0"; + else + if field_combo.LPF_Config_2.p_shift.load_next then + field_storage.LPF_Config_2.p_shift.value <= field_combo.LPF_Config_2.p_shift.next_q; + end if; + end if; + end if; + end process; + hwif_out.LPF_Config_2.p_shift.value <= field_storage.LPF_Config_2.p_shift.value; + + -- Field: msk_top_regs.f1_nco_adjust.data + process(all) + variable next_c: std_logic_vector(31 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.f1_nco_adjust.data.value; + load_next_c := '0'; + if decoded_reg_strb.f1_nco_adjust and decoded_req_is_wr then -- SW write + next_c := (field_storage.f1_nco_adjust.data.value and not decoded_wr_biten(31 downto 0)) or (decoded_wr_data(31 downto 0) and decoded_wr_biten(31 downto 0)); + load_next_c := '1'; + elsif hwif_in.f1_nco_adjust.data.we then -- HW Write - we + next_c := hwif_in.f1_nco_adjust.data.next_q; + load_next_c := '1'; + end if; + field_combo.f1_nco_adjust.data.next_q <= next_c; + field_combo.f1_nco_adjust.data.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.f1_nco_adjust.data.value <= 32x"0"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.f1_nco_adjust.data.value <= 32x"0"; + else + if field_combo.f1_nco_adjust.data.load_next then + field_storage.f1_nco_adjust.data.value <= field_combo.f1_nco_adjust.data.next_q; + end if; + end if; + end if; + end process; + hwif_out.f1_nco_adjust.data.swmod <= decoded_reg_strb.f1_nco_adjust and decoded_req_is_wr and or_reduce(decoded_wr_biten(31 downto 0)); + + -- Field: msk_top_regs.f2_nco_adjust.data + process(all) + variable next_c: std_logic_vector(31 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.f2_nco_adjust.data.value; + load_next_c := '0'; + if decoded_reg_strb.f2_nco_adjust and decoded_req_is_wr then -- SW write + next_c := (field_storage.f2_nco_adjust.data.value and not decoded_wr_biten(31 downto 0)) or (decoded_wr_data(31 downto 0) and decoded_wr_biten(31 downto 0)); + load_next_c := '1'; + elsif hwif_in.f2_nco_adjust.data.we then -- HW Write - we + next_c := hwif_in.f2_nco_adjust.data.next_q; + load_next_c := '1'; + end if; + field_combo.f2_nco_adjust.data.next_q <= next_c; + field_combo.f2_nco_adjust.data.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.f2_nco_adjust.data.value <= 32x"0"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.f2_nco_adjust.data.value <= 32x"0"; + else + if field_combo.f2_nco_adjust.data.load_next then + field_storage.f2_nco_adjust.data.value <= field_combo.f2_nco_adjust.data.next_q; + end if; + end if; + end if; + end process; + hwif_out.f2_nco_adjust.data.swmod <= decoded_reg_strb.f2_nco_adjust and decoded_req_is_wr and or_reduce(decoded_wr_biten(31 downto 0)); + + -- Field: msk_top_regs.f1_error.data + process(all) + variable next_c: std_logic_vector(31 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.f1_error.data.value; + load_next_c := '0'; + if decoded_reg_strb.f1_error and decoded_req_is_wr then -- SW write + next_c := (field_storage.f1_error.data.value and not decoded_wr_biten(31 downto 0)) or (decoded_wr_data(31 downto 0) and decoded_wr_biten(31 downto 0)); + load_next_c := '1'; + elsif hwif_in.f1_error.data.we then -- HW Write - we + next_c := hwif_in.f1_error.data.next_q; + load_next_c := '1'; + end if; + field_combo.f1_error.data.next_q <= next_c; + field_combo.f1_error.data.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.f1_error.data.value <= 32x"0"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.f1_error.data.value <= 32x"0"; + else + if field_combo.f1_error.data.load_next then + field_storage.f1_error.data.value <= field_combo.f1_error.data.next_q; + end if; + end if; + end if; + end process; + hwif_out.f1_error.data.swmod <= decoded_reg_strb.f1_error and decoded_req_is_wr and or_reduce(decoded_wr_biten(31 downto 0)); + + -- Field: msk_top_regs.f2_error.data + process(all) + variable next_c: std_logic_vector(31 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.f2_error.data.value; + load_next_c := '0'; + if decoded_reg_strb.f2_error and decoded_req_is_wr then -- SW write + next_c := (field_storage.f2_error.data.value and not decoded_wr_biten(31 downto 0)) or (decoded_wr_data(31 downto 0) and decoded_wr_biten(31 downto 0)); + load_next_c := '1'; + elsif hwif_in.f2_error.data.we then -- HW Write - we + next_c := hwif_in.f2_error.data.next_q; + load_next_c := '1'; + end if; + field_combo.f2_error.data.next_q <= next_c; + field_combo.f2_error.data.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.f2_error.data.value <= 32x"0"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.f2_error.data.value <= 32x"0"; + else + if field_combo.f2_error.data.load_next then + field_storage.f2_error.data.value <= field_combo.f2_error.data.next_q; + end if; + end if; + end if; + end process; + hwif_out.f2_error.data.swmod <= decoded_reg_strb.f2_error and decoded_req_is_wr and or_reduce(decoded_wr_biten(31 downto 0)); + + -- Field: msk_top_regs.Tx_Sync_Ctrl.tx_sync_ena + process(all) + variable next_c: std_logic; + variable load_next_c: std_logic; + begin + next_c := field_storage.Tx_Sync_Ctrl.tx_sync_ena.value; + load_next_c := '0'; + if decoded_reg_strb.Tx_Sync_Ctrl and decoded_req_is_wr then -- SW write + next_c := (field_storage.Tx_Sync_Ctrl.tx_sync_ena.value and not decoded_wr_biten(0)) or (decoded_wr_data(0) and decoded_wr_biten(0)); + load_next_c := '1'; + end if; + field_combo.Tx_Sync_Ctrl.tx_sync_ena.next_q <= next_c; + field_combo.Tx_Sync_Ctrl.tx_sync_ena.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.Tx_Sync_Ctrl.tx_sync_ena.value <= '0'; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.Tx_Sync_Ctrl.tx_sync_ena.value <= '0'; + else + if field_combo.Tx_Sync_Ctrl.tx_sync_ena.load_next then + field_storage.Tx_Sync_Ctrl.tx_sync_ena.value <= field_combo.Tx_Sync_Ctrl.tx_sync_ena.next_q; + end if; + end if; + end if; + end process; + hwif_out.Tx_Sync_Ctrl.tx_sync_ena.value <= field_storage.Tx_Sync_Ctrl.tx_sync_ena.value; + + -- Field: msk_top_regs.Tx_Sync_Ctrl.tx_sync_force + process(all) + variable next_c: std_logic; + variable load_next_c: std_logic; + begin + next_c := field_storage.Tx_Sync_Ctrl.tx_sync_force.value; + load_next_c := '0'; + if decoded_reg_strb.Tx_Sync_Ctrl and decoded_req_is_wr then -- SW write + next_c := (field_storage.Tx_Sync_Ctrl.tx_sync_force.value and not decoded_wr_biten(1)) or (decoded_wr_data(1) and decoded_wr_biten(1)); + load_next_c := '1'; + end if; + field_combo.Tx_Sync_Ctrl.tx_sync_force.next_q <= next_c; + field_combo.Tx_Sync_Ctrl.tx_sync_force.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.Tx_Sync_Ctrl.tx_sync_force.value <= '0'; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.Tx_Sync_Ctrl.tx_sync_force.value <= '0'; + else + if field_combo.Tx_Sync_Ctrl.tx_sync_force.load_next then + field_storage.Tx_Sync_Ctrl.tx_sync_force.value <= field_combo.Tx_Sync_Ctrl.tx_sync_force.next_q; + end if; + end if; + end if; + end process; + hwif_out.Tx_Sync_Ctrl.tx_sync_force.value <= field_storage.Tx_Sync_Ctrl.tx_sync_force.value; + + -- Field: msk_top_regs.Tx_Sync_Cnt.tx_sync_cnt + process(all) + variable next_c: std_logic_vector(23 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.Tx_Sync_Cnt.tx_sync_cnt.value; + load_next_c := '0'; + if decoded_reg_strb.Tx_Sync_Cnt and decoded_req_is_wr then -- SW write + next_c := (field_storage.Tx_Sync_Cnt.tx_sync_cnt.value and not decoded_wr_biten(23 downto 0)) or (decoded_wr_data(23 downto 0) and decoded_wr_biten(23 downto 0)); + load_next_c := '1'; + end if; + field_combo.Tx_Sync_Cnt.tx_sync_cnt.next_q <= next_c; + field_combo.Tx_Sync_Cnt.tx_sync_cnt.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.Tx_Sync_Cnt.tx_sync_cnt.value <= 24x"0"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.Tx_Sync_Cnt.tx_sync_cnt.value <= 24x"0"; + else + if field_combo.Tx_Sync_Cnt.tx_sync_cnt.load_next then + field_storage.Tx_Sync_Cnt.tx_sync_cnt.value <= field_combo.Tx_Sync_Cnt.tx_sync_cnt.next_q; + end if; + end if; + end if; + end process; + hwif_out.Tx_Sync_Cnt.tx_sync_cnt.value <= field_storage.Tx_Sync_Cnt.tx_sync_cnt.value; + + -- Field: msk_top_regs.lowpass_ema_alpha1.alpha + process(all) + variable next_c: std_logic_vector(17 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.lowpass_ema_alpha1.alpha.value; + load_next_c := '0'; + if decoded_reg_strb.lowpass_ema_alpha1 and decoded_req_is_wr then -- SW write + next_c := (field_storage.lowpass_ema_alpha1.alpha.value and not decoded_wr_biten(17 downto 0)) or (decoded_wr_data(17 downto 0) and decoded_wr_biten(17 downto 0)); + load_next_c := '1'; + end if; + field_combo.lowpass_ema_alpha1.alpha.next_q <= next_c; + field_combo.lowpass_ema_alpha1.alpha.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.lowpass_ema_alpha1.alpha.value <= 18x"0"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.lowpass_ema_alpha1.alpha.value <= 18x"0"; + else + if field_combo.lowpass_ema_alpha1.alpha.load_next then + field_storage.lowpass_ema_alpha1.alpha.value <= field_combo.lowpass_ema_alpha1.alpha.next_q; + end if; + end if; + end if; + end process; + hwif_out.lowpass_ema_alpha1.alpha.value <= field_storage.lowpass_ema_alpha1.alpha.value; + + -- Field: msk_top_regs.lowpass_ema_alpha2.alpha + process(all) + variable next_c: std_logic_vector(17 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.lowpass_ema_alpha2.alpha.value; + load_next_c := '0'; + if decoded_reg_strb.lowpass_ema_alpha2 and decoded_req_is_wr then -- SW write + next_c := (field_storage.lowpass_ema_alpha2.alpha.value and not decoded_wr_biten(17 downto 0)) or (decoded_wr_data(17 downto 0) and decoded_wr_biten(17 downto 0)); + load_next_c := '1'; + end if; + field_combo.lowpass_ema_alpha2.alpha.next_q <= next_c; + field_combo.lowpass_ema_alpha2.alpha.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.lowpass_ema_alpha2.alpha.value <= 18x"0"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.lowpass_ema_alpha2.alpha.value <= 18x"0"; + else + if field_combo.lowpass_ema_alpha2.alpha.load_next then + field_storage.lowpass_ema_alpha2.alpha.value <= field_combo.lowpass_ema_alpha2.alpha.next_q; + end if; + end if; + end if; + end process; + hwif_out.lowpass_ema_alpha2.alpha.value <= field_storage.lowpass_ema_alpha2.alpha.value; + + -- Field: msk_top_regs.rx_power.data + process(all) + variable next_c: std_logic_vector(22 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.rx_power.data.value; + load_next_c := '0'; + if decoded_reg_strb.rx_power and decoded_req_is_wr then -- SW write + next_c := (field_storage.rx_power.data.value and not decoded_wr_biten(22 downto 0)) or (decoded_wr_data(22 downto 0) and decoded_wr_biten(22 downto 0)); + load_next_c := '1'; + elsif hwif_in.rx_power.data.we then -- HW Write - we + next_c := hwif_in.rx_power.data.next_q; + load_next_c := '1'; + end if; + field_combo.rx_power.data.next_q <= next_c; + field_combo.rx_power.data.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.rx_power.data.value <= 23x"0"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.rx_power.data.value <= 23x"0"; + else + if field_combo.rx_power.data.load_next then + field_storage.rx_power.data.value <= field_combo.rx_power.data.next_q; + end if; + end if; + end if; + end process; + hwif_out.rx_power.data.swmod <= decoded_reg_strb.rx_power and decoded_req_is_wr and or_reduce(decoded_wr_biten(22 downto 0)); + + -- Field: msk_top_regs.tx_async_fifo_rd_wr_ptr.data + process(all) + variable next_c: std_logic_vector(31 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.tx_async_fifo_rd_wr_ptr.data.value; + load_next_c := '0'; + if decoded_reg_strb.tx_async_fifo_rd_wr_ptr and decoded_req_is_wr then -- SW write + next_c := (field_storage.tx_async_fifo_rd_wr_ptr.data.value and not decoded_wr_biten(31 downto 0)) or (decoded_wr_data(31 downto 0) and decoded_wr_biten(31 downto 0)); + load_next_c := '1'; + elsif hwif_in.tx_async_fifo_rd_wr_ptr.data.we then -- HW Write - we + next_c := hwif_in.tx_async_fifo_rd_wr_ptr.data.next_q; + load_next_c := '1'; + end if; + field_combo.tx_async_fifo_rd_wr_ptr.data.next_q <= next_c; + field_combo.tx_async_fifo_rd_wr_ptr.data.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.tx_async_fifo_rd_wr_ptr.data.value <= 32x"0"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.tx_async_fifo_rd_wr_ptr.data.value <= 32x"0"; + else + if field_combo.tx_async_fifo_rd_wr_ptr.data.load_next then + field_storage.tx_async_fifo_rd_wr_ptr.data.value <= field_combo.tx_async_fifo_rd_wr_ptr.data.next_q; + end if; + end if; + end if; + end process; + hwif_out.tx_async_fifo_rd_wr_ptr.data.swmod <= decoded_reg_strb.tx_async_fifo_rd_wr_ptr and decoded_req_is_wr and or_reduce(decoded_wr_biten(31 downto 0)); + + -- Field: msk_top_regs.rx_async_fifo_rd_wr_ptr.data + process(all) + variable next_c: std_logic_vector(31 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.rx_async_fifo_rd_wr_ptr.data.value; + load_next_c := '0'; + if decoded_reg_strb.rx_async_fifo_rd_wr_ptr and decoded_req_is_wr then -- SW write + next_c := (field_storage.rx_async_fifo_rd_wr_ptr.data.value and not decoded_wr_biten(31 downto 0)) or (decoded_wr_data(31 downto 0) and decoded_wr_biten(31 downto 0)); + load_next_c := '1'; + elsif hwif_in.rx_async_fifo_rd_wr_ptr.data.we then -- HW Write - we + next_c := hwif_in.rx_async_fifo_rd_wr_ptr.data.next_q; + load_next_c := '1'; + end if; + field_combo.rx_async_fifo_rd_wr_ptr.data.next_q <= next_c; + field_combo.rx_async_fifo_rd_wr_ptr.data.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.rx_async_fifo_rd_wr_ptr.data.value <= 32x"0"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.rx_async_fifo_rd_wr_ptr.data.value <= 32x"0"; + else + if field_combo.rx_async_fifo_rd_wr_ptr.data.load_next then + field_storage.rx_async_fifo_rd_wr_ptr.data.value <= field_combo.rx_async_fifo_rd_wr_ptr.data.next_q; + end if; + end if; + end if; + end process; + hwif_out.rx_async_fifo_rd_wr_ptr.data.swmod <= decoded_reg_strb.rx_async_fifo_rd_wr_ptr and decoded_req_is_wr and or_reduce(decoded_wr_biten(31 downto 0)); + + -- Field: msk_top_regs.rx_frame_sync_status.frame_buffer_overflow + process(all) + variable next_c: std_logic; + variable load_next_c: std_logic; + begin + next_c := field_storage.rx_frame_sync_status.frame_buffer_overflow.value; + load_next_c := '0'; + if decoded_reg_strb.rx_frame_sync_status and not decoded_req_is_wr then -- SW clear on read + next_c := '0'; + load_next_c := '1'; + elsif hwif_in.rx_frame_sync_status.frame_buffer_overflow.we then -- HW Write - we + next_c := hwif_in.rx_frame_sync_status.frame_buffer_overflow.next_q; + load_next_c := '1'; + end if; + field_combo.rx_frame_sync_status.frame_buffer_overflow.next_q <= next_c; + field_combo.rx_frame_sync_status.frame_buffer_overflow.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.rx_frame_sync_status.frame_buffer_overflow.value <= '0'; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.rx_frame_sync_status.frame_buffer_overflow.value <= '0'; + else + if field_combo.rx_frame_sync_status.frame_buffer_overflow.load_next then + field_storage.rx_frame_sync_status.frame_buffer_overflow.value <= field_combo.rx_frame_sync_status.frame_buffer_overflow.next_q; + end if; + end if; + end if; + end process; + + -- Field: msk_top_regs.rx_frame_sync_status.frames_received + process(all) + variable next_c: std_logic_vector(23 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.rx_frame_sync_status.frames_received.value; + load_next_c := '0'; + if decoded_reg_strb.rx_frame_sync_status and decoded_req_is_wr then -- SW write + next_c := (field_storage.rx_frame_sync_status.frames_received.value and not decoded_wr_biten(25 downto 2)) or (decoded_wr_data(25 downto 2) and decoded_wr_biten(25 downto 2)); + load_next_c := '1'; + elsif hwif_in.rx_frame_sync_status.frames_received.we then -- HW Write - we + next_c := hwif_in.rx_frame_sync_status.frames_received.next_q; + load_next_c := '1'; + end if; + field_combo.rx_frame_sync_status.frames_received.next_q <= next_c; + field_combo.rx_frame_sync_status.frames_received.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.rx_frame_sync_status.frames_received.value <= 24x"0"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.rx_frame_sync_status.frames_received.value <= 24x"0"; + else + if field_combo.rx_frame_sync_status.frames_received.load_next then + field_storage.rx_frame_sync_status.frames_received.value <= field_combo.rx_frame_sync_status.frames_received.next_q; + end if; + end if; + end if; + end process; + hwif_out.rx_frame_sync_status.frames_received.swmod <= decoded_reg_strb.rx_frame_sync_status and decoded_req_is_wr and or_reduce(decoded_wr_biten(25 downto 2)); + + -- Field: msk_top_regs.rx_frame_sync_status.frame_sync_errors + process(all) + variable next_c: std_logic_vector(5 downto 0); + variable load_next_c: std_logic; + begin + next_c := field_storage.rx_frame_sync_status.frame_sync_errors.value; + load_next_c := '0'; + if decoded_reg_strb.rx_frame_sync_status and decoded_req_is_wr then -- SW write + next_c := (field_storage.rx_frame_sync_status.frame_sync_errors.value and not decoded_wr_biten(31 downto 26)) or (decoded_wr_data(31 downto 26) and decoded_wr_biten(31 downto 26)); + load_next_c := '1'; + elsif hwif_in.rx_frame_sync_status.frame_sync_errors.we then -- HW Write - we + next_c := hwif_in.rx_frame_sync_status.frame_sync_errors.next_q; + load_next_c := '1'; + end if; + field_combo.rx_frame_sync_status.frame_sync_errors.next_q <= next_c; + field_combo.rx_frame_sync_status.frame_sync_errors.load_next <= load_next_c; + end process; + process(clk) begin + if false then -- async reset + field_storage.rx_frame_sync_status.frame_sync_errors.value <= 6x"0"; + elsif rising_edge(clk) then + if rst then -- sync reset + field_storage.rx_frame_sync_status.frame_sync_errors.value <= 6x"0"; + else + if field_combo.rx_frame_sync_status.frame_sync_errors.load_next then + field_storage.rx_frame_sync_status.frame_sync_errors.value <= field_combo.rx_frame_sync_status.frame_sync_errors.next_q; + end if; + end if; + end if; + end process; + hwif_out.rx_frame_sync_status.frame_sync_errors.swmod <= decoded_reg_strb.rx_frame_sync_status and decoded_req_is_wr and or_reduce(decoded_wr_biten(31 downto 26)); + + ---------------------------------------------------------------------------- + -- Write response + ---------------------------------------------------------------------------- + cpuif_wr_ack <= decoded_req and decoded_req_is_wr; + -- Writes are always granted with no error response + cpuif_wr_err <= '0'; + + ---------------------------------------------------------------------------- + -- Readback + ---------------------------------------------------------------------------- + + -- Assign readback values to a flattened array + readback_array(0)(31 downto 0) <= 32x"AAAA5555" when (decoded_reg_strb.Hash_ID_Low and not decoded_req_is_wr) else (others => '0'); + readback_array(1)(31 downto 0) <= 32x"5555AAAA" when (decoded_reg_strb.Hash_ID_High and not decoded_req_is_wr) else (others => '0'); + readback_array(2)(0 downto 0) <= to_std_logic_vector(field_storage.MSK_Init.txrxinit.value) when (decoded_reg_strb.MSK_Init and not decoded_req_is_wr) else (others => '0'); + readback_array(2)(1 downto 1) <= to_std_logic_vector(field_storage.MSK_Init.txinit.value) when (decoded_reg_strb.MSK_Init and not decoded_req_is_wr) else (others => '0'); + readback_array(2)(2 downto 2) <= to_std_logic_vector(field_storage.MSK_Init.rxinit.value) when (decoded_reg_strb.MSK_Init and not decoded_req_is_wr) else (others => '0'); + readback_array(2)(31 downto 3) <= (others => '0'); + readback_array(3)(0 downto 0) <= to_std_logic_vector(field_storage.MSK_Control.ptt.value) when (decoded_reg_strb.MSK_Control and not decoded_req_is_wr) else (others => '0'); + readback_array(3)(1 downto 1) <= to_std_logic_vector(field_storage.MSK_Control.loopback_ena.value) when (decoded_reg_strb.MSK_Control and not decoded_req_is_wr) else (others => '0'); + readback_array(3)(2 downto 2) <= to_std_logic_vector(field_storage.MSK_Control.rx_invert.value) when (decoded_reg_strb.MSK_Control and not decoded_req_is_wr) else (others => '0'); + readback_array(3)(3 downto 3) <= to_std_logic_vector(field_storage.MSK_Control.clear_counts.value) when (decoded_reg_strb.MSK_Control and not decoded_req_is_wr) else (others => '0'); + readback_array(3)(4 downto 4) <= to_std_logic_vector(field_storage.MSK_Control.diff_encoder_loopback.value) when (decoded_reg_strb.MSK_Control and not decoded_req_is_wr) else (others => '0'); + readback_array(3)(31 downto 5) <= (others => '0'); + readback_array(4)(0 downto 0) <= to_std_logic_vector(hwif_in.MSK_Status.demod_sync_lock.next_q) when (decoded_reg_strb.MSK_Status and not decoded_req_is_wr) else (others => '0'); + readback_array(4)(1 downto 1) <= to_std_logic_vector(hwif_in.MSK_Status.tx_enable.next_q) when (decoded_reg_strb.MSK_Status and not decoded_req_is_wr) else (others => '0'); + readback_array(4)(2 downto 2) <= to_std_logic_vector(hwif_in.MSK_Status.rx_enable.next_q) when (decoded_reg_strb.MSK_Status and not decoded_req_is_wr) else (others => '0'); + readback_array(4)(3 downto 3) <= to_std_logic_vector(hwif_in.MSK_Status.tx_axis_valid.next_q) when (decoded_reg_strb.MSK_Status and not decoded_req_is_wr) else (others => '0'); + readback_array(4)(31 downto 4) <= (others => '0'); + readback_array(5)(31 downto 0) <= field_storage.Tx_Bit_Count.data.value when (decoded_reg_strb.Tx_Bit_Count and not decoded_req_is_wr) else (others => '0'); + readback_array(6)(31 downto 0) <= field_storage.Tx_Enable_Count.data.value when (decoded_reg_strb.Tx_Enable_Count and not decoded_req_is_wr) else (others => '0'); + readback_array(7)(31 downto 0) <= field_storage.Fb_FreqWord.config_data.value when (decoded_reg_strb.Fb_FreqWord and not decoded_req_is_wr) else (others => '0'); + readback_array(8)(31 downto 0) <= field_storage.TX_F1_FreqWord.config_data.value when (decoded_reg_strb.TX_F1_FreqWord and not decoded_req_is_wr) else (others => '0'); + readback_array(9)(31 downto 0) <= field_storage.TX_F2_FreqWord.config_data.value when (decoded_reg_strb.TX_F2_FreqWord and not decoded_req_is_wr) else (others => '0'); + readback_array(10)(31 downto 0) <= field_storage.RX_F1_FreqWord.config_data.value when (decoded_reg_strb.RX_F1_FreqWord and not decoded_req_is_wr) else (others => '0'); + readback_array(11)(31 downto 0) <= field_storage.RX_F2_FreqWord.config_data.value when (decoded_reg_strb.RX_F2_FreqWord and not decoded_req_is_wr) else (others => '0'); + readback_array(12)(0 downto 0) <= to_std_logic_vector(field_storage.LPF_Config_0.lpf_freeze.value) when (decoded_reg_strb.LPF_Config_0 and not decoded_req_is_wr) else (others => '0'); + readback_array(12)(1 downto 1) <= to_std_logic_vector(field_storage.LPF_Config_0.lpf_zero.value) when (decoded_reg_strb.LPF_Config_0 and not decoded_req_is_wr) else (others => '0'); + readback_array(12)(7 downto 2) <= field_storage.LPF_Config_0.prbs_reserved.value when (decoded_reg_strb.LPF_Config_0 and not decoded_req_is_wr) else (others => '0'); + readback_array(12)(31 downto 8) <= field_storage.LPF_Config_0.lpf_alpha.value when (decoded_reg_strb.LPF_Config_0 and not decoded_req_is_wr) else (others => '0'); + readback_array(13)(23 downto 0) <= field_storage.LPF_Config_1.i_gain.value when (decoded_reg_strb.LPF_Config_1 and not decoded_req_is_wr) else (others => '0'); + readback_array(13)(31 downto 24) <= field_storage.LPF_Config_1.i_shift.value when (decoded_reg_strb.LPF_Config_1 and not decoded_req_is_wr) else (others => '0'); + readback_array(14)(7 downto 0) <= field_storage.Tx_Data_Width.data_width.value when (decoded_reg_strb.Tx_Data_Width and not decoded_req_is_wr) else (others => '0'); + readback_array(14)(31 downto 8) <= (others => '0'); + readback_array(15)(7 downto 0) <= field_storage.Rx_Data_Width.data_width.value when (decoded_reg_strb.Rx_Data_Width and not decoded_req_is_wr) else (others => '0'); + readback_array(15)(31 downto 8) <= (others => '0'); + readback_array(16)(0 downto 0) <= to_std_logic_vector(field_storage.PRBS_Control.prbs_sel.value) when (decoded_reg_strb.PRBS_Control and not decoded_req_is_wr) else (others => '0'); + readback_array(16)(3 downto 1) <= (others => '0'); + readback_array(16)(15 downto 4) <= field_storage.PRBS_Control.prbs_reserved.value when (decoded_reg_strb.PRBS_Control and not decoded_req_is_wr) else (others => '0'); + readback_array(16)(31 downto 16) <= field_storage.PRBS_Control.prbs_sync_threshold.value when (decoded_reg_strb.PRBS_Control and not decoded_req_is_wr) else (others => '0'); + readback_array(17)(31 downto 0) <= field_storage.PRBS_Initial_State.config_data.value when (decoded_reg_strb.PRBS_Initial_State and not decoded_req_is_wr) else (others => '0'); + readback_array(18)(31 downto 0) <= field_storage.PRBS_Polynomial.config_data.value when (decoded_reg_strb.PRBS_Polynomial and not decoded_req_is_wr) else (others => '0'); + readback_array(19)(31 downto 0) <= field_storage.PRBS_Error_Mask.config_data.value when (decoded_reg_strb.PRBS_Error_Mask and not decoded_req_is_wr) else (others => '0'); + readback_array(20)(31 downto 0) <= field_storage.PRBS_Bit_Count.data.value when (decoded_reg_strb.PRBS_Bit_Count and not decoded_req_is_wr) else (others => '0'); + readback_array(21)(31 downto 0) <= field_storage.PRBS_Error_Count.data.value when (decoded_reg_strb.PRBS_Error_Count and not decoded_req_is_wr) else (others => '0'); + readback_array(22)(31 downto 0) <= field_storage.LPF_Accum_F1.data.value when (decoded_reg_strb.LPF_Accum_F1 and not decoded_req_is_wr) else (others => '0'); + readback_array(23)(31 downto 0) <= field_storage.LPF_Accum_F2.data.value when (decoded_reg_strb.LPF_Accum_F2 and not decoded_req_is_wr) else (others => '0'); + readback_array(24)(31 downto 0) <= field_storage.axis_xfer_count.data.value when (decoded_reg_strb.axis_xfer_count and not decoded_req_is_wr) else (others => '0'); + readback_array(25)(7 downto 0) <= field_storage.Rx_Sample_Discard.rx_sample_discard.value when (decoded_reg_strb.Rx_Sample_Discard and not decoded_req_is_wr) else (others => '0'); + readback_array(25)(15 downto 8) <= field_storage.Rx_Sample_Discard.rx_nco_discard.value when (decoded_reg_strb.Rx_Sample_Discard and not decoded_req_is_wr) else (others => '0'); + readback_array(25)(31 downto 16) <= (others => '0'); + readback_array(26)(23 downto 0) <= field_storage.LPF_Config_2.p_gain.value when (decoded_reg_strb.LPF_Config_2 and not decoded_req_is_wr) else (others => '0'); + readback_array(26)(31 downto 24) <= field_storage.LPF_Config_2.p_shift.value when (decoded_reg_strb.LPF_Config_2 and not decoded_req_is_wr) else (others => '0'); + readback_array(27)(31 downto 0) <= field_storage.f1_nco_adjust.data.value when (decoded_reg_strb.f1_nco_adjust and not decoded_req_is_wr) else (others => '0'); + readback_array(28)(31 downto 0) <= field_storage.f2_nco_adjust.data.value when (decoded_reg_strb.f2_nco_adjust and not decoded_req_is_wr) else (others => '0'); + readback_array(29)(31 downto 0) <= field_storage.f1_error.data.value when (decoded_reg_strb.f1_error and not decoded_req_is_wr) else (others => '0'); + readback_array(30)(31 downto 0) <= field_storage.f2_error.data.value when (decoded_reg_strb.f2_error and not decoded_req_is_wr) else (others => '0'); + readback_array(31)(0 downto 0) <= to_std_logic_vector(field_storage.Tx_Sync_Ctrl.tx_sync_ena.value) when (decoded_reg_strb.Tx_Sync_Ctrl and not decoded_req_is_wr) else (others => '0'); + readback_array(31)(1 downto 1) <= to_std_logic_vector(field_storage.Tx_Sync_Ctrl.tx_sync_force.value) when (decoded_reg_strb.Tx_Sync_Ctrl and not decoded_req_is_wr) else (others => '0'); + readback_array(31)(31 downto 2) <= (others => '0'); + readback_array(32)(23 downto 0) <= field_storage.Tx_Sync_Cnt.tx_sync_cnt.value when (decoded_reg_strb.Tx_Sync_Cnt and not decoded_req_is_wr) else (others => '0'); + readback_array(32)(31 downto 24) <= (others => '0'); + readback_array(33)(17 downto 0) <= field_storage.lowpass_ema_alpha1.alpha.value when (decoded_reg_strb.lowpass_ema_alpha1 and not decoded_req_is_wr) else (others => '0'); + readback_array(33)(31 downto 18) <= (others => '0'); + readback_array(34)(17 downto 0) <= field_storage.lowpass_ema_alpha2.alpha.value when (decoded_reg_strb.lowpass_ema_alpha2 and not decoded_req_is_wr) else (others => '0'); + readback_array(34)(31 downto 18) <= (others => '0'); + readback_array(35)(22 downto 0) <= field_storage.rx_power.data.value when (decoded_reg_strb.rx_power and not decoded_req_is_wr) else (others => '0'); + readback_array(35)(31 downto 23) <= (others => '0'); + readback_array(36)(31 downto 0) <= field_storage.tx_async_fifo_rd_wr_ptr.data.value when (decoded_reg_strb.tx_async_fifo_rd_wr_ptr and not decoded_req_is_wr) else (others => '0'); + readback_array(37)(31 downto 0) <= field_storage.rx_async_fifo_rd_wr_ptr.data.value when (decoded_reg_strb.rx_async_fifo_rd_wr_ptr and not decoded_req_is_wr) else (others => '0'); + readback_array(38)(0 downto 0) <= to_std_logic_vector(hwif_in.rx_frame_sync_status.frame_sync_locked.next_q) when (decoded_reg_strb.rx_frame_sync_status and not decoded_req_is_wr) else (others => '0'); + readback_array(38)(1 downto 1) <= to_std_logic_vector(field_storage.rx_frame_sync_status.frame_buffer_overflow.value) when (decoded_reg_strb.rx_frame_sync_status and not decoded_req_is_wr) else (others => '0'); + readback_array(38)(25 downto 2) <= field_storage.rx_frame_sync_status.frames_received.value when (decoded_reg_strb.rx_frame_sync_status and not decoded_req_is_wr) else (others => '0'); + readback_array(38)(31 downto 26) <= field_storage.rx_frame_sync_status.frame_sync_errors.value when (decoded_reg_strb.rx_frame_sync_status and not decoded_req_is_wr) else (others => '0'); + + -- Reduce the array + process(all) + variable readback_data_var : std_logic_vector(31 downto 0) := (others => '0'); + begin + readback_done <= decoded_req and not decoded_req_is_wr; + readback_err <= '0'; + readback_data_var := (others => '0'); + for i in readback_array'RANGE loop + readback_data_var := readback_data_var or readback_array(i); + end loop; + readback_data <= readback_data_var; + end process; + + cpuif_rd_ack <= readback_done; + cpuif_rd_data <= readback_data; + cpuif_rd_err <= readback_err; +end architecture rtl; diff --git a/rdl/outputs/rtl/msk_top_regs_pkg.vhd b/rdl/outputs/rtl/msk_top_regs_pkg.vhd new file mode 100644 index 0000000..a4ca55e --- /dev/null +++ b/rdl/outputs/rtl/msk_top_regs_pkg.vhd @@ -0,0 +1,621 @@ +-- Generated by PeakRDL-regblock-vhdl - A free and open-source VHDL generator +-- https://github.com/SystemRDL/PeakRDL-regblock-vhdl +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use ieee.fixed_pkg.all; + +package msk_top_regs_pkg is + + constant MSK_TOP_REGS_DATA_WIDTH : positive := 32; + constant MSK_TOP_REGS_MIN_ADDR_WIDTH : positive := 8; + constant MSK_TOP_REGS_SIZE : positive := 156; + + type \msk_top_regs.msk_stat_0.demod_sync_lock_in_t\ is record + next_q : std_logic; + end record; + + type \msk_top_regs.msk_stat_0.tx_enable_in_t\ is record + next_q : std_logic; + end record; + + type \msk_top_regs.msk_stat_0.rx_enable_in_t\ is record + next_q : std_logic; + end record; + + type \msk_top_regs.msk_stat_0.tx_axis_valid_in_t\ is record + next_q : std_logic; + end record; + + type \msk_top_regs.msk_stat_0_in_t\ is record + demod_sync_lock : \msk_top_regs.msk_stat_0.demod_sync_lock_in_t\; + tx_enable : \msk_top_regs.msk_stat_0.tx_enable_in_t\; + rx_enable : \msk_top_regs.msk_stat_0.rx_enable_in_t\; + tx_axis_valid : \msk_top_regs.msk_stat_0.tx_axis_valid_in_t\; + end record; + + type \msk_top_regs.msk_stat_1.data_in_t\ is record + next_q : std_logic_vector(31 downto 0); + we : std_logic; + end record; + + type \msk_top_regs.msk_stat_1_in_t\ is record + data : \msk_top_regs.msk_stat_1.data_in_t\; + end record; + + type \msk_top_regs.msk_stat_2.data_in_t\ is record + next_q : std_logic_vector(31 downto 0); + we : std_logic; + end record; + + type \msk_top_regs.msk_stat_2_in_t\ is record + data : \msk_top_regs.msk_stat_2.data_in_t\; + end record; + + type \msk_top_regs.stat_32_bits.data_in_t\ is record + next_q : std_logic_vector(31 downto 0); + we : std_logic; + end record; + + type \msk_top_regs.stat_32_bits_in_t\ is record + data : \msk_top_regs.stat_32_bits.data_in_t\; + end record; + + type \msk_top_regs.stat_32_errs.data_in_t\ is record + next_q : std_logic_vector(31 downto 0); + we : std_logic; + end record; + + type \msk_top_regs.stat_32_errs_in_t\ is record + data : \msk_top_regs.stat_32_errs.data_in_t\; + end record; + + type \msk_top_regs.stat_32_lpf_acc_desc_8cebc7dc_name_f20c6670.data_in_t\ is record + next_q : std_logic_vector(31 downto 0); + we : std_logic; + end record; + + type \msk_top_regs.stat_32_lpf_acc_desc_8cebc7dc_name_f20c6670_in_t\ is record + data : \msk_top_regs.stat_32_lpf_acc_desc_8cebc7dc_name_f20c6670.data_in_t\; + end record; + + type \msk_top_regs.stat_32_lpf_acc_desc_dea6bd99_name_758fd0ce.data_in_t\ is record + next_q : std_logic_vector(31 downto 0); + we : std_logic; + end record; + + type \msk_top_regs.stat_32_lpf_acc_desc_dea6bd99_name_758fd0ce_in_t\ is record + data : \msk_top_regs.stat_32_lpf_acc_desc_dea6bd99_name_758fd0ce.data_in_t\; + end record; + + type \msk_top_regs.msk_stat_3.data_in_t\ is record + next_q : std_logic_vector(31 downto 0); + we : std_logic; + end record; + + type \msk_top_regs.msk_stat_3_in_t\ is record + data : \msk_top_regs.msk_stat_3.data_in_t\; + end record; + + type \msk_top_regs.status_reg_data_f53978c8_name_d8ad3b25.data_desc_0ed96915_in_t\ is record + next_q : std_logic_vector(31 downto 0); + we : std_logic; + end record; + + type \msk_top_regs.status_reg_data_f53978c8_name_d8ad3b25_in_t\ is record + data : \msk_top_regs.status_reg_data_f53978c8_name_d8ad3b25.data_desc_0ed96915_in_t\; + end record; + + type \msk_top_regs.status_reg_data_05243a4e_name_2c154788.data_desc_13897f4c_in_t\ is record + next_q : std_logic_vector(31 downto 0); + we : std_logic; + end record; + + type \msk_top_regs.status_reg_data_05243a4e_name_2c154788_in_t\ is record + data : \msk_top_regs.status_reg_data_05243a4e_name_2c154788.data_desc_13897f4c_in_t\; + end record; + + type \msk_top_regs.status_reg_data_10a2e5b5_name_3b640507.data_desc_83db1b72_in_t\ is record + next_q : std_logic_vector(31 downto 0); + we : std_logic; + end record; + + type \msk_top_regs.status_reg_data_10a2e5b5_name_3b640507_in_t\ is record + data : \msk_top_regs.status_reg_data_10a2e5b5_name_3b640507.data_desc_83db1b72_in_t\; + end record; + + type \msk_top_regs.status_reg_data_642692cf_name_3de9a0d3.data_desc_c8bf066a_in_t\ is record + next_q : std_logic_vector(31 downto 0); + we : std_logic; + end record; + + type \msk_top_regs.status_reg_data_642692cf_name_3de9a0d3_in_t\ is record + data : \msk_top_regs.status_reg_data_642692cf_name_3de9a0d3.data_desc_c8bf066a_in_t\; + end record; + + type \msk_top_regs.rx_power.data_in_t\ is record + next_q : std_logic_vector(22 downto 0); + we : std_logic; + end record; + + type \msk_top_regs.rx_power_in_t\ is record + data : \msk_top_regs.rx_power.data_in_t\; + end record; + + type \msk_top_regs.status_reg_data_8a67e1fe_desc_aa4ec676_name_aa4ec676.data_desc_a6882ec4_in_t\ is record + next_q : std_logic_vector(31 downto 0); + we : std_logic; + end record; + + type \msk_top_regs.status_reg_data_8a67e1fe_desc_aa4ec676_name_aa4ec676_in_t\ is record + data : \msk_top_regs.status_reg_data_8a67e1fe_desc_aa4ec676_name_aa4ec676.data_desc_a6882ec4_in_t\; + end record; + + type \msk_top_regs.status_reg_data_8a67e1fe_desc_8a90eed1_name_8a90eed1.data_desc_a6882ec4_in_t\ is record + next_q : std_logic_vector(31 downto 0); + we : std_logic; + end record; + + type \msk_top_regs.status_reg_data_8a67e1fe_desc_8a90eed1_name_8a90eed1_in_t\ is record + data : \msk_top_regs.status_reg_data_8a67e1fe_desc_8a90eed1_name_8a90eed1.data_desc_a6882ec4_in_t\; + end record; + + type \msk_top_regs.frame_sync_status.frame_sync_locked_in_t\ is record + next_q : std_logic; + end record; + + type \msk_top_regs.frame_sync_status.frame_buffer_overflow_in_t\ is record + next_q : std_logic; + we : std_logic; + end record; + + type \msk_top_regs.frame_sync_status.frames_received_in_t\ is record + next_q : std_logic_vector(23 downto 0); + we : std_logic; + end record; + + type \msk_top_regs.frame_sync_status.frame_sync_errors_in_t\ is record + next_q : std_logic_vector(5 downto 0); + we : std_logic; + end record; + + type \msk_top_regs.frame_sync_status_in_t\ is record + frame_sync_locked : \msk_top_regs.frame_sync_status.frame_sync_locked_in_t\; + frame_buffer_overflow : \msk_top_regs.frame_sync_status.frame_buffer_overflow_in_t\; + frames_received : \msk_top_regs.frame_sync_status.frames_received_in_t\; + frame_sync_errors : \msk_top_regs.frame_sync_status.frame_sync_errors_in_t\; + end record; + + type msk_top_regs_in_t is record + MSK_Status : \msk_top_regs.msk_stat_0_in_t\; + Tx_Bit_Count : \msk_top_regs.msk_stat_1_in_t\; + Tx_Enable_Count : \msk_top_regs.msk_stat_2_in_t\; + PRBS_Bit_Count : \msk_top_regs.stat_32_bits_in_t\; + PRBS_Error_Count : \msk_top_regs.stat_32_errs_in_t\; + LPF_Accum_F1 : \msk_top_regs.stat_32_lpf_acc_desc_8cebc7dc_name_f20c6670_in_t\; + LPF_Accum_F2 : \msk_top_regs.stat_32_lpf_acc_desc_dea6bd99_name_758fd0ce_in_t\; + axis_xfer_count : \msk_top_regs.msk_stat_3_in_t\; + f1_nco_adjust : \msk_top_regs.status_reg_data_f53978c8_name_d8ad3b25_in_t\; + f2_nco_adjust : \msk_top_regs.status_reg_data_05243a4e_name_2c154788_in_t\; + f1_error : \msk_top_regs.status_reg_data_10a2e5b5_name_3b640507_in_t\; + f2_error : \msk_top_regs.status_reg_data_642692cf_name_3de9a0d3_in_t\; + rx_power : \msk_top_regs.rx_power_in_t\; + tx_async_fifo_rd_wr_ptr : \msk_top_regs.status_reg_data_8a67e1fe_desc_aa4ec676_name_aa4ec676_in_t\; + rx_async_fifo_rd_wr_ptr : \msk_top_regs.status_reg_data_8a67e1fe_desc_8a90eed1_name_8a90eed1_in_t\; + rx_frame_sync_status : \msk_top_regs.frame_sync_status_in_t\; + end record; + + type \msk_top_regs.msk_init.txrxinit_out_t\ is record + value : std_logic; + end record; + + type \msk_top_regs.msk_init.txinit_out_t\ is record + value : std_logic; + end record; + + type \msk_top_regs.msk_init.rxinit_out_t\ is record + value : std_logic; + end record; + + type \msk_top_regs.msk_init_out_t\ is record + txrxinit : \msk_top_regs.msk_init.txrxinit_out_t\; + txinit : \msk_top_regs.msk_init.txinit_out_t\; + rxinit : \msk_top_regs.msk_init.rxinit_out_t\; + end record; + + type \msk_top_regs.msk_ctrl.ptt_out_t\ is record + value : std_logic; + end record; + + type \msk_top_regs.msk_ctrl.loopback_ena_out_t\ is record + value : std_logic; + end record; + + type \msk_top_regs.msk_ctrl.rx_invert_out_t\ is record + value : std_logic; + end record; + + type \msk_top_regs.msk_ctrl.clear_counts_out_t\ is record + value : std_logic; + end record; + + type \msk_top_regs.msk_ctrl.diff_encoder_loopback_out_t\ is record + value : std_logic; + end record; + + type \msk_top_regs.msk_ctrl_out_t\ is record + ptt : \msk_top_regs.msk_ctrl.ptt_out_t\; + loopback_ena : \msk_top_regs.msk_ctrl.loopback_ena_out_t\; + rx_invert : \msk_top_regs.msk_ctrl.rx_invert_out_t\; + clear_counts : \msk_top_regs.msk_ctrl.clear_counts_out_t\; + diff_encoder_loopback : \msk_top_regs.msk_ctrl.diff_encoder_loopback_out_t\; + end record; + + type \msk_top_regs.msk_stat_1.data_out_t\ is record + swmod : std_logic; + end record; + + type \msk_top_regs.msk_stat_1_out_t\ is record + data : \msk_top_regs.msk_stat_1.data_out_t\; + end record; + + type \msk_top_regs.msk_stat_2.data_out_t\ is record + swmod : std_logic; + end record; + + type \msk_top_regs.msk_stat_2_out_t\ is record + data : \msk_top_regs.msk_stat_2.data_out_t\; + end record; + + type \msk_top_regs.config_nco_fw_desc_c4924cc6_name_0c494469.config_data_out_t\ is record + value : std_logic_vector(31 downto 0); + end record; + + type \msk_top_regs.config_nco_fw_desc_c4924cc6_name_0c494469_out_t\ is record + config_data : \msk_top_regs.config_nco_fw_desc_c4924cc6_name_0c494469.config_data_out_t\; + end record; + + type \msk_top_regs.config_nco_fw_desc_94d7aaf5_name_84dd0c1c.config_data_out_t\ is record + value : std_logic_vector(31 downto 0); + end record; + + type \msk_top_regs.config_nco_fw_desc_94d7aaf5_name_84dd0c1c_out_t\ is record + config_data : \msk_top_regs.config_nco_fw_desc_94d7aaf5_name_84dd0c1c.config_data_out_t\; + end record; + + type \msk_top_regs.config_nco_fw_desc_42134a4f_name_d97dbd51.config_data_out_t\ is record + value : std_logic_vector(31 downto 0); + end record; + + type \msk_top_regs.config_nco_fw_desc_42134a4f_name_d97dbd51_out_t\ is record + config_data : \msk_top_regs.config_nco_fw_desc_42134a4f_name_d97dbd51.config_data_out_t\; + end record; + + type \msk_top_regs.config_nco_fw_desc_16fb48c8_name_8d01a20d.config_data_out_t\ is record + value : std_logic_vector(31 downto 0); + end record; + + type \msk_top_regs.config_nco_fw_desc_16fb48c8_name_8d01a20d_out_t\ is record + config_data : \msk_top_regs.config_nco_fw_desc_16fb48c8_name_8d01a20d.config_data_out_t\; + end record; + + type \msk_top_regs.config_nco_fw_desc_43c0828f_name_bdc60ecf.config_data_out_t\ is record + value : std_logic_vector(31 downto 0); + end record; + + type \msk_top_regs.config_nco_fw_desc_43c0828f_name_bdc60ecf_out_t\ is record + config_data : \msk_top_regs.config_nco_fw_desc_43c0828f_name_bdc60ecf.config_data_out_t\; + end record; + + type \msk_top_regs.lpf_config_0.lpf_freeze_out_t\ is record + value : std_logic; + end record; + + type \msk_top_regs.lpf_config_0.lpf_zero_out_t\ is record + value : std_logic; + end record; + + type \msk_top_regs.lpf_config_0.prbs_reserved_out_t\ is record + value : std_logic_vector(5 downto 0); + end record; + + type \msk_top_regs.lpf_config_0.lpf_alpha_out_t\ is record + value : std_logic_vector(23 downto 0); + end record; + + type \msk_top_regs.lpf_config_0_out_t\ is record + lpf_freeze : \msk_top_regs.lpf_config_0.lpf_freeze_out_t\; + lpf_zero : \msk_top_regs.lpf_config_0.lpf_zero_out_t\; + prbs_reserved : \msk_top_regs.lpf_config_0.prbs_reserved_out_t\; + lpf_alpha : \msk_top_regs.lpf_config_0.lpf_alpha_out_t\; + end record; + + type \msk_top_regs.lpf_config_1.i_gain_out_t\ is record + value : std_logic_vector(23 downto 0); + end record; + + type \msk_top_regs.lpf_config_1.i_shift_out_t\ is record + value : std_logic_vector(7 downto 0); + end record; + + type \msk_top_regs.lpf_config_1_out_t\ is record + i_gain : \msk_top_regs.lpf_config_1.i_gain_out_t\; + i_shift : \msk_top_regs.lpf_config_1.i_shift_out_t\; + end record; + + type \msk_top_regs.data_width_desc_58c848dd_name_2fbd8eba.data_width_out_t\ is record + value : std_logic_vector(7 downto 0); + end record; + + type \msk_top_regs.data_width_desc_58c848dd_name_2fbd8eba_out_t\ is record + data_width : \msk_top_regs.data_width_desc_58c848dd_name_2fbd8eba.data_width_out_t\; + end record; + + type \msk_top_regs.data_width_desc_6097df38_name_4609588b.data_width_out_t\ is record + value : std_logic_vector(7 downto 0); + end record; + + type \msk_top_regs.data_width_desc_6097df38_name_4609588b_out_t\ is record + data_width : \msk_top_regs.data_width_desc_6097df38_name_4609588b.data_width_out_t\; + end record; + + type \msk_top_regs.prbs_ctrl.prbs_sel_out_t\ is record + value : std_logic; + end record; + + type \msk_top_regs.prbs_ctrl.prbs_error_insert_out_t\ is record + value : std_logic; + end record; + + type \msk_top_regs.prbs_ctrl.prbs_clear_out_t\ is record + value : std_logic; + end record; + + type \msk_top_regs.prbs_ctrl.prbs_manual_sync_out_t\ is record + value : std_logic; + end record; + + type \msk_top_regs.prbs_ctrl.prbs_reserved_out_t\ is record + value : std_logic_vector(11 downto 0); + end record; + + type \msk_top_regs.prbs_ctrl.prbs_sync_threshold_out_t\ is record + value : std_logic_vector(15 downto 0); + end record; + + type \msk_top_regs.prbs_ctrl_out_t\ is record + prbs_sel : \msk_top_regs.prbs_ctrl.prbs_sel_out_t\; + prbs_error_insert : \msk_top_regs.prbs_ctrl.prbs_error_insert_out_t\; + prbs_clear : \msk_top_regs.prbs_ctrl.prbs_clear_out_t\; + prbs_manual_sync : \msk_top_regs.prbs_ctrl.prbs_manual_sync_out_t\; + prbs_reserved : \msk_top_regs.prbs_ctrl.prbs_reserved_out_t\; + prbs_sync_threshold : \msk_top_regs.prbs_ctrl.prbs_sync_threshold_out_t\; + end record; + + type \msk_top_regs.config_prbs_seed.config_data_out_t\ is record + value : std_logic_vector(31 downto 0); + end record; + + type \msk_top_regs.config_prbs_seed_out_t\ is record + config_data : \msk_top_regs.config_prbs_seed.config_data_out_t\; + end record; + + type \msk_top_regs.config_prbs_poly.config_data_out_t\ is record + value : std_logic_vector(31 downto 0); + end record; + + type \msk_top_regs.config_prbs_poly_out_t\ is record + config_data : \msk_top_regs.config_prbs_poly.config_data_out_t\; + end record; + + type \msk_top_regs.config_prbs_errmask.config_data_out_t\ is record + value : std_logic_vector(31 downto 0); + end record; + + type \msk_top_regs.config_prbs_errmask_out_t\ is record + config_data : \msk_top_regs.config_prbs_errmask.config_data_out_t\; + end record; + + type \msk_top_regs.stat_32_bits.data_out_t\ is record + swmod : std_logic; + end record; + + type \msk_top_regs.stat_32_bits_out_t\ is record + data : \msk_top_regs.stat_32_bits.data_out_t\; + end record; + + type \msk_top_regs.stat_32_errs.data_out_t\ is record + swmod : std_logic; + end record; + + type \msk_top_regs.stat_32_errs_out_t\ is record + data : \msk_top_regs.stat_32_errs.data_out_t\; + end record; + + type \msk_top_regs.stat_32_lpf_acc_desc_8cebc7dc_name_f20c6670.data_out_t\ is record + swmod : std_logic; + end record; + + type \msk_top_regs.stat_32_lpf_acc_desc_8cebc7dc_name_f20c6670_out_t\ is record + data : \msk_top_regs.stat_32_lpf_acc_desc_8cebc7dc_name_f20c6670.data_out_t\; + end record; + + type \msk_top_regs.stat_32_lpf_acc_desc_dea6bd99_name_758fd0ce.data_out_t\ is record + swmod : std_logic; + end record; + + type \msk_top_regs.stat_32_lpf_acc_desc_dea6bd99_name_758fd0ce_out_t\ is record + data : \msk_top_regs.stat_32_lpf_acc_desc_dea6bd99_name_758fd0ce.data_out_t\; + end record; + + type \msk_top_regs.msk_stat_3.data_out_t\ is record + swmod : std_logic; + end record; + + type \msk_top_regs.msk_stat_3_out_t\ is record + data : \msk_top_regs.msk_stat_3.data_out_t\; + end record; + + type \msk_top_regs.rx_sample_discard.rx_sample_discard_out_t\ is record + value : std_logic_vector(7 downto 0); + end record; + + type \msk_top_regs.rx_sample_discard.rx_nco_discard_out_t\ is record + value : std_logic_vector(7 downto 0); + end record; + + type \msk_top_regs.rx_sample_discard_out_t\ is record + rx_sample_discard : \msk_top_regs.rx_sample_discard.rx_sample_discard_out_t\; + rx_nco_discard : \msk_top_regs.rx_sample_discard.rx_nco_discard_out_t\; + end record; + + type \msk_top_regs.lpf_config_2.p_gain_out_t\ is record + value : std_logic_vector(23 downto 0); + end record; + + type \msk_top_regs.lpf_config_2.p_shift_out_t\ is record + value : std_logic_vector(7 downto 0); + end record; + + type \msk_top_regs.lpf_config_2_out_t\ is record + p_gain : \msk_top_regs.lpf_config_2.p_gain_out_t\; + p_shift : \msk_top_regs.lpf_config_2.p_shift_out_t\; + end record; + + type \msk_top_regs.status_reg_data_f53978c8_name_d8ad3b25.data_desc_0ed96915_out_t\ is record + swmod : std_logic; + end record; + + type \msk_top_regs.status_reg_data_f53978c8_name_d8ad3b25_out_t\ is record + data : \msk_top_regs.status_reg_data_f53978c8_name_d8ad3b25.data_desc_0ed96915_out_t\; + end record; + + type \msk_top_regs.status_reg_data_05243a4e_name_2c154788.data_desc_13897f4c_out_t\ is record + swmod : std_logic; + end record; + + type \msk_top_regs.status_reg_data_05243a4e_name_2c154788_out_t\ is record + data : \msk_top_regs.status_reg_data_05243a4e_name_2c154788.data_desc_13897f4c_out_t\; + end record; + + type \msk_top_regs.status_reg_data_10a2e5b5_name_3b640507.data_desc_83db1b72_out_t\ is record + swmod : std_logic; + end record; + + type \msk_top_regs.status_reg_data_10a2e5b5_name_3b640507_out_t\ is record + data : \msk_top_regs.status_reg_data_10a2e5b5_name_3b640507.data_desc_83db1b72_out_t\; + end record; + + type \msk_top_regs.status_reg_data_642692cf_name_3de9a0d3.data_desc_c8bf066a_out_t\ is record + swmod : std_logic; + end record; + + type \msk_top_regs.status_reg_data_642692cf_name_3de9a0d3_out_t\ is record + data : \msk_top_regs.status_reg_data_642692cf_name_3de9a0d3.data_desc_c8bf066a_out_t\; + end record; + + type \msk_top_regs.tx_sync_ctrl.tx_sync_ena_out_t\ is record + value : std_logic; + end record; + + type \msk_top_regs.tx_sync_ctrl.tx_sync_force_out_t\ is record + value : std_logic; + end record; + + type \msk_top_regs.tx_sync_ctrl_out_t\ is record + tx_sync_ena : \msk_top_regs.tx_sync_ctrl.tx_sync_ena_out_t\; + tx_sync_force : \msk_top_regs.tx_sync_ctrl.tx_sync_force_out_t\; + end record; + + type \msk_top_regs.tx_sync_cnt.tx_sync_cnt_out_t\ is record + value : std_logic_vector(23 downto 0); + end record; + + type \msk_top_regs.tx_sync_cnt_out_t\ is record + tx_sync_cnt : \msk_top_regs.tx_sync_cnt.tx_sync_cnt_out_t\; + end record; + + type \msk_top_regs.lowpass_ema_alpha.alpha_out_t\ is record + value : std_logic_vector(17 downto 0); + end record; + + type \msk_top_regs.lowpass_ema_alpha_out_t\ is record + alpha : \msk_top_regs.lowpass_ema_alpha.alpha_out_t\; + end record; + + type \msk_top_regs.rx_power.data_out_t\ is record + swmod : std_logic; + end record; + + type \msk_top_regs.rx_power_out_t\ is record + data : \msk_top_regs.rx_power.data_out_t\; + end record; + + type \msk_top_regs.status_reg_data_8a67e1fe_desc_aa4ec676_name_aa4ec676.data_desc_a6882ec4_out_t\ is record + swmod : std_logic; + end record; + + type \msk_top_regs.status_reg_data_8a67e1fe_desc_aa4ec676_name_aa4ec676_out_t\ is record + data : \msk_top_regs.status_reg_data_8a67e1fe_desc_aa4ec676_name_aa4ec676.data_desc_a6882ec4_out_t\; + end record; + + type \msk_top_regs.status_reg_data_8a67e1fe_desc_8a90eed1_name_8a90eed1.data_desc_a6882ec4_out_t\ is record + swmod : std_logic; + end record; + + type \msk_top_regs.status_reg_data_8a67e1fe_desc_8a90eed1_name_8a90eed1_out_t\ is record + data : \msk_top_regs.status_reg_data_8a67e1fe_desc_8a90eed1_name_8a90eed1.data_desc_a6882ec4_out_t\; + end record; + + type \msk_top_regs.frame_sync_status.frames_received_out_t\ is record + swmod : std_logic; + end record; + + type \msk_top_regs.frame_sync_status.frame_sync_errors_out_t\ is record + swmod : std_logic; + end record; + + type \msk_top_regs.frame_sync_status_out_t\ is record + frames_received : \msk_top_regs.frame_sync_status.frames_received_out_t\; + frame_sync_errors : \msk_top_regs.frame_sync_status.frame_sync_errors_out_t\; + end record; + + type msk_top_regs_out_t is record + MSK_Init : \msk_top_regs.msk_init_out_t\; + MSK_Control : \msk_top_regs.msk_ctrl_out_t\; + Tx_Bit_Count : \msk_top_regs.msk_stat_1_out_t\; + Tx_Enable_Count : \msk_top_regs.msk_stat_2_out_t\; + Fb_FreqWord : \msk_top_regs.config_nco_fw_desc_c4924cc6_name_0c494469_out_t\; + TX_F1_FreqWord : \msk_top_regs.config_nco_fw_desc_94d7aaf5_name_84dd0c1c_out_t\; + TX_F2_FreqWord : \msk_top_regs.config_nco_fw_desc_42134a4f_name_d97dbd51_out_t\; + RX_F1_FreqWord : \msk_top_regs.config_nco_fw_desc_16fb48c8_name_8d01a20d_out_t\; + RX_F2_FreqWord : \msk_top_regs.config_nco_fw_desc_43c0828f_name_bdc60ecf_out_t\; + LPF_Config_0 : \msk_top_regs.lpf_config_0_out_t\; + LPF_Config_1 : \msk_top_regs.lpf_config_1_out_t\; + Tx_Data_Width : \msk_top_regs.data_width_desc_58c848dd_name_2fbd8eba_out_t\; + Rx_Data_Width : \msk_top_regs.data_width_desc_6097df38_name_4609588b_out_t\; + PRBS_Control : \msk_top_regs.prbs_ctrl_out_t\; + PRBS_Initial_State : \msk_top_regs.config_prbs_seed_out_t\; + PRBS_Polynomial : \msk_top_regs.config_prbs_poly_out_t\; + PRBS_Error_Mask : \msk_top_regs.config_prbs_errmask_out_t\; + PRBS_Bit_Count : \msk_top_regs.stat_32_bits_out_t\; + PRBS_Error_Count : \msk_top_regs.stat_32_errs_out_t\; + LPF_Accum_F1 : \msk_top_regs.stat_32_lpf_acc_desc_8cebc7dc_name_f20c6670_out_t\; + LPF_Accum_F2 : \msk_top_regs.stat_32_lpf_acc_desc_dea6bd99_name_758fd0ce_out_t\; + axis_xfer_count : \msk_top_regs.msk_stat_3_out_t\; + Rx_Sample_Discard : \msk_top_regs.rx_sample_discard_out_t\; + LPF_Config_2 : \msk_top_regs.lpf_config_2_out_t\; + f1_nco_adjust : \msk_top_regs.status_reg_data_f53978c8_name_d8ad3b25_out_t\; + f2_nco_adjust : \msk_top_regs.status_reg_data_05243a4e_name_2c154788_out_t\; + f1_error : \msk_top_regs.status_reg_data_10a2e5b5_name_3b640507_out_t\; + f2_error : \msk_top_regs.status_reg_data_642692cf_name_3de9a0d3_out_t\; + Tx_Sync_Ctrl : \msk_top_regs.tx_sync_ctrl_out_t\; + Tx_Sync_Cnt : \msk_top_regs.tx_sync_cnt_out_t\; + lowpass_ema_alpha1 : \msk_top_regs.lowpass_ema_alpha_out_t\; + lowpass_ema_alpha2 : \msk_top_regs.lowpass_ema_alpha_out_t\; + rx_power : \msk_top_regs.rx_power_out_t\; + tx_async_fifo_rd_wr_ptr : \msk_top_regs.status_reg_data_8a67e1fe_desc_aa4ec676_name_aa4ec676_out_t\; + rx_async_fifo_rd_wr_ptr : \msk_top_regs.status_reg_data_8a67e1fe_desc_8a90eed1_name_8a90eed1_out_t\; + rx_frame_sync_status : \msk_top_regs.frame_sync_status_out_t\; + end record; +end package; diff --git a/rdl/src/axi4lite_intf_pkg.vhd b/rdl/src/axi4lite_intf_pkg.vhd new file mode 100644 index 0000000..6c83998 --- /dev/null +++ b/rdl/src/axi4lite_intf_pkg.vhd @@ -0,0 +1,43 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +package axi4lite_intf_pkg is + + type axi4lite_slave_in_intf is record + AWVALID : std_logic; + AWADDR : std_logic_vector; + AWPROT : std_logic_vector(2 downto 0); + + WVALID : std_logic; + WDATA : std_logic_vector; + WSTRB : std_logic_vector; + + BREADY : std_logic; + + ARVALID : std_logic; + ARADDR : std_logic_vector; + ARPROT : std_logic_vector(2 downto 0); + + RREADY : std_logic; + end record axi4lite_slave_in_intf; + + type axi4lite_slave_out_intf is record + AWREADY : std_logic; + + WREADY : std_logic; + + BVALID : std_logic; + BRESP : std_logic_vector(1 downto 0); + + ARREADY : std_logic; + + RVALID : std_logic; + RDATA : std_logic_vector; + RRESP : std_logic_vector(1 downto 0); + end record axi4lite_slave_out_intf; + +end package axi4lite_intf_pkg; + +-- package body axi4lite_intf_pkg is +-- end package body axi4lite_intf_pkg; \ No newline at end of file diff --git a/rdl/src/msk_top_regs.rdl b/rdl/src/msk_top_regs.rdl new file mode 100644 index 0000000..4ca52f3 --- /dev/null +++ b/rdl/src/msk_top_regs.rdl @@ -0,0 +1,732 @@ +//---------------------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------------------- +// _______ ________ ______ +// __ __ \________ _____ _______ ___ __ \_____ _____________ ______ ___________________ /_ +// _ / / /___ __ \_ _ \__ __ \ __ /_/ /_ _ \__ ___/_ _ \_ __ `/__ ___/_ ___/__ __ \ +// / /_/ / __ /_/ // __/_ / / / _ _, _/ / __/_(__ ) / __// /_/ / _ / / /__ _ / / / +// \____/ _ .___/ \___/ /_/ /_/ /_/ |_| \___/ /____/ \___/ \__,_/ /_/ \___/ /_/ /_/ +// /_/ +// ________ _____ _____ _____ _____ +// ____ _/_______ __________ /____(_)__ /_____ ____ /______ +// __ / __ __ \__ ___/_ __/__ / _ __/_ / / /_ __/_ _ \ +// __/ / _ / / /_(__ ) / /_ _ / / /_ / /_/ / / /_ / __/ +// /___/ /_/ /_/ /____/ \__/ /_/ \__/ \__,_/ \__/ \___/ +// +//---------------------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------------------- +// +// Copyright 2024, 2025 by M. Wishek +// +//---------------------------------------------------------------------------------------------------- +// License +//---------------------------------------------------------------------------------------------------- +// +// This source describes Open Hardware and is licensed under the CERN-OHL-W v2. +// +// You may redistribute and modify this source and make products using it under +// the terms of the CERN-OHL-W v2 (https://ohwr.org/cern_ohl_w_v2.txt). +// +// This source is distributed WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING +// OF MERCHANTABILITY, SATISFACTORY QUALITY AND FITNESS FOR A PARTICULAR PURPOSE. +// Please see the CERN-OHL-W v2 for applicable conditions. +// +// Source location: TBD +// +// As per CERN-OHL-W v2 section 4.1, should You produce hardware based on this +// source, You must maintain the Source Location visible on the external case of +// the products you make using this source. +// +//---------------------------------------------------------------------------------------------------- +// Block name and description +//---------------------------------------------------------------------------------------------------- +// +// SystemRDL register definitions for Pluto MSK modem +// +// Documentation location: TBD +// +//---------------------------------------------------------------------------------------------------- +//---------------------------------------------------------------------------------------------------- + + +addrmap msk_top_regs { + + name="Pluto MSK Registers"; + desc="MSK Modem Configuration and Status Registers"; + lsb0; + default accesswidth = 32; + default regwidth = 32; + default sw = rw; + default hw = r; + + reg msk_hash_lo { + + name = "Pluto MSK FPGA Hash ID - Lower 32-bits"; + + default sw = r; + default hw = na; + + field { + name = "Hash ID Lower 32-bits"; + desc = "Lower 32-bits of Pluto MSK FPGA Hash ID"; + } hash_id_lo[31:0] = 0xAAAA5555; + }; + + reg msk_hash_hi { + + name = "Pluto MSK FPGA Hash ID - Upper 32-bits"; + + default sw = r; + default hw = na; + + field { + name = "Hash ID Upper 32-bits"; + desc = "Upper 32-bits of Pluto MSK FPGA Hash ID"; + } hash_id_hi[31:0] = 0x5555AAAA; + }; + + reg msk_init { + + name = "MSK Modem Initialization Control"; + desc = "Synchronous initialization of MSK Modem functions, does not affect configuration registers."; + + field { + name = "Tx/Rx Init Enable"; + desc = "0 -> Normal modem operation + + 1 -> Initialize Tx and Rx"; + } txrxinit = 1; + + field { + name = "Tx Init Enable"; + desc = "0 -> Normal Tx operation + + 1 -> Initialize Tx"; + } txinit = 1; + + field { + name = "Rx Init Enable"; + desc = "0 -> Normal Rx operation + + 1 -> Initialize Rx"; + } rxinit = 1; + }; + + reg msk_ctrl { + + name = "MSK Modem Control"; + desc = "MSK Modem Configuration and Control"; + + field { + name = "Push-to-Talk Enable"; + desc = "0 -> PTT Disabled + 1 -> PTT Enabled"; + } ptt = 0; + field { + name = "Modem Digital Tx -> Rx Loopback Enable"; + desc = "0 -> Modem loopback disabled + + 1 -> Modem loopback enabled"; + } loopback_ena = 0; + field { + name = "Rx Data Invert Enable"; + desc = "0 -> Rx data normal + 1 -> Rx data inverted"; + } rx_invert = 0; + field { + desc = "Clear Tx Bit Counter and Tx Enable Counter"; + name = "Clear Status Counters"; + singlepulse = true; + } clear_counts = 0; + field { + name = "Differential Encoder -> Decoder Loopback Enable"; + desc = "0 -> Differential Encoder -> Decoder loopback disabled + + 1 -> Differential Encoder -> Decoder loopback enabled"; + } diff_encoder_loopback = 0; + }; + + reg msk_stat_0 { + name = "MSK Modem Status 0"; + desc = "Modem status bits"; + regwidth = 32; + field { + name = "Demodulator Sync Status"; + desc = "Demodulator Sync Status - not currently implemented"; + sw = r; + hw = w; + } demod_sync_lock = 0; + field { + name = "AD9363 DAC Interface Tx Enable Input Active"; + desc = "1 -> Data to DAC Enabled + + 0 -> Data to DAC Disabled"; + sw = r; + hw = w; + } tx_enable=0; + field { + name = "AD9363 ADC Interface Rx Enable Input Active"; + desc = "1 -> Data from ADC Enabled + + 0 -> Data from ADC Disabled"; + sw = r; + hw = w; + } rx_enable = 0; + field { + name = "Tx S_AXIS_VALID"; + desc = "1 -> S_AXIS_VALID Enabled + + 0 -> S_AXIS_VALID Disabled"; + sw = r; + hw = w; + } tx_axis_valid = 0; + }; + + reg msk_stat_1 { + name = "MSK Modem Status 1"; + desc = "Modem status data"; + regwidth = 32; + field { + name = "Tx Bit Count"; + desc = "Count of data requests made by modem + + This register is write-to-capture. + + To read data the following steps are required: + + 1 - Write any value to this register to capture read data + + 2 - Read the register"; + sw = rw; + hw = w; + we = true; + swmod = true; + } data[31:0] = 0; + }; + + reg msk_stat_2 { + name = "MSK Modem Status 2"; + desc = "Modem status data"; + regwidth = 32; + field { + desc = "Number of clocks on which Tx Enable is active + + This register is write-to-capture. + + To read data the following steps are required: + + 1 - Write any value to this register to capture read data + + 2 - Read the register"; + name = "Tx Enable Count"; + sw = rw; + hw = w; + we = true; + swmod = true; + } data[31:0] = 0; + }; + + reg config_nco_fw { + regwidth = 32; + field { + name = "Frequency Control Word"; + desc = "Sets the center frequency of the NCO as FW = Fn * 2^32/Fs, + where Fn is the desired NCO frequency, and Fs is the NCO sample rate"; + } config_data[31:0] = 0; + }; + + reg rx_sample_discard { + name = "Rx Sample Discard"; + desc = "Configure samples discard operation for demodulator"; + regwidth = 32; + field { + desc = "Number of Rx samples to discard"; + name = "Rx Sample Discard Value"; + } rx_sample_discard[7:0] = 0; + field { + desc = "Number of NCO samples to discard"; + name = "Rx NCO Sample Discard Value"; + } rx_nco_discard[15:8] = 0; + }; + + reg lpf_config_0 { + name = "PI Controller Configuration and Low-pass Filter Configuration"; + desc = "Configure PI controller and low-pass filter"; + regwidth = 32; + field { + name = "Freeze the accumulator's current value"; + desc = "0 -> Normal operation + + 1 -> Freeze current value"; + } lpf_freeze = 0; + field { + name = "Hold the PI Accumulator at zero"; + desc = "0 -> Normal operation + + 1 -> Zero and hold accumulator"; + } lpf_zero = 0; + field { + name = "Reserved"; + } prbs_reserved[7:2] = 0; + field { + name = "Lowpass IIR filter alpha"; + desc = "Value controls the filter rolloff"; + } lpf_alpha[31:8] = 0; + }; + + reg lpf_config_1 { + name = "PI Controller Configuration Configuration Register 1"; + desc = "Configures PI Controller I-gain and divisor"; + regwidth = 32; + field { + name = "Integral Gain Value"; + desc = "Value m of 0-16,777,215 sets the integral multiplier"; + } i_gain[23:0] = 0; + field { + name = "Integral Gain Bit Shift"; + desc = "Value n of 0-32 sets the integral divisor as 2^-n"; + } i_shift[31:24] = 0; + }; + + reg lpf_config_2 { + name = "PI Controller Configuration Configuration Register 2"; + desc = "Configures PI Controller I-gain and divisor"; + regwidth = 32; + field { + name = "Proportional Gain Value"; + desc = "Value m of 0-16,777,215 sets the proportional multiplier"; + } p_gain[23:0] = 0; + field { + name = "Proportional Gain Bit Shift"; + desc = "Value n of 0-32 sets the proportional divisor as 2^-n"; + } p_shift[31:24] = 0; + }; + + reg data_width { + regwidth = 32; + field { + name = "Modem input/output data width"; + desc = "Set the data width of the modem input/output"; + } data_width[7:0] = 8; + }; + + reg prbs_ctrl { + name = "PRBS Control 0"; + desc = "Configures operation of the PRBS Generator and Monitor"; + regwidth = 32; + field { + name = "PRBS Data Select"; + desc = "0 -> Select Normal Tx Data + 1 -> Select PRBS Tx Data"; + } prbs_sel = 0; + field { + name = "PRBS Error Insert"; + desc = "0 -> 1 : Insert bit error in Tx data (both Normal and PRBS) + + 1 -> 0 : Insert bit error in Tx data (both Normal and PRBS)"; + sw = w; + hw = r; + singlepulse = true; + } prbs_error_insert = 0; + field { + name = "PRBS Clear Counters"; + desc = "0 -> 1 : Clear PRBS Counters + + 1 -> 0 : Clear PRBS Counters"; + sw = w; + hw = r; + singlepulse = true; + } prbs_clear = 0; + field { + name = "PRBS Manual Sync"; + desc = "0 -> 1 : Synchronize PRBS monitor + + 1 -> 0 : Synchronize PRBS monitor"; + sw = w; + hw = r; + singlepulse = true; + } prbs_manual_sync = 0; + field { + name = "Reserved"; + } prbs_reserved[15:4] = 0; + field { + name = "PRBS Auto Sync Threshold"; + desc = "0 : Auto Sync Disabled + + N > 0 : Auto sync after N errors"; + } prbs_sync_threshold[31:16] = 0; + }; + + reg config_prbs_seed { + name = "PRBS Control 1"; + desc = "PRBS Initial State"; + regwidth = 32; + field { + name = "PRBS Seed"; + + desc = "Sets the starting value of the PRBS generator"; + } config_data[31:0] = 0; + }; + + reg config_prbs_poly { + name = "PRBS Control 2"; + desc = "PRBS Polynomial"; + regwidth = 32; + field { + name = "PRBS Polynomial"; + + desc = "Bit positions set to '1' indicate polynomial feedback positions"; + } config_data[31:0] = 0; + }; + + reg config_prbs_errmask { + name = "PRBS Control 3"; + desc = "PRBS Error Mask"; + regwidth = 32; + field { + name = "PRBS Error Mask"; + + desc = "Bit positions set to '1' indicate bits that are inverted when a bit error is inserted"; + } config_data[31:0] = 0; + }; + + reg stat_32_bits { + name = "PRBS Status 0"; + desc = "PRBS Bits Received"; + regwidth = 32; + field { + name = "PRBS Bits Received"; + desc = "Number of bits received by the PRBS monitor since last + BER can be calculated as the ratio of received bits to errored-bits + + This register is write-to-capture. + + To read data the following steps are required: + + 1 - Write any value to this register to capture read data + + 2 - Read the register"; + sw = rw; + hw = w; + we = true; + swmod = true; + } data[31:0] = 0; + }; + + reg stat_32_errs { + name = "PRBS Status 1"; + desc = "PRBS Bit Errors"; + regwidth = 32; + field { + name = "PRBS Bit Errors"; + desc = "Number of errored-bits received by the PRBS monitor since last sync + BER can be calculated as the ratio of received bits to errored-bits + + This register is write-to-capture. + + To read data the following steps are required: + + 1 - Write any value to this register to capture read data + + 2 - Read the register"; + sw = rw; + hw = w; + we = true; + swmod = true; + } data[31:0] = 0; + }; + + reg stat_32_lpf_acc { + regwidth = 32; + field { + name = "PI Controller Accumulator Value"; + desc = "PI Controller Accumulator Value + + This register is write-to-capture. + + To read data the following steps are required: + + 1 - Write any value to this register to capture read data + + 2 - Read the register"; + sw = rw; + hw = w; + we = true; + swmod = true; + } data[31:0] = 0; + }; + + reg msk_stat_3 { + name = "MSK Modem Status 3"; + desc = "Modem status data"; + regwidth = 32; + field { + name = "S_AXIS Transfers"; + desc = "Number completed S_AXIS transfers + + This register is write-to-capture. + + To read data the following steps are required: + + 1 - Write any value to this register to capture read data + + 2 - Read the register"; + sw = rw; + hw = w; + we = true; + swmod = true; + } data[31:0] = 0; + }; + + reg tx_sync_ctrl { + name = "Transmitter Sync Control"; + desc = "Provides control bits for generation of transmitter synchronization patterns"; + regwidth = 32; + field { + name = "Tx Sync Enable"; + desc = "0 : Disable sync transmission + + 1 : Enable sync transmission when PTT is asserted"; + } tx_sync_ena = 0; + field { + name = "Tx Sync Force"; + desc = "0 : Normal operation + + 1 : Continuously transmit synchronization pattern"; + } tx_sync_force = 0; + }; + + reg tx_sync_cnt { + name = "Transmitter Sync Duration"; + desc = "Sets the duration of the synchronization tones when enabled"; + regwidth = 32; + field { + name = "Tx sync duration"; + desc = "Value from 0x00_0000 to 0xFF_FFFF. + + This value represents the number bit-times the synchronization signal should be sent after PTT is asserted."; + sw = rw; + hw = r; + } tx_sync_cnt[23:0] = 0; + }; + + reg lowpass_ema_alpha { + name = "Exponential Moving Average Alpha"; + desc = "Sets the alpha for the EMA"; + regwidth = 32; + field { + name = "EMA alpha"; + desc = "Value from 0x0_0000 to 0x3_FFFF represent the EMA alpha"; + } alpha[17:0] = 0; + }; + + reg rx_power { + name = "Receive Power"; + desc = "Receive power computed from I/Q samples"; + regwidth = 32; + field { + name = "Receive Power"; + desc = "Value that represent the RMS power of the incoming signal (I-channel) + + This register is write-to-capture. To read data the following steps are required: + [list=1] + [*] Write any value to this register to capture read data + [*] Read the register + [/list]"; + sw = rw; + hw = w; + we = true; + swmod = true; + } data[22:0] = 0; + }; + + reg status_reg { + name = "Status Register"; + desc = "Status Register"; + regwidth = 32; + field { + fieldwidth = 32; + sw = rw; + hw = w; + we = true; + swmod = true; + } data[31:0] = 0; + }; + + reg frame_sync_status { + name = "Frame Sync Status"; + //desc = "Frame Sync Status"; + regwidth = 32; + field { + name = "Frame Sync Lock"; + desc = "0 - Frame sync not locked + 1 - Frame sync locked"; + fieldwidth = 1; + sw = r; + hw = w; + } frame_sync_locked = 0; + field { + name = "Frame Buffer Overflow"; + desc = "0 - Normal operation + 1 - Buffer overflow"; + fieldwidth = 1; + sw = r; + hw = w; + we = true; + rclr = true; + } frame_buffer_overflow = 0; + field { + name = "Frames Received"; + desc = "Count of frames received. Value is 0x00_0000 to 0xFF_FFFF. Counter rolls over when max count is reached."; + fieldwidth = 24; + sw = rw; + hw = w; + swmod = true; + we = true; + } frames_received = 0; + field { + name = "Frames Sync Errors"; + desc = "Count of frame sync errors. Value is 0 to 63. Counter rolls over when max count is reached."; + fieldwidth = 6; + sw = rw; + hw = w; + swmod = true; + we = true; + } frame_sync_errors = 0; + }; + + + msk_hash_lo Hash_ID_Low; + msk_hash_hi Hash_ID_High; + msk_init MSK_Init; + msk_ctrl MSK_Control; + msk_stat_0 MSK_Status; + msk_stat_1 Tx_Bit_Count; + msk_stat_2 Tx_Enable_Count; + config_nco_fw Fb_FreqWord; + Fb_FreqWord->desc = "Set Modem Data Rate"; + Fb_FreqWord->name = "Bitrate NCO Frequency Control Word"; + config_nco_fw TX_F1_FreqWord; + TX_F1_FreqWord->desc = "Set Modulator F1 Frequency"; + TX_F1_FreqWord->name = "Tx F1 NCO Frequency Control Word"; + config_nco_fw TX_F2_FreqWord; + TX_F2_FreqWord->desc = "Set Modulator F2 Frequency"; + TX_F2_FreqWord->name = "Tx F2 NCO Frequency Control Word"; + config_nco_fw RX_F1_FreqWord; + RX_F1_FreqWord->desc = "Set Demodulator F1 Frequency"; + RX_F1_FreqWord->name = "Rx F1 NCO Frequency Control Word"; + config_nco_fw RX_F2_FreqWord; + RX_F2_FreqWord->desc = "Set Demodulator F2 Frequency"; + RX_F2_FreqWord->name = "Rx F2 NCO Frequency Control Word"; + lpf_config_0 LPF_Config_0; + lpf_config_1 LPF_Config_1; + data_width Tx_Data_Width; + Tx_Data_Width->desc = "Set the parallel data width of the parallel-to-serial converter"; + Tx_Data_Width->name = "Modem Tx Input Data Width"; + data_width Rx_Data_Width; + Rx_Data_Width->desc = "Set the parallel data width of the serial-to-parallel converter"; + Rx_Data_Width->name = "Modem Rx Output Data Width"; + prbs_ctrl PRBS_Control; + config_prbs_seed PRBS_Initial_State; + config_prbs_poly PRBS_Polynomial; + config_prbs_errmask PRBS_Error_Mask; + stat_32_bits PRBS_Bit_Count; + stat_32_errs PRBS_Error_Count; + stat_32_lpf_acc LPF_Accum_F1; + LPF_Accum_F1->name = "F1 PI Controller Accumulator"; + LPF_Accum_F1->desc = "Value of the F1 PI Controller Accumulator"; + stat_32_lpf_acc LPF_Accum_F2; + LPF_Accum_F2->name = "F2 PI Controller Accumulator"; + LPF_Accum_F2->desc = "Value of the F2 PI Controller Accumulator"; + msk_stat_3 axis_xfer_count; + rx_sample_discard Rx_Sample_Discard; + lpf_config_2 LPF_Config_2; + + status_reg f1_nco_adjust; + f1_nco_adjust->name = "F1 NCO Frequency Adjust"; + f1_nco_adjust.data->desc = "Frequency offet applied to the F1 NCO + + This register is write-to-capture. + + To read data the following steps are required: + + 1 - Write any value to this register to capture read data + + 2 - Read the register"; + + status_reg f2_nco_adjust; + f2_nco_adjust->name = "F2 NCO Frequency Adjust"; + f2_nco_adjust.data->desc = "Frequency offet applied to the F2 NCO + + This register is write-to-capture. + + To read data the following steps are required: + + 1 - Write any value to this register to capture read data + + 2 - Read the register"; + + status_reg f1_error; + f1_error->name = "F1 Error Value"; + f1_error.data->desc = "Error value of the F1 Costas loop after each active bit period + + This register is write-to-capture. + + To read data the following steps are required: + + 1 - Write any value to this register to capture read data + + 2 - Read the register"; + + status_reg f2_error; + f2_error->name = "F2 Error Value"; + f2_error.data->desc = "Error value of the F2 Costas loop after each active bit period + + This register is write-to-capture. + + To read data the following steps are required: + + 1 - Write any value to this register to capture read data + + 2 - Read the register"; + + tx_sync_ctrl Tx_Sync_Ctrl; + tx_sync_cnt Tx_Sync_Cnt; + lowpass_ema_alpha lowpass_ema_alpha1; + lowpass_ema_alpha lowpass_ema_alpha2; + rx_power rx_power; + + status_reg tx_async_fifo_rd_wr_ptr; + tx_async_fifo_rd_wr_ptr->name = "Tx async FIFO read and write pointers"; + tx_async_fifo_rd_wr_ptr->desc = "Tx async FIFO read and write pointers"; + tx_async_fifo_rd_wr_ptr.data->desc = "Read and Write Pointers + + [code] + Bits 31:16 - write pointer (12-bits) + Bits 15:00 - read pointer (12-bits) + [/code] + + This register is write-to-capture. To read data the following steps are required: + [list=1] + [*] Write any value to this register to capture read data + [*] Read the register + [/list]"; + + status_reg rx_async_fifo_rd_wr_ptr; + rx_async_fifo_rd_wr_ptr->name = "Rx async FIFO read and write pointers"; + rx_async_fifo_rd_wr_ptr->desc = "Rx async FIFO read and write pointers"; + rx_async_fifo_rd_wr_ptr.data->desc = "Read and Write Pointers + + [code] + Bits 31:16 - write pointer (12-bits) + Bits 15:00 - read pointer (12-bits) + [/code] + + This register is write-to-capture. To read data the following steps are required: + [list=1] + [*] Write any value to this register to capture read data + [*] Read the register + [/list]"; + + frame_sync_status rx_frame_sync_status; + +}; diff --git a/rdl/src/reg_utils.vhd b/rdl/src/reg_utils.vhd new file mode 100644 index 0000000..bfb9e85 --- /dev/null +++ b/rdl/src/reg_utils.vhd @@ -0,0 +1,233 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use ieee.fixed_pkg.all; + +-- Convenience types and utility functions used by the autogenerated regblock code +package reg_utils is + + type std_logic_array1 is array(natural range<>) of std_logic; + type std_logic_array2 is array(natural range<>, natural range<>) of std_logic; + type std_logic_array3 is array(natural range<>, natural range<>, natural range<>) of std_logic; + type std_logic_array4 is array(natural range<>, natural range<>, natural range<>, natural range<>) of std_logic; + type std_logic_array5 is array(natural range<>, natural range<>, natural range<>, natural range<>, natural range<>) of std_logic; + + type std_logic_vector_array1 is array(natural range<>) of std_logic_vector; + type std_logic_vector_array2 is array(natural range<>, natural range<>) of std_logic_vector; + type std_logic_vector_array3 is array(natural range<>, natural range<>, natural range<>) of std_logic_vector; + type std_logic_vector_array4 is array(natural range<>, natural range<>, natural range<>, natural range<>) of std_logic_vector; + type std_logic_vector_array5 is array(natural range<>, natural range<>, natural range<>, natural range<>, natural range<>) of std_logic_vector; + + -- reverse bits of the input vector + function bitswap(vec: in std_logic_vector) return std_logic_vector; + function bitswap(logic: in std_logic) return std_logic; + + -- Autogenerating VHDL when dealing with programmatically defined field widths + -- can be challenging, especially when doing arithmetic. These conversion functions + -- are overloaded with various input types, allow them to work regardless + -- of the input type or width. + function to_unsigned(vec: in std_logic_vector) return unsigned; + function to_unsigned(logic: in std_logic) return unsigned; + + function to_signed(vec: in std_logic_vector) return signed; + function to_signed(logic: in std_logic) return signed; + + function to_std_logic_vector(uns: in unsigned) return std_logic_vector; + function to_std_logic_vector(sgnd: in signed) return std_logic_vector; + function to_std_logic_vector(logic: in std_logic) return std_logic_vector; + -- std_logic_vector variant provided by ieee.std_logic_1164 + -- ufixed and sfixed variants are provided by ieee.fixed_pkg + + function from_std_logic_vector(vec: in std_logic_vector; slv: in std_logic_vector) return std_logic_vector; + function from_std_logic_vector(vec: in std_logic_vector; uns: in unsigned) return unsigned; + function from_std_logic_vector(vec: in std_logic_vector; sgnd: in signed) return signed; + function from_std_logic_vector(vec: in std_logic_vector; ufx: in ufixed) return ufixed; + function from_std_logic_vector(vec: in std_logic_vector; sfx: in sfixed) return sfixed; + + function to_std_logic(bool: in boolean) return std_logic; + function to_std_logic(logic: in std_logic) return std_logic; + function to_std_logic(vec: in std_logic_vector(0 downto 0)) return std_logic; + function to_std_logic(uns: in unsigned(0 downto 0)) return std_logic; + function to_std_logic(sgnd: in signed(0 downto 0)) return std_logic; + function to_std_logic(ufx: in ufixed(0 downto 0)) return std_logic; + function to_std_logic(sfx: in sfixed(0 downto 0)) return std_logic; + + function from_std_logic(logic: in std_logic; lg: in std_logic) return std_logic; + function from_std_logic(logic: in std_logic; uns: in unsigned) return unsigned; + function from_std_logic(logic: in std_logic; sgnd: in signed) return signed; + function from_std_logic(logic: in std_logic; ufx: in ufixed) return ufixed; + function from_std_logic(logic: in std_logic; sfx: in sfixed) return sfixed; + + -- reduction OR for tools with poor VHDL 2008 support + function or_reduce(vec: in std_logic_vector) return std_logic; + function or_reduce(logic: in std_logic) return std_logic; + +end package reg_utils; + +package body reg_utils is + + function bitswap(vec: in std_logic_vector) return std_logic_vector is + variable result: std_logic_vector(vec'RANGE); + alias swapped: std_logic_vector(vec'REVERSE_RANGE) is vec; + begin + for i in swapped'RANGE loop + result(i) := swapped(i); + end loop; + return result; + end function; + + function bitswap(logic: in std_logic) return std_logic is + begin + return logic; + end function; + + function to_unsigned(vec: in std_logic_vector) return unsigned is + begin + return unsigned(vec); + end function; + + function to_unsigned(logic: in std_logic) return unsigned is + variable result: unsigned(0 downto 0); + begin + result(0) := logic; + return result; + end function; + + function to_signed(vec: in std_logic_vector) return signed is + begin + return signed(vec); + end function; + + function to_signed(logic: in std_logic) return signed is + variable result: signed(0 downto 0); + begin + result(0) := logic; + return result; + end function; + + function to_std_logic_vector(uns: in unsigned) return std_logic_vector is + begin + return std_logic_vector(uns); + end function; + + function to_std_logic_vector(sgnd: in signed) return std_logic_vector is + begin + return std_logic_vector(sgnd); + end function; + + function to_std_logic_vector(logic: in std_logic) return std_logic_vector is + variable result: std_logic_vector(0 downto 0); + begin + result(0) := logic; + return result; + end function; + + + function from_std_logic_vector(vec: in std_logic_vector; slv: in std_logic_vector) return std_logic_vector is + begin + return vec; + end function; + + function from_std_logic_vector(vec: in std_logic_vector; uns: in unsigned) return unsigned is + begin + return unsigned(vec); + end function; + + function from_std_logic_vector(vec: in std_logic_vector; sgnd: in signed) return signed is + begin + return signed(vec); + end function; + + function from_std_logic_vector(vec: in std_logic_vector; ufx: in ufixed) return ufixed is + begin + return ufixed(vec); + end function; + + function from_std_logic_vector(vec: in std_logic_vector; sfx: in sfixed) return sfixed is + begin + return sfixed(vec); + end function; + + + function to_std_logic(bool: in boolean) return std_logic is + begin + if bool = TRUE then + return '1'; + else + return '0'; + end if; + end function; + + function to_std_logic(logic: in std_logic) return std_logic is + begin + return logic; + end function; + + function to_std_logic(vec: in std_logic_vector(0 downto 0)) return std_logic is + begin + return vec(0); + end function; + + function to_std_logic(uns: in unsigned(0 downto 0)) return std_logic is + begin + return uns(0); + end function; + + function to_std_logic(sgnd: in signed(0 downto 0)) return std_logic is + begin + return sgnd(0); + end function; + + function to_std_logic(ufx: in ufixed(0 downto 0)) return std_logic is + begin + return ufx(0); + end function; + + function to_std_logic(sfx: in sfixed(0 downto 0)) return std_logic is + begin + return sfx(0); + end function; + + + function from_std_logic(logic: in std_logic; lg: in std_logic) return std_logic is + begin + return logic; + end function; + + function from_std_logic(logic: in std_logic; uns: in unsigned) return unsigned is + begin + return to_unsigned(logic); + end function; + + function from_std_logic(logic: in std_logic; sgnd: in signed) return signed is + begin + return to_signed(logic); + end function; + + function from_std_logic(logic: in std_logic; ufx: in ufixed) return ufixed is + begin + return ufixed(to_unsigned(logic)); + end function; + + function from_std_logic(logic: in std_logic; sfx: in sfixed) return sfixed is + begin + return sfixed(to_signed(logic)); + end function; + + + function or_reduce(vec: in std_logic_vector) return std_logic is + variable result: std_logic; + begin + result := '0'; + for i in vec'RANGE loop + result := result or vec(i); + end loop; + return result; + end function; + + function or_reduce(logic: in std_logic) return std_logic is + begin + return logic; + end function; + +end package body; \ No newline at end of file diff --git a/rdl/src/regblock_udps.rdl b/rdl/src/regblock_udps.rdl new file mode 100644 index 0000000..eafdc5a --- /dev/null +++ b/rdl/src/regblock_udps.rdl @@ -0,0 +1,54 @@ +/* + * This file defines several property extensions that are understood by the + * PeakRDL-Regblock-vhdl code generator. + * + * Compile this file prior to your other SystemRDL sources. + * + * For more details, see: https://peakrdl-regblock-vhdl.readthedocs.io/en/latest/udps/intro.html + */ + +property buffer_reads { + component = reg; + type = boolean; +}; + +property rbuffer_trigger { + component = reg; + type = ref; +}; + +property buffer_writes { + component = reg; + type = boolean; +}; + +property wbuffer_trigger { + component = reg; + type = ref; +}; + +property rd_swacc { + component = field; + type = boolean; +}; + +property wr_swacc { + component = field; + type = boolean; +}; + +property is_signed { + type = boolean; + component = field; + default = true; +}; + +property intwidth { + type = longint unsigned; + component = field; +}; + +property fracwidth { + type = longint unsigned; + component = field; +}; diff --git a/rdl/vhdl/desyrdl/pkg_desyrdl_common.vhd b/rdl/vhdl/desyrdl/pkg_desyrdl_common.vhd deleted file mode 100644 index b630a3b..0000000 --- a/rdl/vhdl/desyrdl/pkg_desyrdl_common.vhd +++ /dev/null @@ -1,266 +0,0 @@ -------------------------------------------------------------------------------- --- ____ _____________ __ -- --- / __ \/ ____/ ___/\ \/ / _ _ _ -- --- / / / / __/ \__ \ \ / / \ / \ / \ -- --- / /_/ / /___ ___/ / / / = ( M | S | K )= -- --- /_____/_____//____/ /_/ \_/ \_/ \_/ -- --- -- -------------------------------------------------------------------------------- ---! @copyright Copyright 2021-2022 DESY ---! SPDX-License-Identifier: Apache-2.0 -------------------------------------------------------------------------------- ---! @date 2021-08-04 ---! @author Michael Büchler ---! @author Lukasz Butkowski -------------------------------------------------------------------------------- ---! @brief Package with common DesyRDL components -------------------------------------------------------------------------------- - -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - --- library desy; --- use desy.common_types.all; --- use desy.common_axi.all; - -package common is - - constant C_AXI4L_ADDR_WIDTH : natural := 32; - constant C_AXI4L_DATA_WIDTH : natural := 32; - - --------------------------------------------------------------------------- - -- common type definitions - -- type t_4b_slv_array is array (integer range<>) of std_logic_vector( 3 downto 0) ; - -- type t_32b_slv_array is array (integer range<>) of std_logic_vector(31 downto 0) ; - -- type t_integer_array is array (integer range<>) of integer ; - - --============================================================================ - -- AXI4-Lite - --============================================================================ - type t_axi4l_m2s is record - -- write address channel signals--------------------------------------------- - awaddr : std_logic_vector(C_AXI4L_ADDR_WIDTH-1 downto 0); - awprot : std_logic_vector(2 downto 0); - awvalid : std_logic; - -- write data channel signals--------------------------------------------- - wdata : std_logic_vector(C_AXI4L_DATA_WIDTH-1 downto 0); - wstrb : std_logic_vector(C_AXI4L_DATA_WIDTH/8-1 downto 0); - wvalid : std_logic; - -- write response channel signals - bready : std_logic; - -- read address channel signals --------------------------------------------- - araddr : std_logic_vector(C_AXI4L_ADDR_WIDTH-1 downto 0); - arprot : std_logic_vector(2 downto 0); - arvalid : std_logic; - -- read data channel signals--------------------------------------------- - rready : std_logic; - end record t_axi4l_m2s; - - type t_axi4l_s2m is record - -- write address channel signals--------------------------------------------- - awready : std_logic; - -- write data channel signals--------------------------------------------- - wready : std_logic; - -- write response channel signals --------------------------------------------- - bresp : std_logic_vector(1 downto 0); - bvalid : std_logic; - -- read address channel signals--------------------------------------------- - arready : std_logic; - -- read data channel signals--------------------------------------------- - rdata : std_logic_vector(C_AXI4L_DATA_WIDTH-1 downto 0); - rresp : std_logic_vector(1 downto 0); - rvalid : std_logic; - end record t_axi4l_s2m; - - type t_axi4l_m2s_vector is array (integer range <>) of t_axi4l_m2s; - type t_axi4l_s2m_vector is array (integer range <>) of t_axi4l_s2m; - - constant C_AXI4L_S2M_DEFAULT : t_axi4l_s2m := ( - awready => '0', - wready => '0', - bresp => (others => '0'), - bvalid => '0', - arready => '0' , - rdata => (others => '0'), - rresp => (others => '0'), - rvalid => '0' - ); - constant C_AXI4L_M2S_DEFAULT : t_axi4l_m2s := ( - awaddr => (others => '0'), - awprot => (others => '0'), - awvalid => '0', - wdata => (others => '0'), - wstrb => (others => '0'), - wvalid => '0', - bready => '0', - araddr => (others => '0'), - arprot => (others => '0'), - arvalid => '0', - rready => '0' - ); - - --------------------------------------------------------------------------- - -- Interface definitions for IBUS - -- Internal BUS (IBUS) is the internal bus used in the applications of MSK Firmware - -- repository. - - -- Output signals of IBUS. Through this record the application send data/commands to the bus - type t_ibus_m2s is record - addr : std_logic_vector(31 downto 0); - data : std_logic_vector(31 downto 0); - rena : std_logic; - wena : std_logic; - end record t_ibus_m2s; - - -- Output signals of IBUS. Through this record the application send data/commands to the bus - type t_ibus_s2m is record - data : std_logic_vector(31 downto 0); - rack : std_logic; - wack : std_logic; - end record t_ibus_s2m; - - -- Array of IBUS outputs - type t_ibus_m2s_vector is array (integer range<>) of t_ibus_m2s; - - -- Array of IBUS inputs - type t_ibus_s2m_vector is array (integer range<>) of t_ibus_s2m; - - -- Default IBUS connections for the output (All entries equals 0) - constant C_IBUS_M2S_DEFAULT : t_ibus_m2s := ( - addr => (others => '0'), - data => (others => '0'), - rena => '0', - wena => '0' - ); - -- Default IBUS connections for the input (All entries equals 0) - constant C_IBUS_S2M_DEFAULT : t_ibus_s2m := ( - data => (others => '0'), - rack => '0', - wack => '0' - ); - - - --------------------------------------------------------------------------- - -- SystemRDL-specific definitions - --type t_field_access is (R, W, RW, NA); - subtype t_access_type is integer; - constant C_NA : integer := 1; - constant C_RW : integer := 2; - constant C_R : integer := 3; - constant C_W : integer := 4; - constant C_RW1 : integer := 5; - constant C_W1 : integer := 6; - - type t_field_type is (STORAGE, WIRE, COUNTER, INTERRUPT); - - type t_field_info is record - ftype : t_field_type; - len : integer; - upper : integer; - lower : integer; - sw : t_access_type; - hw : t_access_type; - we : integer; - incrwidth : integer; - decrwidth : integer; - defval : integer; - end record; - - type t_field_info_vector is array (integer range <>) of t_field_info; - - constant C_FIELD_NONE : t_field_info := (WIRE, 0, 0, 0, C_NA, C_NA, 0, 0, 0, 0); - - type t_reg_info is record - -- index : integer; - address : unsigned(C_AXI4L_ADDR_WIDTH-1 downto 0); - elements : integer; - index : integer; - fields : t_field_info_vector(31 downto 0); - --dim : natural; - dim_n : positive; - dim_m : positive; - end record; - - type t_reg_info_vector is array (integer range <>) of t_reg_info; - - constant C_REG_NONE : t_reg_info := (x"0000_0000", 0, 0,(others => C_FIELD_NONE),1,1); - - type t_mem_info is record - -- index : integer; - address : unsigned(C_AXI4L_ADDR_WIDTH-1 downto 0); - addrwidth : integer; - datawidth : integer; - entries : integer; - sw : t_access_type; - end record; - - type t_mem_info_vector is array (integer range <>) of t_mem_info; - - constant C_MEM_NONE : t_mem_info := (x"0000_0000", 0, 0, 0, C_NA); - - type t_ext_info is record - -- index : integer; - address : unsigned(C_AXI4L_ADDR_WIDTH-1 downto 0); - addrwidth : integer; - size : integer; - end record; - - type t_ext_info_vector is array (integer range <>) of t_ext_info; - - constant C_EXT_NONE : t_ext_info := (x"0000_0000", 0, 0); - - -- interface types - type t_if_type Is (DPM, AXI4, AXI4L, IBUS, WISHBONE, AVALON, NONE); - type t_if_type_vector is array (integer range <>) of t_if_type; - - ----------------------------------------------------------------------------- - -- bus converter components - component axi4l_to_axi4l is - port ( - pi_reset : in std_logic; - pi_clock : in std_logic; - pi_s_decoder : in t_axi4l_m2s; - po_s_decoder : out t_axi4l_s2m; - po_m_ext : out t_axi4l_m2s; - pi_m_ext : in t_axi4l_s2m); - end component axi4l_to_axi4l; - - component axi4l_to_ibus is - port ( - pi_reset : in std_logic; - pi_clock : in std_logic; - pi_s_decoder : in t_axi4l_m2s; - po_s_decoder : out t_axi4l_s2m; - po_m_ext : out t_ibus_m2s; - pi_m_ext : in t_ibus_s2m); - end component axi4l_to_ibus; - - component ibus_to_axi4l is - port ( - pi_reset : in std_logic; - pi_clock : in std_logic; - pi_s_decoder : in t_ibus_m2s; - po_s_decoder : out t_ibus_s2m; - po_m_ext : out t_axi4l_m2s; - pi_m_ext : in t_axi4l_s2m); - end component ibus_to_axi4l; - - --common functions - -- intr_or_reduce - or recuce for interrupt register - function intr_or_reduce (arg: std_logic_vector) return std_logic; - -end package common; - ---============================================================================== -package body common is - function intr_or_reduce (arg : std_logic_vector) return std_logic is - constant C_ZEROES : std_logic_vector(arg'length - 1 downto 0) := (others => '0'); - begin -- function intr_or_reduce - if (arg = C_ZEROES) then - return '0'; - else - return '1'; - end if; - end function intr_or_reduce; -end package body; \ No newline at end of file diff --git a/rdl/vhdl/msk_top_regs/msk_top_regs.vhd b/rdl/vhdl/msk_top_regs/msk_top_regs.vhd deleted file mode 100644 index a0ba184..0000000 --- a/rdl/vhdl/msk_top_regs/msk_top_regs.vhd +++ /dev/null @@ -1,792 +0,0 @@ ------------------------------------------------------------------------------- --- ____ _____________ __ -- --- / __ \/ ____/ ___/\ \/ / _ _ _ -- --- / / / / __/ \__ \ \ / / \ / \ / \ -- --- / /_/ / /___ ___/ / / / = ( M | S | K )= -- --- /_____/_____//____/ /_/ \_/ \_/ \_/ -- --- -- ------------------------------------------------------------------------------- ---! @copyright Copyright 2021-2022 DESY ---! SPDX-License-Identifier: Apache-2.0 ------------------------------------------------------------------------------- ---! @date 2021-04-07 ---! @author Michael Büchler ---! @author Lukasz Butkowski ------------------------------------------------------------------------------- ---! @brief ---! Top component of DesyRDL address space decoder for msk_top_regs ------------------------------------------------------------------------------- - -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -library desyrdl; -use desyrdl.common.all; - -use work.pkg_msk_top_regs.all; - -entity msk_top_regs is - port ( - pi_clock : in std_logic; - pi_reset : in std_logic; - -- TOP subordinate memory mapped interface - pi_s_reset : in std_logic := '0'; - pi_s_top : in t_msk_top_regs_m2s; - po_s_top : out t_msk_top_regs_s2m; - -- to logic interface - pi_addrmap : in t_addrmap_msk_top_regs_in; - po_addrmap : out t_addrmap_msk_top_regs_out - ); -end entity msk_top_regs; - -architecture arch of msk_top_regs is - - type t_data_out is array (natural range<>) of std_logic_vector(C_DATA_WIDTH-1 downto 0) ; - - -- - signal reg_data_out_vect : t_data_out(36-1 downto 0); - signal reg_rd_stb : std_logic_vector(36-1 downto 0); - signal reg_wr_stb : std_logic_vector(36-1 downto 0); - signal reg_data_in : std_logic_vector(C_DATA_WIDTH-1 downto 0); - signal reg_data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); - -- - -begin - - ins_decoder_axi4l : entity work.msk_top_regs_decoder_axi4l - generic map ( - g_addr_width => C_ADDR_WIDTH, - g_data_width => C_DATA_WIDTH - ) - port map ( - pi_clock => pi_clock, - pi_reset => pi_reset, - - -- - po_reg_rd_stb => reg_rd_stb, - po_reg_wr_stb => reg_wr_stb, - po_reg_data => reg_data_in, - pi_reg_data => reg_data_out, - -- - -- - -- - -- - pi_s_reset => pi_s_reset, - pi_s_top => pi_s_top, - po_s_top => po_s_top - ); - -- - prs_reg_rd_mux: process(pi_clock) - begin - if rising_edge(pi_clock) then - for idx in 0 to 36-1 loop - if reg_rd_stb(idx) = '1' then - reg_data_out <= reg_data_out_vect(idx); - end if; - end loop; - end if; - end process prs_reg_rd_mux; - -- - -- - -- - - -- =========================================================================== - -- generated registers instances - -- --------------------------------------------------------------------------- - -- reg name: Hash_ID_Low reg type: msk_hash_lo - -- --------------------------------------------------------------------------- - blk_Hash_ID_Low : block - begin -- - inst_Hash_ID_Low: entity work.msk_top_regs_msk_hash_lo - port map( - pi_clock => pi_clock, - pi_reset => pi_reset, - -- to/from adapter - pi_decoder_rd_stb => reg_rd_stb(0), - pi_decoder_wr_stb => reg_wr_stb(0), - pi_decoder_data => reg_data_in, - po_decoder_data => reg_data_out_vect(0), - - pi_reg => pi_addrmap.Hash_ID_Low, - po_reg => po_addrmap.Hash_ID_Low - ); -- - end block; -- - -- --------------------------------------------------------------------------- - -- reg name: Hash_ID_High reg type: msk_hash_hi - -- --------------------------------------------------------------------------- - blk_Hash_ID_High : block - begin -- - inst_Hash_ID_High: entity work.msk_top_regs_msk_hash_hi - port map( - pi_clock => pi_clock, - pi_reset => pi_reset, - -- to/from adapter - pi_decoder_rd_stb => reg_rd_stb(1), - pi_decoder_wr_stb => reg_wr_stb(1), - pi_decoder_data => reg_data_in, - po_decoder_data => reg_data_out_vect(1), - - pi_reg => pi_addrmap.Hash_ID_High, - po_reg => po_addrmap.Hash_ID_High - ); -- - end block; -- - -- --------------------------------------------------------------------------- - -- reg name: MSK_Init reg type: msk_init - -- --------------------------------------------------------------------------- - blk_MSK_Init : block - begin -- - inst_MSK_Init: entity work.msk_top_regs_msk_init - port map( - pi_clock => pi_clock, - pi_reset => pi_reset, - -- to/from adapter - pi_decoder_rd_stb => reg_rd_stb(2), - pi_decoder_wr_stb => reg_wr_stb(2), - pi_decoder_data => reg_data_in, - po_decoder_data => reg_data_out_vect(2), - - pi_reg => pi_addrmap.MSK_Init, - po_reg => po_addrmap.MSK_Init - ); -- - end block; -- - -- --------------------------------------------------------------------------- - -- reg name: MSK_Control reg type: msk_ctrl - -- --------------------------------------------------------------------------- - blk_MSK_Control : block - begin -- - inst_MSK_Control: entity work.msk_top_regs_msk_ctrl - port map( - pi_clock => pi_clock, - pi_reset => pi_reset, - -- to/from adapter - pi_decoder_rd_stb => reg_rd_stb(3), - pi_decoder_wr_stb => reg_wr_stb(3), - pi_decoder_data => reg_data_in, - po_decoder_data => reg_data_out_vect(3), - - pi_reg => pi_addrmap.MSK_Control, - po_reg => po_addrmap.MSK_Control - ); -- - end block; -- - -- --------------------------------------------------------------------------- - -- reg name: MSK_Status reg type: msk_stat_0 - -- --------------------------------------------------------------------------- - blk_MSK_Status : block - begin -- - inst_MSK_Status: entity work.msk_top_regs_msk_stat_0 - port map( - pi_clock => pi_clock, - pi_reset => pi_reset, - -- to/from adapter - pi_decoder_rd_stb => reg_rd_stb(4), - pi_decoder_wr_stb => reg_wr_stb(4), - pi_decoder_data => reg_data_in, - po_decoder_data => reg_data_out_vect(4), - - pi_reg => pi_addrmap.MSK_Status, - po_reg => po_addrmap.MSK_Status - ); -- - end block; -- - -- --------------------------------------------------------------------------- - -- reg name: Tx_Bit_Count reg type: msk_stat_1 - -- --------------------------------------------------------------------------- - blk_Tx_Bit_Count : block - begin -- - inst_Tx_Bit_Count: entity work.msk_top_regs_msk_stat_1 - port map( - pi_clock => pi_clock, - pi_reset => pi_reset, - -- to/from adapter - pi_decoder_rd_stb => reg_rd_stb(5), - pi_decoder_wr_stb => reg_wr_stb(5), - pi_decoder_data => reg_data_in, - po_decoder_data => reg_data_out_vect(5), - - pi_reg => pi_addrmap.Tx_Bit_Count, - po_reg => po_addrmap.Tx_Bit_Count - ); -- - end block; -- - -- --------------------------------------------------------------------------- - -- reg name: Tx_Enable_Count reg type: msk_stat_2 - -- --------------------------------------------------------------------------- - blk_Tx_Enable_Count : block - begin -- - inst_Tx_Enable_Count: entity work.msk_top_regs_msk_stat_2 - port map( - pi_clock => pi_clock, - pi_reset => pi_reset, - -- to/from adapter - pi_decoder_rd_stb => reg_rd_stb(6), - pi_decoder_wr_stb => reg_wr_stb(6), - pi_decoder_data => reg_data_in, - po_decoder_data => reg_data_out_vect(6), - - pi_reg => pi_addrmap.Tx_Enable_Count, - po_reg => po_addrmap.Tx_Enable_Count - ); -- - end block; -- - -- --------------------------------------------------------------------------- - -- reg name: Fb_FreqWord reg type: config_nco_fw - -- --------------------------------------------------------------------------- - blk_Fb_FreqWord : block - begin -- - inst_Fb_FreqWord: entity work.msk_top_regs_config_nco_fw - port map( - pi_clock => pi_clock, - pi_reset => pi_reset, - -- to/from adapter - pi_decoder_rd_stb => reg_rd_stb(7), - pi_decoder_wr_stb => reg_wr_stb(7), - pi_decoder_data => reg_data_in, - po_decoder_data => reg_data_out_vect(7), - - pi_reg => pi_addrmap.Fb_FreqWord, - po_reg => po_addrmap.Fb_FreqWord - ); -- - end block; -- - -- --------------------------------------------------------------------------- - -- reg name: TX_F1_FreqWord reg type: config_nco_fw - -- --------------------------------------------------------------------------- - blk_TX_F1_FreqWord : block - begin -- - inst_TX_F1_FreqWord: entity work.msk_top_regs_config_nco_fw - port map( - pi_clock => pi_clock, - pi_reset => pi_reset, - -- to/from adapter - pi_decoder_rd_stb => reg_rd_stb(8), - pi_decoder_wr_stb => reg_wr_stb(8), - pi_decoder_data => reg_data_in, - po_decoder_data => reg_data_out_vect(8), - - pi_reg => pi_addrmap.TX_F1_FreqWord, - po_reg => po_addrmap.TX_F1_FreqWord - ); -- - end block; -- - -- --------------------------------------------------------------------------- - -- reg name: TX_F2_FreqWord reg type: config_nco_fw - -- --------------------------------------------------------------------------- - blk_TX_F2_FreqWord : block - begin -- - inst_TX_F2_FreqWord: entity work.msk_top_regs_config_nco_fw - port map( - pi_clock => pi_clock, - pi_reset => pi_reset, - -- to/from adapter - pi_decoder_rd_stb => reg_rd_stb(9), - pi_decoder_wr_stb => reg_wr_stb(9), - pi_decoder_data => reg_data_in, - po_decoder_data => reg_data_out_vect(9), - - pi_reg => pi_addrmap.TX_F2_FreqWord, - po_reg => po_addrmap.TX_F2_FreqWord - ); -- - end block; -- - -- --------------------------------------------------------------------------- - -- reg name: RX_F1_FreqWord reg type: config_nco_fw - -- --------------------------------------------------------------------------- - blk_RX_F1_FreqWord : block - begin -- - inst_RX_F1_FreqWord: entity work.msk_top_regs_config_nco_fw - port map( - pi_clock => pi_clock, - pi_reset => pi_reset, - -- to/from adapter - pi_decoder_rd_stb => reg_rd_stb(10), - pi_decoder_wr_stb => reg_wr_stb(10), - pi_decoder_data => reg_data_in, - po_decoder_data => reg_data_out_vect(10), - - pi_reg => pi_addrmap.RX_F1_FreqWord, - po_reg => po_addrmap.RX_F1_FreqWord - ); -- - end block; -- - -- --------------------------------------------------------------------------- - -- reg name: RX_F2_FreqWord reg type: config_nco_fw - -- --------------------------------------------------------------------------- - blk_RX_F2_FreqWord : block - begin -- - inst_RX_F2_FreqWord: entity work.msk_top_regs_config_nco_fw - port map( - pi_clock => pi_clock, - pi_reset => pi_reset, - -- to/from adapter - pi_decoder_rd_stb => reg_rd_stb(11), - pi_decoder_wr_stb => reg_wr_stb(11), - pi_decoder_data => reg_data_in, - po_decoder_data => reg_data_out_vect(11), - - pi_reg => pi_addrmap.RX_F2_FreqWord, - po_reg => po_addrmap.RX_F2_FreqWord - ); -- - end block; -- - -- --------------------------------------------------------------------------- - -- reg name: LPF_Config_0 reg type: lpf_config_0 - -- --------------------------------------------------------------------------- - blk_LPF_Config_0 : block - begin -- - inst_LPF_Config_0: entity work.msk_top_regs_lpf_config_0 - port map( - pi_clock => pi_clock, - pi_reset => pi_reset, - -- to/from adapter - pi_decoder_rd_stb => reg_rd_stb(12), - pi_decoder_wr_stb => reg_wr_stb(12), - pi_decoder_data => reg_data_in, - po_decoder_data => reg_data_out_vect(12), - - pi_reg => pi_addrmap.LPF_Config_0, - po_reg => po_addrmap.LPF_Config_0 - ); -- - end block; -- - -- --------------------------------------------------------------------------- - -- reg name: LPF_Config_1 reg type: lpf_config_1 - -- --------------------------------------------------------------------------- - blk_LPF_Config_1 : block - begin -- - inst_LPF_Config_1: entity work.msk_top_regs_lpf_config_1 - port map( - pi_clock => pi_clock, - pi_reset => pi_reset, - -- to/from adapter - pi_decoder_rd_stb => reg_rd_stb(13), - pi_decoder_wr_stb => reg_wr_stb(13), - pi_decoder_data => reg_data_in, - po_decoder_data => reg_data_out_vect(13), - - pi_reg => pi_addrmap.LPF_Config_1, - po_reg => po_addrmap.LPF_Config_1 - ); -- - end block; -- - -- --------------------------------------------------------------------------- - -- reg name: Tx_Data_Width reg type: data_width - -- --------------------------------------------------------------------------- - blk_Tx_Data_Width : block - begin -- - inst_Tx_Data_Width: entity work.msk_top_regs_data_width - port map( - pi_clock => pi_clock, - pi_reset => pi_reset, - -- to/from adapter - pi_decoder_rd_stb => reg_rd_stb(14), - pi_decoder_wr_stb => reg_wr_stb(14), - pi_decoder_data => reg_data_in, - po_decoder_data => reg_data_out_vect(14), - - pi_reg => pi_addrmap.Tx_Data_Width, - po_reg => po_addrmap.Tx_Data_Width - ); -- - end block; -- - -- --------------------------------------------------------------------------- - -- reg name: Rx_Data_Width reg type: data_width - -- --------------------------------------------------------------------------- - blk_Rx_Data_Width : block - begin -- - inst_Rx_Data_Width: entity work.msk_top_regs_data_width - port map( - pi_clock => pi_clock, - pi_reset => pi_reset, - -- to/from adapter - pi_decoder_rd_stb => reg_rd_stb(15), - pi_decoder_wr_stb => reg_wr_stb(15), - pi_decoder_data => reg_data_in, - po_decoder_data => reg_data_out_vect(15), - - pi_reg => pi_addrmap.Rx_Data_Width, - po_reg => po_addrmap.Rx_Data_Width - ); -- - end block; -- - -- --------------------------------------------------------------------------- - -- reg name: PRBS_Control reg type: prbs_ctrl - -- --------------------------------------------------------------------------- - blk_PRBS_Control : block - begin -- - inst_PRBS_Control: entity work.msk_top_regs_prbs_ctrl - port map( - pi_clock => pi_clock, - pi_reset => pi_reset, - -- to/from adapter - pi_decoder_rd_stb => reg_rd_stb(16), - pi_decoder_wr_stb => reg_wr_stb(16), - pi_decoder_data => reg_data_in, - po_decoder_data => reg_data_out_vect(16), - - pi_reg => pi_addrmap.PRBS_Control, - po_reg => po_addrmap.PRBS_Control - ); -- - end block; -- - -- --------------------------------------------------------------------------- - -- reg name: PRBS_Initial_State reg type: config_prbs_seed - -- --------------------------------------------------------------------------- - blk_PRBS_Initial_State : block - begin -- - inst_PRBS_Initial_State: entity work.msk_top_regs_config_prbs_seed - port map( - pi_clock => pi_clock, - pi_reset => pi_reset, - -- to/from adapter - pi_decoder_rd_stb => reg_rd_stb(17), - pi_decoder_wr_stb => reg_wr_stb(17), - pi_decoder_data => reg_data_in, - po_decoder_data => reg_data_out_vect(17), - - pi_reg => pi_addrmap.PRBS_Initial_State, - po_reg => po_addrmap.PRBS_Initial_State - ); -- - end block; -- - -- --------------------------------------------------------------------------- - -- reg name: PRBS_Polynomial reg type: config_prbs_poly - -- --------------------------------------------------------------------------- - blk_PRBS_Polynomial : block - begin -- - inst_PRBS_Polynomial: entity work.msk_top_regs_config_prbs_poly - port map( - pi_clock => pi_clock, - pi_reset => pi_reset, - -- to/from adapter - pi_decoder_rd_stb => reg_rd_stb(18), - pi_decoder_wr_stb => reg_wr_stb(18), - pi_decoder_data => reg_data_in, - po_decoder_data => reg_data_out_vect(18), - - pi_reg => pi_addrmap.PRBS_Polynomial, - po_reg => po_addrmap.PRBS_Polynomial - ); -- - end block; -- - -- --------------------------------------------------------------------------- - -- reg name: PRBS_Error_Mask reg type: config_prbs_errmask - -- --------------------------------------------------------------------------- - blk_PRBS_Error_Mask : block - begin -- - inst_PRBS_Error_Mask: entity work.msk_top_regs_config_prbs_errmask - port map( - pi_clock => pi_clock, - pi_reset => pi_reset, - -- to/from adapter - pi_decoder_rd_stb => reg_rd_stb(19), - pi_decoder_wr_stb => reg_wr_stb(19), - pi_decoder_data => reg_data_in, - po_decoder_data => reg_data_out_vect(19), - - pi_reg => pi_addrmap.PRBS_Error_Mask, - po_reg => po_addrmap.PRBS_Error_Mask - ); -- - end block; -- - -- --------------------------------------------------------------------------- - -- reg name: PRBS_Bit_Count reg type: stat_32_bits - -- --------------------------------------------------------------------------- - blk_PRBS_Bit_Count : block - begin -- - inst_PRBS_Bit_Count: entity work.msk_top_regs_stat_32_bits - port map( - pi_clock => pi_clock, - pi_reset => pi_reset, - -- to/from adapter - pi_decoder_rd_stb => reg_rd_stb(20), - pi_decoder_wr_stb => reg_wr_stb(20), - pi_decoder_data => reg_data_in, - po_decoder_data => reg_data_out_vect(20), - - pi_reg => pi_addrmap.PRBS_Bit_Count, - po_reg => po_addrmap.PRBS_Bit_Count - ); -- - end block; -- - -- --------------------------------------------------------------------------- - -- reg name: PRBS_Error_Count reg type: stat_32_errs - -- --------------------------------------------------------------------------- - blk_PRBS_Error_Count : block - begin -- - inst_PRBS_Error_Count: entity work.msk_top_regs_stat_32_errs - port map( - pi_clock => pi_clock, - pi_reset => pi_reset, - -- to/from adapter - pi_decoder_rd_stb => reg_rd_stb(21), - pi_decoder_wr_stb => reg_wr_stb(21), - pi_decoder_data => reg_data_in, - po_decoder_data => reg_data_out_vect(21), - - pi_reg => pi_addrmap.PRBS_Error_Count, - po_reg => po_addrmap.PRBS_Error_Count - ); -- - end block; -- - -- --------------------------------------------------------------------------- - -- reg name: LPF_Accum_F1 reg type: stat_32_lpf_acc - -- --------------------------------------------------------------------------- - blk_LPF_Accum_F1 : block - begin -- - inst_LPF_Accum_F1: entity work.msk_top_regs_stat_32_lpf_acc - port map( - pi_clock => pi_clock, - pi_reset => pi_reset, - -- to/from adapter - pi_decoder_rd_stb => reg_rd_stb(22), - pi_decoder_wr_stb => reg_wr_stb(22), - pi_decoder_data => reg_data_in, - po_decoder_data => reg_data_out_vect(22), - - pi_reg => pi_addrmap.LPF_Accum_F1, - po_reg => po_addrmap.LPF_Accum_F1 - ); -- - end block; -- - -- --------------------------------------------------------------------------- - -- reg name: LPF_Accum_F2 reg type: stat_32_lpf_acc - -- --------------------------------------------------------------------------- - blk_LPF_Accum_F2 : block - begin -- - inst_LPF_Accum_F2: entity work.msk_top_regs_stat_32_lpf_acc - port map( - pi_clock => pi_clock, - pi_reset => pi_reset, - -- to/from adapter - pi_decoder_rd_stb => reg_rd_stb(23), - pi_decoder_wr_stb => reg_wr_stb(23), - pi_decoder_data => reg_data_in, - po_decoder_data => reg_data_out_vect(23), - - pi_reg => pi_addrmap.LPF_Accum_F2, - po_reg => po_addrmap.LPF_Accum_F2 - ); -- - end block; -- - -- --------------------------------------------------------------------------- - -- reg name: axis_xfer_count reg type: msk_stat_3 - -- --------------------------------------------------------------------------- - blk_axis_xfer_count : block - begin -- - inst_axis_xfer_count: entity work.msk_top_regs_msk_stat_3 - port map( - pi_clock => pi_clock, - pi_reset => pi_reset, - -- to/from adapter - pi_decoder_rd_stb => reg_rd_stb(24), - pi_decoder_wr_stb => reg_wr_stb(24), - pi_decoder_data => reg_data_in, - po_decoder_data => reg_data_out_vect(24), - - pi_reg => pi_addrmap.axis_xfer_count, - po_reg => po_addrmap.axis_xfer_count - ); -- - end block; -- - -- --------------------------------------------------------------------------- - -- reg name: Rx_Sample_Discard reg type: rx_sample_discard - -- --------------------------------------------------------------------------- - blk_Rx_Sample_Discard : block - begin -- - inst_Rx_Sample_Discard: entity work.msk_top_regs_rx_sample_discard - port map( - pi_clock => pi_clock, - pi_reset => pi_reset, - -- to/from adapter - pi_decoder_rd_stb => reg_rd_stb(25), - pi_decoder_wr_stb => reg_wr_stb(25), - pi_decoder_data => reg_data_in, - po_decoder_data => reg_data_out_vect(25), - - pi_reg => pi_addrmap.Rx_Sample_Discard, - po_reg => po_addrmap.Rx_Sample_Discard - ); -- - end block; -- - -- --------------------------------------------------------------------------- - -- reg name: LPF_Config_2 reg type: lpf_config_2 - -- --------------------------------------------------------------------------- - blk_LPF_Config_2 : block - begin -- - inst_LPF_Config_2: entity work.msk_top_regs_lpf_config_2 - port map( - pi_clock => pi_clock, - pi_reset => pi_reset, - -- to/from adapter - pi_decoder_rd_stb => reg_rd_stb(26), - pi_decoder_wr_stb => reg_wr_stb(26), - pi_decoder_data => reg_data_in, - po_decoder_data => reg_data_out_vect(26), - - pi_reg => pi_addrmap.LPF_Config_2, - po_reg => po_addrmap.LPF_Config_2 - ); -- - end block; -- - -- --------------------------------------------------------------------------- - -- reg name: f1_nco_adjust reg type: observation_data - -- --------------------------------------------------------------------------- - blk_f1_nco_adjust : block - begin -- - inst_f1_nco_adjust: entity work.msk_top_regs_observation_data - port map( - pi_clock => pi_clock, - pi_reset => pi_reset, - -- to/from adapter - pi_decoder_rd_stb => reg_rd_stb(27), - pi_decoder_wr_stb => reg_wr_stb(27), - pi_decoder_data => reg_data_in, - po_decoder_data => reg_data_out_vect(27), - - pi_reg => pi_addrmap.f1_nco_adjust, - po_reg => po_addrmap.f1_nco_adjust - ); -- - end block; -- - -- --------------------------------------------------------------------------- - -- reg name: f2_nco_adjust reg type: observation_data - -- --------------------------------------------------------------------------- - blk_f2_nco_adjust : block - begin -- - inst_f2_nco_adjust: entity work.msk_top_regs_observation_data - port map( - pi_clock => pi_clock, - pi_reset => pi_reset, - -- to/from adapter - pi_decoder_rd_stb => reg_rd_stb(28), - pi_decoder_wr_stb => reg_wr_stb(28), - pi_decoder_data => reg_data_in, - po_decoder_data => reg_data_out_vect(28), - - pi_reg => pi_addrmap.f2_nco_adjust, - po_reg => po_addrmap.f2_nco_adjust - ); -- - end block; -- - -- --------------------------------------------------------------------------- - -- reg name: f1_error reg type: observation_data - -- --------------------------------------------------------------------------- - blk_f1_error : block - begin -- - inst_f1_error: entity work.msk_top_regs_observation_data - port map( - pi_clock => pi_clock, - pi_reset => pi_reset, - -- to/from adapter - pi_decoder_rd_stb => reg_rd_stb(29), - pi_decoder_wr_stb => reg_wr_stb(29), - pi_decoder_data => reg_data_in, - po_decoder_data => reg_data_out_vect(29), - - pi_reg => pi_addrmap.f1_error, - po_reg => po_addrmap.f1_error - ); -- - end block; -- - -- --------------------------------------------------------------------------- - -- reg name: f2_error reg type: observation_data - -- --------------------------------------------------------------------------- - blk_f2_error : block - begin -- - inst_f2_error: entity work.msk_top_regs_observation_data - port map( - pi_clock => pi_clock, - pi_reset => pi_reset, - -- to/from adapter - pi_decoder_rd_stb => reg_rd_stb(30), - pi_decoder_wr_stb => reg_wr_stb(30), - pi_decoder_data => reg_data_in, - po_decoder_data => reg_data_out_vect(30), - - pi_reg => pi_addrmap.f2_error, - po_reg => po_addrmap.f2_error - ); -- - end block; -- - -- --------------------------------------------------------------------------- - -- reg name: Tx_Sync_Ctrl reg type: tx_sync_ctrl - -- --------------------------------------------------------------------------- - blk_Tx_Sync_Ctrl : block - begin -- - inst_Tx_Sync_Ctrl: entity work.msk_top_regs_tx_sync_ctrl - port map( - pi_clock => pi_clock, - pi_reset => pi_reset, - -- to/from adapter - pi_decoder_rd_stb => reg_rd_stb(31), - pi_decoder_wr_stb => reg_wr_stb(31), - pi_decoder_data => reg_data_in, - po_decoder_data => reg_data_out_vect(31), - - pi_reg => pi_addrmap.Tx_Sync_Ctrl, - po_reg => po_addrmap.Tx_Sync_Ctrl - ); -- - end block; -- - -- --------------------------------------------------------------------------- - -- reg name: Tx_Sync_Cnt reg type: tx_sync_cnt - -- --------------------------------------------------------------------------- - blk_Tx_Sync_Cnt : block - begin -- - inst_Tx_Sync_Cnt: entity work.msk_top_regs_tx_sync_cnt - port map( - pi_clock => pi_clock, - pi_reset => pi_reset, - -- to/from adapter - pi_decoder_rd_stb => reg_rd_stb(32), - pi_decoder_wr_stb => reg_wr_stb(32), - pi_decoder_data => reg_data_in, - po_decoder_data => reg_data_out_vect(32), - - pi_reg => pi_addrmap.Tx_Sync_Cnt, - po_reg => po_addrmap.Tx_Sync_Cnt - ); -- - end block; -- - -- --------------------------------------------------------------------------- - -- reg name: lowpass_ema_alpha1 reg type: lowpass_ema_alpha - -- --------------------------------------------------------------------------- - blk_lowpass_ema_alpha1 : block - begin -- - inst_lowpass_ema_alpha1: entity work.msk_top_regs_lowpass_ema_alpha - port map( - pi_clock => pi_clock, - pi_reset => pi_reset, - -- to/from adapter - pi_decoder_rd_stb => reg_rd_stb(33), - pi_decoder_wr_stb => reg_wr_stb(33), - pi_decoder_data => reg_data_in, - po_decoder_data => reg_data_out_vect(33), - - pi_reg => pi_addrmap.lowpass_ema_alpha1, - po_reg => po_addrmap.lowpass_ema_alpha1 - ); -- - end block; -- - -- --------------------------------------------------------------------------- - -- reg name: lowpass_ema_alpha2 reg type: lowpass_ema_alpha - -- --------------------------------------------------------------------------- - blk_lowpass_ema_alpha2 : block - begin -- - inst_lowpass_ema_alpha2: entity work.msk_top_regs_lowpass_ema_alpha - port map( - pi_clock => pi_clock, - pi_reset => pi_reset, - -- to/from adapter - pi_decoder_rd_stb => reg_rd_stb(34), - pi_decoder_wr_stb => reg_wr_stb(34), - pi_decoder_data => reg_data_in, - po_decoder_data => reg_data_out_vect(34), - - pi_reg => pi_addrmap.lowpass_ema_alpha2, - po_reg => po_addrmap.lowpass_ema_alpha2 - ); -- - end block; -- - -- --------------------------------------------------------------------------- - -- reg name: rx_power reg type: rx_power - -- --------------------------------------------------------------------------- - blk_rx_power : block - begin -- - inst_rx_power: entity work.msk_top_regs_rx_power - port map( - pi_clock => pi_clock, - pi_reset => pi_reset, - -- to/from adapter - pi_decoder_rd_stb => reg_rd_stb(35), - pi_decoder_wr_stb => reg_wr_stb(35), - pi_decoder_data => reg_data_in, - po_decoder_data => reg_data_out_vect(35), - - pi_reg => pi_addrmap.rx_power, - po_reg => po_addrmap.rx_power - ); -- - end block; -- - - -- =========================================================================== - -- generated registers instances in regfiles - - -- =========================================================================== - -- Generated Mem Instances - -- - -- --------------------------------------------------------------------------- - - -- =========================================================================== - -- External Busses - -end architecture; diff --git a/rdl/vhdl/msk_top_regs/msk_top_regs_decoder_axi4l.vhd b/rdl/vhdl/msk_top_regs/msk_top_regs_decoder_axi4l.vhd deleted file mode 100644 index 6a4f008..0000000 --- a/rdl/vhdl/msk_top_regs/msk_top_regs_decoder_axi4l.vhd +++ /dev/null @@ -1,536 +0,0 @@ ------------------------------------------------------------------------------- --- ____ _____________ __ -- --- / __ \/ ____/ ___/\ \/ / _ _ _ -- --- / / / / __/ \__ \ \ / / \ / \ / \ -- --- / /_/ / /___ ___/ / / / = ( M | S | K )= -- --- /_____/_____//____/ /_/ \_/ \_/ \_/ -- --- -- ------------------------------------------------------------------------------- ---! @copyright Copyright 2020-2022 DESY ---! SPDX-License-Identifier: Apache-2.0 ------------------------------------------------------------------------------- ---! @date 2020-05-25/2021-10-12 ---! @author Lukasz Butkowski ---! @author Michael Büchler ------------------------------------------------------------------------------- ---! @brief ---! ax4-lite address decoder for DesyRdl ------------------------------------------------------------------------------- - - -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -library desyrdl; -use desyrdl.common.all; - -entity msk_top_regs_decoder_axi4l is - generic ( - G_ADDR_WIDTH : integer := 32; - G_DATA_WIDTH : integer := 32 - ); - port ( - pi_clock : in std_logic; - pi_reset : in std_logic; - -- - po_reg_rd_stb : out std_logic_vector(36-1 downto 0); - po_reg_wr_stb : out std_logic_vector(36-1 downto 0); - po_reg_data : out std_logic_vector(G_DATA_WIDTH-1 downto 0); - pi_reg_data : in std_logic_vector(G_DATA_WIDTH-1 downto 0); - -- - -- - -- - -- - pi_s_reset : in std_logic; - pi_s_top : in t_axi4l_m2s ; - po_s_top : out t_axi4l_s2m -); -end entity msk_top_regs_decoder_axi4l; - -architecture arch of msk_top_regs_decoder_axi4l is - - type t_target is (REG, NONE ); - - signal rtarget, wtarget : t_target := NONE; - - -- Standard statements - --- INLINE statement with -- # - ---------------------------------------------------------- - -- read - type t_state_read is ( - ST_READ_IDLE, - ST_READ_SELECT, - ST_READ_VALID, - ST_READ_REG_BUSY, -- when no address hit, dummy reg - ST_READ_DONE - ); - signal state_read : t_state_read; - - signal rdata_reg : std_logic_vector(G_DATA_WIDTH-1 downto 0); - signal rdata_rgf : std_logic_vector(G_DATA_WIDTH-1 downto 0); - signal rdata_mem : std_logic_vector(G_DATA_WIDTH-1 downto 0); - signal rdata_ext : std_logic_vector(G_DATA_WIDTH-1 downto 0); - - signal rdata : std_logic_vector(G_DATA_WIDTH-1 downto 0) := (others => '0'); - signal raddr : std_logic_vector(G_ADDR_WIDTH-1 downto 0) := (others => '0'); - signal raddr_int : integer; - - ---------------------------------------------------------- - -- write - type t_state_write is ( - ST_WRITE_IDLE, - ST_WRITE_WAIT_DATA, - ST_WRITE_WAIT_ADDR, - ST_WRITE_SELECT, - ST_WRITE_RESP - ); - signal state_write : t_state_write; - - signal wdata : std_logic_vector(G_DATA_WIDTH-1 downto 0) := (others => '0'); - signal wstrb : std_logic_vector(G_DATA_WIDTH/8-1 downto 0) := (others => '0'); - signal waddr : std_logic_vector(G_ADDR_WIDTH-1 downto 0) := (others => '0'); - signal waddr_int : integer; - signal wvalid : std_logic; - - ----------------------------------------------------------- - signal reg_rd_stb : std_logic_vector(36-1 downto 0) := (others => '0'); - signal reg_wr_stb : std_logic_vector(36-1 downto 0) := (others => '0'); - - -- external bus - - constant read_timeout : natural := 8191; - constant write_timeout : natural := 8191; - signal read_time_cnt : natural := 0; - signal write_time_cnt : natural := 0; - signal invalid_rdata : std_logic ; - - signal reset : std_logic; -begin - - -- main reset - global or bus reset - reset <= pi_reset or pi_s_reset; - - -- =========================================================================== - -- ### read logic - ------------------------------------------------------------------------------ - -- read channel state machine - ------------------------------------------------------------------------------ - prs_state_read: process (pi_clock) - begin - if rising_edge(pi_clock) then - if reset = '1' then - state_read <= ST_READ_IDLE; - invalid_rdata <= '0'; - else - case state_read is - when ST_READ_IDLE => - - if pi_s_top.arvalid = '1' then - state_read <= ST_READ_SELECT; - end if; - invalid_rdata <= '0'; - when ST_READ_SELECT => - case rtarget is - when REG => - state_read <= ST_READ_VALID; - when others => - state_read <= ST_READ_REG_BUSY; - end case; - - when ST_READ_REG_BUSY => - state_read <= ST_READ_VALID; - - when ST_READ_VALID => - if pi_s_top.rready = '1' then - state_read <= ST_READ_DONE; - end if; - - when ST_READ_DONE => - state_read <= ST_READ_IDLE; - - when others => - state_read <= ST_READ_IDLE; - - end case; - - end if; - end if; - end process; - po_s_top.rresp <= "00"; - ------------------------------------------------------------------------------ - -- read data mux - prs_rdata_mux: process(rtarget,rdata_reg,invalid_rdata) - begin - if invalid_rdata = '1' then - po_s_top.rdata <= (others => '0' ) ; - elsif rtarget = REG then - po_s_top.rdata <= rdata_reg ; - else - po_s_top.rdata <= (others => '0' ) ; - end if; - end process prs_rdata_mux; - - ------------------------------------------------------------------------------ - -- ARREADY flag handling - prs_axi_arready: process (state_read) - begin - case state_read is - when ST_READ_IDLE => - po_s_top.arready <= '1'; - when others => - po_s_top.arready <= '0'; - end case; - end process; - - -- RVALID flag handling - prs_axi_rvalid: process ( - state_read) - begin - case state_read is - when ST_READ_VALID => - po_s_top.rvalid <= '1'; - when others => - po_s_top.rvalid <= '0'; - end case; - end process; - - ------------------------------------------------------------------------------ - -- Address decoder - ------------------------------------------------------------------------------ - raddr_int <= to_integer(unsigned(pi_s_top.araddr(G_ADDR_WIDTH-1 downto 0))); - - prs_raddr_decoder: process(pi_clock) - begin - if rising_edge(pi_clock) then - if state_read = ST_READ_IDLE and pi_s_top.arvalid = '1' then - reg_rd_stb <= (others => '0'); - case raddr_int is - when 0 => - rtarget <= REG; - reg_rd_stb(0) <= '1'; - when 4 => - rtarget <= REG; - reg_rd_stb(1) <= '1'; - when 8 => - rtarget <= REG; - reg_rd_stb(2) <= '1'; - when 12 => - rtarget <= REG; - reg_rd_stb(3) <= '1'; - when 16 => - rtarget <= REG; - reg_rd_stb(4) <= '1'; - when 20 => - rtarget <= REG; - reg_rd_stb(5) <= '1'; - when 24 => - rtarget <= REG; - reg_rd_stb(6) <= '1'; - when 28 => - rtarget <= REG; - reg_rd_stb(7) <= '1'; - when 32 => - rtarget <= REG; - reg_rd_stb(8) <= '1'; - when 36 => - rtarget <= REG; - reg_rd_stb(9) <= '1'; - when 40 => - rtarget <= REG; - reg_rd_stb(10) <= '1'; - when 44 => - rtarget <= REG; - reg_rd_stb(11) <= '1'; - when 48 => - rtarget <= REG; - reg_rd_stb(12) <= '1'; - when 52 => - rtarget <= REG; - reg_rd_stb(13) <= '1'; - when 56 => - rtarget <= REG; - reg_rd_stb(14) <= '1'; - when 60 => - rtarget <= REG; - reg_rd_stb(15) <= '1'; - when 64 => - rtarget <= REG; - reg_rd_stb(16) <= '1'; - when 68 => - rtarget <= REG; - reg_rd_stb(17) <= '1'; - when 72 => - rtarget <= REG; - reg_rd_stb(18) <= '1'; - when 76 => - rtarget <= REG; - reg_rd_stb(19) <= '1'; - when 80 => - rtarget <= REG; - reg_rd_stb(20) <= '1'; - when 84 => - rtarget <= REG; - reg_rd_stb(21) <= '1'; - when 88 => - rtarget <= REG; - reg_rd_stb(22) <= '1'; - when 92 => - rtarget <= REG; - reg_rd_stb(23) <= '1'; - when 96 => - rtarget <= REG; - reg_rd_stb(24) <= '1'; - when 100 => - rtarget <= REG; - reg_rd_stb(25) <= '1'; - when 104 => - rtarget <= REG; - reg_rd_stb(26) <= '1'; - when 108 => - rtarget <= REG; - reg_rd_stb(27) <= '1'; - when 112 => - rtarget <= REG; - reg_rd_stb(28) <= '1'; - when 116 => - rtarget <= REG; - reg_rd_stb(29) <= '1'; - when 120 => - rtarget <= REG; - reg_rd_stb(30) <= '1'; - when 124 => - rtarget <= REG; - reg_rd_stb(31) <= '1'; - when 128 => - rtarget <= REG; - reg_rd_stb(32) <= '1'; - when 132 => - rtarget <= REG; - reg_rd_stb(33) <= '1'; - when 136 => - rtarget <= REG; - reg_rd_stb(34) <= '1'; - when 140 => - rtarget <= REG; - reg_rd_stb(35) <= '1'; - when others => - rtarget <= NONE; - end case; - - elsif state_read = ST_READ_DONE then - reg_rd_stb <= (others => '0'); - - end if; - end if; - end process prs_raddr_decoder; - ---------------------------------------------------------- - -- - - -- =========================================================================== - -- ### write logic - ------------------------------------------------------------------------------ - -- Write channel state machine - ------------------------------------------------------------------------------ - prs_state_write: process (pi_clock) - begin - if rising_edge (pi_clock) then - if reset = '1' then - state_write <= ST_WRITE_IDLE; - else - case state_write is - when ST_WRITE_IDLE => - - if pi_s_top.awvalid = '1' and pi_s_top.wvalid = '1' then - state_write <= ST_WRITE_SELECT; - elsif pi_s_top.awvalid = '1' and pi_s_top.wvalid = '0' then - state_write <= ST_WRITE_WAIT_DATA; - elsif pi_s_top.awvalid = '0' and pi_s_top.wvalid = '1' then - state_write <= ST_WRITE_WAIT_ADDR; - end if; - - when ST_WRITE_WAIT_DATA => - if pi_s_top.wvalid = '1' then - state_write <= ST_WRITE_SELECT; - end if; - - when ST_WRITE_WAIT_ADDR => - if pi_s_top.awvalid = '1' then - state_write <= ST_WRITE_SELECT; - end if; - - when ST_WRITE_SELECT => - case wtarget is - when REG => - state_write <= ST_WRITE_RESP; - when others => - state_write <= ST_WRITE_RESP; -- every write transaction must end with response - end case; - - when ST_WRITE_RESP => - if pi_s_top.bready = '1' then - state_write <= ST_WRITE_IDLE; - end if; - - when others => - state_write <= ST_WRITE_IDLE; - - end case; - end if; - end if; - end process; - - ------------------------------------------------------------------------------ - -- WRITE AXI handshaking - po_s_top.bresp <= "00"; - - prs_axi_bvalid: process (state_write) - begin - case state_write is - when ST_WRITE_RESP => - po_s_top.bvalid <= '1'; - when others => - po_s_top.bvalid <= '0'; - end case; - end process; - - prs_axi_awready: process (state_write) - begin - case state_write is - when ST_WRITE_IDLE | ST_WRITE_WAIT_ADDR => - po_s_top.awready <= '1'; - when others => - po_s_top.awready <= '0'; - end case; - end process; - - prs_axi_wready: process (state_write) - begin - case state_write is - when ST_WRITE_IDLE | ST_WRITE_WAIT_DATA => - po_s_top.wready <= '1'; - when others => - po_s_top.wready <= '0'; - end case; - end process; - - ------------------------------------------------------------------------------ - -- write Address decoder - ------------------------------------------------------------------------------ - waddr_int <= to_integer(unsigned(pi_s_top.awaddr(G_ADDR_WIDTH-1 downto 0))); - - prs_waddr_decoder: process(pi_clock) - begin - if rising_edge(pi_clock) then - if (state_write = ST_WRITE_IDLE or state_write = ST_WRITE_WAIT_ADDR ) and pi_s_top.awvalid = '1' then - reg_wr_stb <= (others => '0'); - case waddr_int is - when 8 => - wtarget <= REG; - reg_wr_stb(2) <= '1'; - when 12 => - wtarget <= REG; - reg_wr_stb(3) <= '1'; - when 28 => - wtarget <= REG; - reg_wr_stb(7) <= '1'; - when 32 => - wtarget <= REG; - reg_wr_stb(8) <= '1'; - when 36 => - wtarget <= REG; - reg_wr_stb(9) <= '1'; - when 40 => - wtarget <= REG; - reg_wr_stb(10) <= '1'; - when 44 => - wtarget <= REG; - reg_wr_stb(11) <= '1'; - when 48 => - wtarget <= REG; - reg_wr_stb(12) <= '1'; - when 52 => - wtarget <= REG; - reg_wr_stb(13) <= '1'; - when 56 => - wtarget <= REG; - reg_wr_stb(14) <= '1'; - when 60 => - wtarget <= REG; - reg_wr_stb(15) <= '1'; - when 64 => - wtarget <= REG; - reg_wr_stb(16) <= '1'; - when 68 => - wtarget <= REG; - reg_wr_stb(17) <= '1'; - when 72 => - wtarget <= REG; - reg_wr_stb(18) <= '1'; - when 76 => - wtarget <= REG; - reg_wr_stb(19) <= '1'; - when 100 => - wtarget <= REG; - reg_wr_stb(25) <= '1'; - when 104 => - wtarget <= REG; - reg_wr_stb(26) <= '1'; - when 124 => - wtarget <= REG; - reg_wr_stb(31) <= '1'; - when 128 => - wtarget <= REG; - reg_wr_stb(32) <= '1'; - when 132 => - wtarget <= REG; - reg_wr_stb(33) <= '1'; - when 136 => - wtarget <= REG; - reg_wr_stb(34) <= '1'; - when others => - wtarget <= NONE; - end case; - - elsif state_write = ST_WRITE_RESP then - reg_wr_stb <= (others => '0'); - end if; - end if; - end process prs_waddr_decoder; - ---------------------------------------------------------- - -- - - prs_wvalid_reg : process(pi_clock) - begin - if rising_edge(pi_clock) then - if state_write = ST_WRITE_IDLE or state_write = ST_WRITE_WAIT_DATA then - wvalid <= pi_s_top.wvalid; - elsif state_write = ST_WRITE_RESP then - wvalid <= '0'; - end if; - end if; - end process; - - prs_wdata_reg : process(pi_clock) - begin - if rising_edge(pi_clock) then - if state_write = ST_WRITE_IDLE or state_write = ST_WRITE_WAIT_DATA then - wdata <= pi_s_top.wdata; - end if; - end if; - end process prs_wdata_reg ; - - -- =========================================================================== - -- OUTPUT - -- =========================================================================== - -- registers - ------------------------------------------------------------------------------ - gen_reg_wr_str: for ridx in 0 to 36-1 generate - po_reg_wr_stb(ridx) <= reg_wr_stb(ridx) and wvalid; - end generate; - po_reg_data <= wdata; - po_reg_rd_stb <= reg_rd_stb; - rdata_reg <= pi_reg_data ; - -end architecture arch; diff --git a/rdl/vhdl/msk_top_regs/pkg_msk_top_regs.vhd b/rdl/vhdl/msk_top_regs/pkg_msk_top_regs.vhd deleted file mode 100644 index 42ebf24..0000000 --- a/rdl/vhdl/msk_top_regs/pkg_msk_top_regs.vhd +++ /dev/null @@ -1,3394 +0,0 @@ ------------------------------------------------------------------------------- --- ____ _____________ __ -- --- / __ \/ ____/ ___/\ \/ / _ _ _ -- --- / / / / __/ \__ \ \ / / \ / \ / \ -- --- / /_/ / /___ ___/ / / / = ( M | S | K )= -- --- /_____/_____//____/ /_/ \_/ \_/ \_/ -- --- -- ------------------------------------------------------------------------------- ---! @copyright Copyright 2021-2022 DESY ---! SPDX-License-Identifier: Apache-2.0 ------------------------------------------------------------------------------- ---! @date 2021-10-01 ---! @author Michael Büchler ---! @author Lukasz Butkowski ------------------------------------------------------------------------------- ---! @brief ---! VHDL package of DesyRDL for address space decoder for msk_top_regs ------------------------------------------------------------------------------- - -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -library desyrdl; -use desyrdl.common.all; - --- library desy; --- use desy.common_axi.all; - -package pkg_msk_top_regs is - - ----------------------------------------------- - -- per addrmap / module - ----------------------------------------------- - constant C_ADDR_WIDTH : integer := 8; - constant C_DATA_WIDTH : integer := 32; - - -- =========================================================================== - -- --------------------------------------------------------------------------- - -- registers - -- --------------------------------------------------------------------------- - - -- =========================================================================== - -- REGISTERS interface - -- --------------------------------------------------------------------------- - -- register type: msk_hash_lo - ----------------------------------------------- - type t_field_signals_msk_hash_lo_hash_id_lo_in is record - -- no data if field cannot be written from hw - data : std_logic_vector(-1 downto 0); -- - end record; - - type t_field_signals_msk_hash_lo_hash_id_lo_out is record - -- no data if field cannot be written from hw - dummy : std_logic; -- - end record; -- - - -- The actual register types - type t_reg_msk_hash_lo_in is record-- - hash_id_lo : t_field_signals_msk_hash_lo_hash_id_lo_in; -- - end record; - type t_reg_msk_hash_lo_out is record-- - hash_id_lo : t_field_signals_msk_hash_lo_hash_id_lo_out; -- - end record; - type t_reg_msk_hash_lo_2d_in is array (integer range <>) of t_reg_msk_hash_lo_in; - type t_reg_msk_hash_lo_2d_out is array (integer range <>) of t_reg_msk_hash_lo_out; - type t_reg_msk_hash_lo_3d_in is array (integer range <>, integer range <>) of t_reg_msk_hash_lo_in; - type t_reg_msk_hash_lo_3d_out is array (integer range <>, integer range <>) of t_reg_msk_hash_lo_out; - ----------------------------------------------- - -- register type: msk_hash_hi - ----------------------------------------------- - type t_field_signals_msk_hash_hi_hash_id_hi_in is record - -- no data if field cannot be written from hw - data : std_logic_vector(-1 downto 0); -- - end record; - - type t_field_signals_msk_hash_hi_hash_id_hi_out is record - -- no data if field cannot be written from hw - dummy : std_logic; -- - end record; -- - - -- The actual register types - type t_reg_msk_hash_hi_in is record-- - hash_id_hi : t_field_signals_msk_hash_hi_hash_id_hi_in; -- - end record; - type t_reg_msk_hash_hi_out is record-- - hash_id_hi : t_field_signals_msk_hash_hi_hash_id_hi_out; -- - end record; - type t_reg_msk_hash_hi_2d_in is array (integer range <>) of t_reg_msk_hash_hi_in; - type t_reg_msk_hash_hi_2d_out is array (integer range <>) of t_reg_msk_hash_hi_out; - type t_reg_msk_hash_hi_3d_in is array (integer range <>, integer range <>) of t_reg_msk_hash_hi_in; - type t_reg_msk_hash_hi_3d_out is array (integer range <>, integer range <>) of t_reg_msk_hash_hi_out; - ----------------------------------------------- - -- register type: msk_init - ----------------------------------------------- - type t_field_signals_msk_init_txrxinit_in is record - -- no data if field cannot be written from hw - data : std_logic_vector(-1 downto 0); -- - end record; - - type t_field_signals_msk_init_txrxinit_out is record - data : std_logic_vector(1-1 downto 0); -- - end record; -- - type t_field_signals_msk_init_txinit_in is record - -- no data if field cannot be written from hw - data : std_logic_vector(-1 downto 0); -- - end record; - - type t_field_signals_msk_init_txinit_out is record - data : std_logic_vector(1-1 downto 0); -- - end record; -- - type t_field_signals_msk_init_rxinit_in is record - -- no data if field cannot be written from hw - data : std_logic_vector(-1 downto 0); -- - end record; - - type t_field_signals_msk_init_rxinit_out is record - data : std_logic_vector(1-1 downto 0); -- - end record; -- - - -- The actual register types - type t_reg_msk_init_in is record-- - txrxinit : t_field_signals_msk_init_txrxinit_in; -- - txinit : t_field_signals_msk_init_txinit_in; -- - rxinit : t_field_signals_msk_init_rxinit_in; -- - end record; - type t_reg_msk_init_out is record-- - txrxinit : t_field_signals_msk_init_txrxinit_out; -- - txinit : t_field_signals_msk_init_txinit_out; -- - rxinit : t_field_signals_msk_init_rxinit_out; -- - end record; - type t_reg_msk_init_2d_in is array (integer range <>) of t_reg_msk_init_in; - type t_reg_msk_init_2d_out is array (integer range <>) of t_reg_msk_init_out; - type t_reg_msk_init_3d_in is array (integer range <>, integer range <>) of t_reg_msk_init_in; - type t_reg_msk_init_3d_out is array (integer range <>, integer range <>) of t_reg_msk_init_out; - ----------------------------------------------- - -- register type: msk_ctrl - ----------------------------------------------- - type t_field_signals_msk_ctrl_ptt_in is record - -- no data if field cannot be written from hw - data : std_logic_vector(-1 downto 0); -- - end record; - - type t_field_signals_msk_ctrl_ptt_out is record - data : std_logic_vector(1-1 downto 0); -- - end record; -- - type t_field_signals_msk_ctrl_loopback_ena_in is record - -- no data if field cannot be written from hw - data : std_logic_vector(-1 downto 0); -- - end record; - - type t_field_signals_msk_ctrl_loopback_ena_out is record - data : std_logic_vector(1-1 downto 0); -- - end record; -- - type t_field_signals_msk_ctrl_rx_invert_in is record - -- no data if field cannot be written from hw - data : std_logic_vector(-1 downto 0); -- - end record; - - type t_field_signals_msk_ctrl_rx_invert_out is record - data : std_logic_vector(1-1 downto 0); -- - end record; -- - type t_field_signals_msk_ctrl_clear_counts_in is record - -- no data if field cannot be written from hw - data : std_logic_vector(-1 downto 0); -- - end record; - - type t_field_signals_msk_ctrl_clear_counts_out is record - data : std_logic_vector(1-1 downto 0); -- - end record; -- - type t_field_signals_msk_ctrl_diff_encoder_loopback_in is record - -- no data if field cannot be written from hw - data : std_logic_vector(-1 downto 0); -- - end record; - - type t_field_signals_msk_ctrl_diff_encoder_loopback_out is record - data : std_logic_vector(1-1 downto 0); -- - end record; -- - - -- The actual register types - type t_reg_msk_ctrl_in is record-- - ptt : t_field_signals_msk_ctrl_ptt_in; -- - loopback_ena : t_field_signals_msk_ctrl_loopback_ena_in; -- - rx_invert : t_field_signals_msk_ctrl_rx_invert_in; -- - clear_counts : t_field_signals_msk_ctrl_clear_counts_in; -- - diff_encoder_loopback : t_field_signals_msk_ctrl_diff_encoder_loopback_in; -- - end record; - type t_reg_msk_ctrl_out is record-- - ptt : t_field_signals_msk_ctrl_ptt_out; -- - loopback_ena : t_field_signals_msk_ctrl_loopback_ena_out; -- - rx_invert : t_field_signals_msk_ctrl_rx_invert_out; -- - clear_counts : t_field_signals_msk_ctrl_clear_counts_out; -- - diff_encoder_loopback : t_field_signals_msk_ctrl_diff_encoder_loopback_out; -- - end record; - type t_reg_msk_ctrl_2d_in is array (integer range <>) of t_reg_msk_ctrl_in; - type t_reg_msk_ctrl_2d_out is array (integer range <>) of t_reg_msk_ctrl_out; - type t_reg_msk_ctrl_3d_in is array (integer range <>, integer range <>) of t_reg_msk_ctrl_in; - type t_reg_msk_ctrl_3d_out is array (integer range <>, integer range <>) of t_reg_msk_ctrl_out; - ----------------------------------------------- - -- register type: msk_stat_0 - ----------------------------------------------- - type t_field_signals_msk_stat_0_demod_sync_lock_in is record - data : std_logic_vector(1-1 downto 0); -- - end record; - - type t_field_signals_msk_stat_0_demod_sync_lock_out is record - -- no data if field cannot be written from hw - dummy : std_logic; -- - end record; -- - type t_field_signals_msk_stat_0_tx_enable_in is record - data : std_logic_vector(1-1 downto 0); -- - end record; - - type t_field_signals_msk_stat_0_tx_enable_out is record - -- no data if field cannot be written from hw - dummy : std_logic; -- - end record; -- - type t_field_signals_msk_stat_0_rx_enable_in is record - data : std_logic_vector(1-1 downto 0); -- - end record; - - type t_field_signals_msk_stat_0_rx_enable_out is record - -- no data if field cannot be written from hw - dummy : std_logic; -- - end record; -- - type t_field_signals_msk_stat_0_tx_axis_valid_in is record - data : std_logic_vector(1-1 downto 0); -- - end record; - - type t_field_signals_msk_stat_0_tx_axis_valid_out is record - -- no data if field cannot be written from hw - dummy : std_logic; -- - end record; -- - - -- The actual register types - type t_reg_msk_stat_0_in is record-- - demod_sync_lock : t_field_signals_msk_stat_0_demod_sync_lock_in; -- - tx_enable : t_field_signals_msk_stat_0_tx_enable_in; -- - rx_enable : t_field_signals_msk_stat_0_rx_enable_in; -- - tx_axis_valid : t_field_signals_msk_stat_0_tx_axis_valid_in; -- - end record; - type t_reg_msk_stat_0_out is record-- - demod_sync_lock : t_field_signals_msk_stat_0_demod_sync_lock_out; -- - tx_enable : t_field_signals_msk_stat_0_tx_enable_out; -- - rx_enable : t_field_signals_msk_stat_0_rx_enable_out; -- - tx_axis_valid : t_field_signals_msk_stat_0_tx_axis_valid_out; -- - end record; - type t_reg_msk_stat_0_2d_in is array (integer range <>) of t_reg_msk_stat_0_in; - type t_reg_msk_stat_0_2d_out is array (integer range <>) of t_reg_msk_stat_0_out; - type t_reg_msk_stat_0_3d_in is array (integer range <>, integer range <>) of t_reg_msk_stat_0_in; - type t_reg_msk_stat_0_3d_out is array (integer range <>, integer range <>) of t_reg_msk_stat_0_out; - ----------------------------------------------- - -- register type: msk_stat_1 - ----------------------------------------------- - type t_field_signals_msk_stat_1_tx_bit_counter_in is record - data : std_logic_vector(32-1 downto 0); -- - end record; - - type t_field_signals_msk_stat_1_tx_bit_counter_out is record - -- no data if field cannot be written from hw - dummy : std_logic; -- - end record; -- - - -- The actual register types - type t_reg_msk_stat_1_in is record-- - tx_bit_counter : t_field_signals_msk_stat_1_tx_bit_counter_in; -- - end record; - type t_reg_msk_stat_1_out is record-- - tx_bit_counter : t_field_signals_msk_stat_1_tx_bit_counter_out; -- - end record; - type t_reg_msk_stat_1_2d_in is array (integer range <>) of t_reg_msk_stat_1_in; - type t_reg_msk_stat_1_2d_out is array (integer range <>) of t_reg_msk_stat_1_out; - type t_reg_msk_stat_1_3d_in is array (integer range <>, integer range <>) of t_reg_msk_stat_1_in; - type t_reg_msk_stat_1_3d_out is array (integer range <>, integer range <>) of t_reg_msk_stat_1_out; - ----------------------------------------------- - -- register type: msk_stat_2 - ----------------------------------------------- - type t_field_signals_msk_stat_2_tx_ena_counter_in is record - data : std_logic_vector(32-1 downto 0); -- - end record; - - type t_field_signals_msk_stat_2_tx_ena_counter_out is record - -- no data if field cannot be written from hw - dummy : std_logic; -- - end record; -- - - -- The actual register types - type t_reg_msk_stat_2_in is record-- - tx_ena_counter : t_field_signals_msk_stat_2_tx_ena_counter_in; -- - end record; - type t_reg_msk_stat_2_out is record-- - tx_ena_counter : t_field_signals_msk_stat_2_tx_ena_counter_out; -- - end record; - type t_reg_msk_stat_2_2d_in is array (integer range <>) of t_reg_msk_stat_2_in; - type t_reg_msk_stat_2_2d_out is array (integer range <>) of t_reg_msk_stat_2_out; - type t_reg_msk_stat_2_3d_in is array (integer range <>, integer range <>) of t_reg_msk_stat_2_in; - type t_reg_msk_stat_2_3d_out is array (integer range <>, integer range <>) of t_reg_msk_stat_2_out; - ----------------------------------------------- - -- register type: config_nco_fw - ----------------------------------------------- - type t_field_signals_config_nco_fw_config_data_in is record - -- no data if field cannot be written from hw - data : std_logic_vector(-1 downto 0); -- - end record; - - type t_field_signals_config_nco_fw_config_data_out is record - data : std_logic_vector(32-1 downto 0); -- - end record; -- - - -- The actual register types - type t_reg_config_nco_fw_in is record-- - config_data : t_field_signals_config_nco_fw_config_data_in; -- - end record; - type t_reg_config_nco_fw_out is record-- - config_data : t_field_signals_config_nco_fw_config_data_out; -- - end record; - type t_reg_config_nco_fw_2d_in is array (integer range <>) of t_reg_config_nco_fw_in; - type t_reg_config_nco_fw_2d_out is array (integer range <>) of t_reg_config_nco_fw_out; - type t_reg_config_nco_fw_3d_in is array (integer range <>, integer range <>) of t_reg_config_nco_fw_in; - type t_reg_config_nco_fw_3d_out is array (integer range <>, integer range <>) of t_reg_config_nco_fw_out; - ----------------------------------------------- - -- register type: lpf_config_0 - ----------------------------------------------- - type t_field_signals_lpf_config_0_lpf_freeze_in is record - -- no data if field cannot be written from hw - data : std_logic_vector(-1 downto 0); -- - end record; - - type t_field_signals_lpf_config_0_lpf_freeze_out is record - data : std_logic_vector(1-1 downto 0); -- - end record; -- - type t_field_signals_lpf_config_0_lpf_zero_in is record - -- no data if field cannot be written from hw - data : std_logic_vector(-1 downto 0); -- - end record; - - type t_field_signals_lpf_config_0_lpf_zero_out is record - data : std_logic_vector(1-1 downto 0); -- - end record; -- - type t_field_signals_lpf_config_0_prbs_reserved_in is record - -- no data if field cannot be written from hw - data : std_logic_vector(-1 downto 0); -- - end record; - - type t_field_signals_lpf_config_0_prbs_reserved_out is record - data : std_logic_vector(6-1 downto 0); -- - end record; -- - type t_field_signals_lpf_config_0_lpf_alpha_in is record - -- no data if field cannot be written from hw - data : std_logic_vector(-1 downto 0); -- - end record; - - type t_field_signals_lpf_config_0_lpf_alpha_out is record - data : std_logic_vector(24-1 downto 0); -- - end record; -- - - -- The actual register types - type t_reg_lpf_config_0_in is record-- - lpf_freeze : t_field_signals_lpf_config_0_lpf_freeze_in; -- - lpf_zero : t_field_signals_lpf_config_0_lpf_zero_in; -- - prbs_reserved : t_field_signals_lpf_config_0_prbs_reserved_in; -- - lpf_alpha : t_field_signals_lpf_config_0_lpf_alpha_in; -- - end record; - type t_reg_lpf_config_0_out is record-- - lpf_freeze : t_field_signals_lpf_config_0_lpf_freeze_out; -- - lpf_zero : t_field_signals_lpf_config_0_lpf_zero_out; -- - prbs_reserved : t_field_signals_lpf_config_0_prbs_reserved_out; -- - lpf_alpha : t_field_signals_lpf_config_0_lpf_alpha_out; -- - end record; - type t_reg_lpf_config_0_2d_in is array (integer range <>) of t_reg_lpf_config_0_in; - type t_reg_lpf_config_0_2d_out is array (integer range <>) of t_reg_lpf_config_0_out; - type t_reg_lpf_config_0_3d_in is array (integer range <>, integer range <>) of t_reg_lpf_config_0_in; - type t_reg_lpf_config_0_3d_out is array (integer range <>, integer range <>) of t_reg_lpf_config_0_out; - ----------------------------------------------- - -- register type: lpf_config_1 - ----------------------------------------------- - type t_field_signals_lpf_config_1_i_gain_in is record - -- no data if field cannot be written from hw - data : std_logic_vector(-1 downto 0); -- - end record; - - type t_field_signals_lpf_config_1_i_gain_out is record - data : std_logic_vector(24-1 downto 0); -- - end record; -- - type t_field_signals_lpf_config_1_i_shift_in is record - -- no data if field cannot be written from hw - data : std_logic_vector(-1 downto 0); -- - end record; - - type t_field_signals_lpf_config_1_i_shift_out is record - data : std_logic_vector(8-1 downto 0); -- - end record; -- - - -- The actual register types - type t_reg_lpf_config_1_in is record-- - i_gain : t_field_signals_lpf_config_1_i_gain_in; -- - i_shift : t_field_signals_lpf_config_1_i_shift_in; -- - end record; - type t_reg_lpf_config_1_out is record-- - i_gain : t_field_signals_lpf_config_1_i_gain_out; -- - i_shift : t_field_signals_lpf_config_1_i_shift_out; -- - end record; - type t_reg_lpf_config_1_2d_in is array (integer range <>) of t_reg_lpf_config_1_in; - type t_reg_lpf_config_1_2d_out is array (integer range <>) of t_reg_lpf_config_1_out; - type t_reg_lpf_config_1_3d_in is array (integer range <>, integer range <>) of t_reg_lpf_config_1_in; - type t_reg_lpf_config_1_3d_out is array (integer range <>, integer range <>) of t_reg_lpf_config_1_out; - ----------------------------------------------- - -- register type: data_width - ----------------------------------------------- - type t_field_signals_data_width_data_width_in is record - -- no data if field cannot be written from hw - data : std_logic_vector(-1 downto 0); -- - end record; - - type t_field_signals_data_width_data_width_out is record - data : std_logic_vector(8-1 downto 0); -- - end record; -- - - -- The actual register types - type t_reg_data_width_in is record-- - data_width : t_field_signals_data_width_data_width_in; -- - end record; - type t_reg_data_width_out is record-- - data_width : t_field_signals_data_width_data_width_out; -- - end record; - type t_reg_data_width_2d_in is array (integer range <>) of t_reg_data_width_in; - type t_reg_data_width_2d_out is array (integer range <>) of t_reg_data_width_out; - type t_reg_data_width_3d_in is array (integer range <>, integer range <>) of t_reg_data_width_in; - type t_reg_data_width_3d_out is array (integer range <>, integer range <>) of t_reg_data_width_out; - ----------------------------------------------- - -- register type: prbs_ctrl - ----------------------------------------------- - type t_field_signals_prbs_ctrl_prbs_sel_in is record - -- no data if field cannot be written from hw - data : std_logic_vector(-1 downto 0); -- - end record; - - type t_field_signals_prbs_ctrl_prbs_sel_out is record - data : std_logic_vector(1-1 downto 0); -- - end record; -- - type t_field_signals_prbs_ctrl_prbs_error_insert_in is record - -- no data if field cannot be written from hw - data : std_logic_vector(-1 downto 0); -- - end record; - - type t_field_signals_prbs_ctrl_prbs_error_insert_out is record - data : std_logic_vector(1-1 downto 0); -- - end record; -- - type t_field_signals_prbs_ctrl_prbs_clear_in is record - -- no data if field cannot be written from hw - data : std_logic_vector(-1 downto 0); -- - end record; - - type t_field_signals_prbs_ctrl_prbs_clear_out is record - data : std_logic_vector(1-1 downto 0); -- - end record; -- - type t_field_signals_prbs_ctrl_prbs_manual_sync_in is record - -- no data if field cannot be written from hw - data : std_logic_vector(-1 downto 0); -- - end record; - - type t_field_signals_prbs_ctrl_prbs_manual_sync_out is record - data : std_logic_vector(1-1 downto 0); -- - end record; -- - type t_field_signals_prbs_ctrl_prbs_reserved_in is record - -- no data if field cannot be written from hw - data : std_logic_vector(-1 downto 0); -- - end record; - - type t_field_signals_prbs_ctrl_prbs_reserved_out is record - data : std_logic_vector(12-1 downto 0); -- - end record; -- - type t_field_signals_prbs_ctrl_prbs_sync_threshold_in is record - -- no data if field cannot be written from hw - data : std_logic_vector(-1 downto 0); -- - end record; - - type t_field_signals_prbs_ctrl_prbs_sync_threshold_out is record - data : std_logic_vector(16-1 downto 0); -- - end record; -- - - -- The actual register types - type t_reg_prbs_ctrl_in is record-- - prbs_sel : t_field_signals_prbs_ctrl_prbs_sel_in; -- - prbs_error_insert : t_field_signals_prbs_ctrl_prbs_error_insert_in; -- - prbs_clear : t_field_signals_prbs_ctrl_prbs_clear_in; -- - prbs_manual_sync : t_field_signals_prbs_ctrl_prbs_manual_sync_in; -- - prbs_reserved : t_field_signals_prbs_ctrl_prbs_reserved_in; -- - prbs_sync_threshold : t_field_signals_prbs_ctrl_prbs_sync_threshold_in; -- - end record; - type t_reg_prbs_ctrl_out is record-- - prbs_sel : t_field_signals_prbs_ctrl_prbs_sel_out; -- - prbs_error_insert : t_field_signals_prbs_ctrl_prbs_error_insert_out; -- - prbs_clear : t_field_signals_prbs_ctrl_prbs_clear_out; -- - prbs_manual_sync : t_field_signals_prbs_ctrl_prbs_manual_sync_out; -- - prbs_reserved : t_field_signals_prbs_ctrl_prbs_reserved_out; -- - prbs_sync_threshold : t_field_signals_prbs_ctrl_prbs_sync_threshold_out; -- - end record; - type t_reg_prbs_ctrl_2d_in is array (integer range <>) of t_reg_prbs_ctrl_in; - type t_reg_prbs_ctrl_2d_out is array (integer range <>) of t_reg_prbs_ctrl_out; - type t_reg_prbs_ctrl_3d_in is array (integer range <>, integer range <>) of t_reg_prbs_ctrl_in; - type t_reg_prbs_ctrl_3d_out is array (integer range <>, integer range <>) of t_reg_prbs_ctrl_out; - ----------------------------------------------- - -- register type: config_prbs_seed - ----------------------------------------------- - type t_field_signals_config_prbs_seed_config_data_in is record - -- no data if field cannot be written from hw - data : std_logic_vector(-1 downto 0); -- - end record; - - type t_field_signals_config_prbs_seed_config_data_out is record - data : std_logic_vector(32-1 downto 0); -- - end record; -- - - -- The actual register types - type t_reg_config_prbs_seed_in is record-- - config_data : t_field_signals_config_prbs_seed_config_data_in; -- - end record; - type t_reg_config_prbs_seed_out is record-- - config_data : t_field_signals_config_prbs_seed_config_data_out; -- - end record; - type t_reg_config_prbs_seed_2d_in is array (integer range <>) of t_reg_config_prbs_seed_in; - type t_reg_config_prbs_seed_2d_out is array (integer range <>) of t_reg_config_prbs_seed_out; - type t_reg_config_prbs_seed_3d_in is array (integer range <>, integer range <>) of t_reg_config_prbs_seed_in; - type t_reg_config_prbs_seed_3d_out is array (integer range <>, integer range <>) of t_reg_config_prbs_seed_out; - ----------------------------------------------- - -- register type: config_prbs_poly - ----------------------------------------------- - type t_field_signals_config_prbs_poly_config_data_in is record - -- no data if field cannot be written from hw - data : std_logic_vector(-1 downto 0); -- - end record; - - type t_field_signals_config_prbs_poly_config_data_out is record - data : std_logic_vector(32-1 downto 0); -- - end record; -- - - -- The actual register types - type t_reg_config_prbs_poly_in is record-- - config_data : t_field_signals_config_prbs_poly_config_data_in; -- - end record; - type t_reg_config_prbs_poly_out is record-- - config_data : t_field_signals_config_prbs_poly_config_data_out; -- - end record; - type t_reg_config_prbs_poly_2d_in is array (integer range <>) of t_reg_config_prbs_poly_in; - type t_reg_config_prbs_poly_2d_out is array (integer range <>) of t_reg_config_prbs_poly_out; - type t_reg_config_prbs_poly_3d_in is array (integer range <>, integer range <>) of t_reg_config_prbs_poly_in; - type t_reg_config_prbs_poly_3d_out is array (integer range <>, integer range <>) of t_reg_config_prbs_poly_out; - ----------------------------------------------- - -- register type: config_prbs_errmask - ----------------------------------------------- - type t_field_signals_config_prbs_errmask_config_data_in is record - -- no data if field cannot be written from hw - data : std_logic_vector(-1 downto 0); -- - end record; - - type t_field_signals_config_prbs_errmask_config_data_out is record - data : std_logic_vector(32-1 downto 0); -- - end record; -- - - -- The actual register types - type t_reg_config_prbs_errmask_in is record-- - config_data : t_field_signals_config_prbs_errmask_config_data_in; -- - end record; - type t_reg_config_prbs_errmask_out is record-- - config_data : t_field_signals_config_prbs_errmask_config_data_out; -- - end record; - type t_reg_config_prbs_errmask_2d_in is array (integer range <>) of t_reg_config_prbs_errmask_in; - type t_reg_config_prbs_errmask_2d_out is array (integer range <>) of t_reg_config_prbs_errmask_out; - type t_reg_config_prbs_errmask_3d_in is array (integer range <>, integer range <>) of t_reg_config_prbs_errmask_in; - type t_reg_config_prbs_errmask_3d_out is array (integer range <>, integer range <>) of t_reg_config_prbs_errmask_out; - ----------------------------------------------- - -- register type: stat_32_bits - ----------------------------------------------- - type t_field_signals_stat_32_bits_status_data_in is record - data : std_logic_vector(32-1 downto 0); -- - end record; - - type t_field_signals_stat_32_bits_status_data_out is record - -- no data if field cannot be written from hw - dummy : std_logic; -- - end record; -- - - -- The actual register types - type t_reg_stat_32_bits_in is record-- - status_data : t_field_signals_stat_32_bits_status_data_in; -- - end record; - type t_reg_stat_32_bits_out is record-- - status_data : t_field_signals_stat_32_bits_status_data_out; -- - end record; - type t_reg_stat_32_bits_2d_in is array (integer range <>) of t_reg_stat_32_bits_in; - type t_reg_stat_32_bits_2d_out is array (integer range <>) of t_reg_stat_32_bits_out; - type t_reg_stat_32_bits_3d_in is array (integer range <>, integer range <>) of t_reg_stat_32_bits_in; - type t_reg_stat_32_bits_3d_out is array (integer range <>, integer range <>) of t_reg_stat_32_bits_out; - ----------------------------------------------- - -- register type: stat_32_errs - ----------------------------------------------- - type t_field_signals_stat_32_errs_status_data_in is record - data : std_logic_vector(32-1 downto 0); -- - end record; - - type t_field_signals_stat_32_errs_status_data_out is record - -- no data if field cannot be written from hw - dummy : std_logic; -- - end record; -- - - -- The actual register types - type t_reg_stat_32_errs_in is record-- - status_data : t_field_signals_stat_32_errs_status_data_in; -- - end record; - type t_reg_stat_32_errs_out is record-- - status_data : t_field_signals_stat_32_errs_status_data_out; -- - end record; - type t_reg_stat_32_errs_2d_in is array (integer range <>) of t_reg_stat_32_errs_in; - type t_reg_stat_32_errs_2d_out is array (integer range <>) of t_reg_stat_32_errs_out; - type t_reg_stat_32_errs_3d_in is array (integer range <>, integer range <>) of t_reg_stat_32_errs_in; - type t_reg_stat_32_errs_3d_out is array (integer range <>, integer range <>) of t_reg_stat_32_errs_out; - ----------------------------------------------- - -- register type: stat_32_lpf_acc - ----------------------------------------------- - type t_field_signals_stat_32_lpf_acc_status_data_in is record - data : std_logic_vector(32-1 downto 0); -- - end record; - - type t_field_signals_stat_32_lpf_acc_status_data_out is record - -- no data if field cannot be written from hw - dummy : std_logic; -- - end record; -- - - -- The actual register types - type t_reg_stat_32_lpf_acc_in is record-- - status_data : t_field_signals_stat_32_lpf_acc_status_data_in; -- - end record; - type t_reg_stat_32_lpf_acc_out is record-- - status_data : t_field_signals_stat_32_lpf_acc_status_data_out; -- - end record; - type t_reg_stat_32_lpf_acc_2d_in is array (integer range <>) of t_reg_stat_32_lpf_acc_in; - type t_reg_stat_32_lpf_acc_2d_out is array (integer range <>) of t_reg_stat_32_lpf_acc_out; - type t_reg_stat_32_lpf_acc_3d_in is array (integer range <>, integer range <>) of t_reg_stat_32_lpf_acc_in; - type t_reg_stat_32_lpf_acc_3d_out is array (integer range <>, integer range <>) of t_reg_stat_32_lpf_acc_out; - ----------------------------------------------- - -- register type: msk_stat_3 - ----------------------------------------------- - type t_field_signals_msk_stat_3_xfer_count_in is record - data : std_logic_vector(32-1 downto 0); -- - end record; - - type t_field_signals_msk_stat_3_xfer_count_out is record - -- no data if field cannot be written from hw - dummy : std_logic; -- - end record; -- - - -- The actual register types - type t_reg_msk_stat_3_in is record-- - xfer_count : t_field_signals_msk_stat_3_xfer_count_in; -- - end record; - type t_reg_msk_stat_3_out is record-- - xfer_count : t_field_signals_msk_stat_3_xfer_count_out; -- - end record; - type t_reg_msk_stat_3_2d_in is array (integer range <>) of t_reg_msk_stat_3_in; - type t_reg_msk_stat_3_2d_out is array (integer range <>) of t_reg_msk_stat_3_out; - type t_reg_msk_stat_3_3d_in is array (integer range <>, integer range <>) of t_reg_msk_stat_3_in; - type t_reg_msk_stat_3_3d_out is array (integer range <>, integer range <>) of t_reg_msk_stat_3_out; - ----------------------------------------------- - -- register type: rx_sample_discard - ----------------------------------------------- - type t_field_signals_rx_sample_discard_rx_sample_discard_in is record - -- no data if field cannot be written from hw - data : std_logic_vector(-1 downto 0); -- - end record; - - type t_field_signals_rx_sample_discard_rx_sample_discard_out is record - data : std_logic_vector(8-1 downto 0); -- - end record; -- - type t_field_signals_rx_sample_discard_rx_nco_discard_in is record - -- no data if field cannot be written from hw - data : std_logic_vector(-1 downto 0); -- - end record; - - type t_field_signals_rx_sample_discard_rx_nco_discard_out is record - data : std_logic_vector(8-1 downto 0); -- - end record; -- - - -- The actual register types - type t_reg_rx_sample_discard_in is record-- - rx_sample_discard : t_field_signals_rx_sample_discard_rx_sample_discard_in; -- - rx_nco_discard : t_field_signals_rx_sample_discard_rx_nco_discard_in; -- - end record; - type t_reg_rx_sample_discard_out is record-- - rx_sample_discard : t_field_signals_rx_sample_discard_rx_sample_discard_out; -- - rx_nco_discard : t_field_signals_rx_sample_discard_rx_nco_discard_out; -- - end record; - type t_reg_rx_sample_discard_2d_in is array (integer range <>) of t_reg_rx_sample_discard_in; - type t_reg_rx_sample_discard_2d_out is array (integer range <>) of t_reg_rx_sample_discard_out; - type t_reg_rx_sample_discard_3d_in is array (integer range <>, integer range <>) of t_reg_rx_sample_discard_in; - type t_reg_rx_sample_discard_3d_out is array (integer range <>, integer range <>) of t_reg_rx_sample_discard_out; - ----------------------------------------------- - -- register type: lpf_config_2 - ----------------------------------------------- - type t_field_signals_lpf_config_2_p_gain_in is record - -- no data if field cannot be written from hw - data : std_logic_vector(-1 downto 0); -- - end record; - - type t_field_signals_lpf_config_2_p_gain_out is record - data : std_logic_vector(24-1 downto 0); -- - end record; -- - type t_field_signals_lpf_config_2_p_shift_in is record - -- no data if field cannot be written from hw - data : std_logic_vector(-1 downto 0); -- - end record; - - type t_field_signals_lpf_config_2_p_shift_out is record - data : std_logic_vector(8-1 downto 0); -- - end record; -- - - -- The actual register types - type t_reg_lpf_config_2_in is record-- - p_gain : t_field_signals_lpf_config_2_p_gain_in; -- - p_shift : t_field_signals_lpf_config_2_p_shift_in; -- - end record; - type t_reg_lpf_config_2_out is record-- - p_gain : t_field_signals_lpf_config_2_p_gain_out; -- - p_shift : t_field_signals_lpf_config_2_p_shift_out; -- - end record; - type t_reg_lpf_config_2_2d_in is array (integer range <>) of t_reg_lpf_config_2_in; - type t_reg_lpf_config_2_2d_out is array (integer range <>) of t_reg_lpf_config_2_out; - type t_reg_lpf_config_2_3d_in is array (integer range <>, integer range <>) of t_reg_lpf_config_2_in; - type t_reg_lpf_config_2_3d_out is array (integer range <>, integer range <>) of t_reg_lpf_config_2_out; - ----------------------------------------------- - -- register type: observation_data - ----------------------------------------------- - type t_field_signals_observation_data_data32_in is record - data : std_logic_vector(32-1 downto 0); -- - end record; - - type t_field_signals_observation_data_data32_out is record - -- no data if field cannot be written from hw - dummy : std_logic; -- - end record; -- - - -- The actual register types - type t_reg_observation_data_in is record-- - data : t_field_signals_observation_data_data32_in; -- - end record; - type t_reg_observation_data_out is record-- - data : t_field_signals_observation_data_data32_out; -- - end record; - type t_reg_observation_data_2d_in is array (integer range <>) of t_reg_observation_data_in; - type t_reg_observation_data_2d_out is array (integer range <>) of t_reg_observation_data_out; - type t_reg_observation_data_3d_in is array (integer range <>, integer range <>) of t_reg_observation_data_in; - type t_reg_observation_data_3d_out is array (integer range <>, integer range <>) of t_reg_observation_data_out; - ----------------------------------------------- - -- register type: tx_sync_ctrl - ----------------------------------------------- - type t_field_signals_tx_sync_ctrl_tx_sync_ena_in is record - -- no data if field cannot be written from hw - data : std_logic_vector(-1 downto 0); -- - end record; - - type t_field_signals_tx_sync_ctrl_tx_sync_ena_out is record - data : std_logic_vector(1-1 downto 0); -- - end record; -- - type t_field_signals_tx_sync_ctrl_tx_sync_force_in is record - -- no data if field cannot be written from hw - data : std_logic_vector(-1 downto 0); -- - end record; - - type t_field_signals_tx_sync_ctrl_tx_sync_force_out is record - data : std_logic_vector(1-1 downto 0); -- - end record; -- - type t_field_signals_tx_sync_ctrl_tx_sync_f1_in is record - -- no data if field cannot be written from hw - data : std_logic_vector(-1 downto 0); -- - end record; - - type t_field_signals_tx_sync_ctrl_tx_sync_f1_out is record - data : std_logic_vector(1-1 downto 0); -- - end record; -- - type t_field_signals_tx_sync_ctrl_tx_sync_f2_in is record - -- no data if field cannot be written from hw - data : std_logic_vector(-1 downto 0); -- - end record; - - type t_field_signals_tx_sync_ctrl_tx_sync_f2_out is record - data : std_logic_vector(1-1 downto 0); -- - end record; -- - - -- The actual register types - type t_reg_tx_sync_ctrl_in is record-- - tx_sync_ena : t_field_signals_tx_sync_ctrl_tx_sync_ena_in; -- - tx_sync_force : t_field_signals_tx_sync_ctrl_tx_sync_force_in; -- - tx_sync_f1 : t_field_signals_tx_sync_ctrl_tx_sync_f1_in; -- - tx_sync_f2 : t_field_signals_tx_sync_ctrl_tx_sync_f2_in; -- - end record; - type t_reg_tx_sync_ctrl_out is record-- - tx_sync_ena : t_field_signals_tx_sync_ctrl_tx_sync_ena_out; -- - tx_sync_force : t_field_signals_tx_sync_ctrl_tx_sync_force_out; -- - tx_sync_f1 : t_field_signals_tx_sync_ctrl_tx_sync_f1_out; -- - tx_sync_f2 : t_field_signals_tx_sync_ctrl_tx_sync_f2_out; -- - end record; - type t_reg_tx_sync_ctrl_2d_in is array (integer range <>) of t_reg_tx_sync_ctrl_in; - type t_reg_tx_sync_ctrl_2d_out is array (integer range <>) of t_reg_tx_sync_ctrl_out; - type t_reg_tx_sync_ctrl_3d_in is array (integer range <>, integer range <>) of t_reg_tx_sync_ctrl_in; - type t_reg_tx_sync_ctrl_3d_out is array (integer range <>, integer range <>) of t_reg_tx_sync_ctrl_out; - ----------------------------------------------- - -- register type: tx_sync_cnt - ----------------------------------------------- - type t_field_signals_tx_sync_cnt_tx_sync_cnt_in is record - -- no data if field cannot be written from hw - data : std_logic_vector(-1 downto 0); -- - end record; - - type t_field_signals_tx_sync_cnt_tx_sync_cnt_out is record - data : std_logic_vector(24-1 downto 0); -- - end record; -- - - -- The actual register types - type t_reg_tx_sync_cnt_in is record-- - tx_sync_cnt : t_field_signals_tx_sync_cnt_tx_sync_cnt_in; -- - end record; - type t_reg_tx_sync_cnt_out is record-- - tx_sync_cnt : t_field_signals_tx_sync_cnt_tx_sync_cnt_out; -- - end record; - type t_reg_tx_sync_cnt_2d_in is array (integer range <>) of t_reg_tx_sync_cnt_in; - type t_reg_tx_sync_cnt_2d_out is array (integer range <>) of t_reg_tx_sync_cnt_out; - type t_reg_tx_sync_cnt_3d_in is array (integer range <>, integer range <>) of t_reg_tx_sync_cnt_in; - type t_reg_tx_sync_cnt_3d_out is array (integer range <>, integer range <>) of t_reg_tx_sync_cnt_out; - ----------------------------------------------- - -- register type: lowpass_ema_alpha - ----------------------------------------------- - type t_field_signals_lowpass_ema_alpha_alpha_in is record - -- no data if field cannot be written from hw - data : std_logic_vector(-1 downto 0); -- - end record; - - type t_field_signals_lowpass_ema_alpha_alpha_out is record - data : std_logic_vector(18-1 downto 0); -- - end record; -- - - -- The actual register types - type t_reg_lowpass_ema_alpha_in is record-- - alpha : t_field_signals_lowpass_ema_alpha_alpha_in; -- - end record; - type t_reg_lowpass_ema_alpha_out is record-- - alpha : t_field_signals_lowpass_ema_alpha_alpha_out; -- - end record; - type t_reg_lowpass_ema_alpha_2d_in is array (integer range <>) of t_reg_lowpass_ema_alpha_in; - type t_reg_lowpass_ema_alpha_2d_out is array (integer range <>) of t_reg_lowpass_ema_alpha_out; - type t_reg_lowpass_ema_alpha_3d_in is array (integer range <>, integer range <>) of t_reg_lowpass_ema_alpha_in; - type t_reg_lowpass_ema_alpha_3d_out is array (integer range <>, integer range <>) of t_reg_lowpass_ema_alpha_out; - ----------------------------------------------- - -- register type: rx_power - ----------------------------------------------- - type t_field_signals_rx_power_rx_power_in is record - data : std_logic_vector(23-1 downto 0); -- - end record; - - type t_field_signals_rx_power_rx_power_out is record - -- no data if field cannot be written from hw - dummy : std_logic; -- - end record; -- - - -- The actual register types - type t_reg_rx_power_in is record-- - rx_power : t_field_signals_rx_power_rx_power_in; -- - end record; - type t_reg_rx_power_out is record-- - rx_power : t_field_signals_rx_power_rx_power_out; -- - end record; - type t_reg_rx_power_2d_in is array (integer range <>) of t_reg_rx_power_in; - type t_reg_rx_power_2d_out is array (integer range <>) of t_reg_rx_power_out; - type t_reg_rx_power_3d_in is array (integer range <>, integer range <>) of t_reg_rx_power_in; - type t_reg_rx_power_3d_out is array (integer range <>, integer range <>) of t_reg_rx_power_out; - ----------------------------------------------- - - ------------------------------------------------------------------------------ - -- Register types in regfiles -- - - -- =========================================================================== - -- REGFILE interface - -- ----------------------------------------------------------------------------- - - -- =========================================================================== - -- MEMORIES interface - -- --------------------------------------------------------------------------- - - -- =========================================================================== - -- msk_top_regs : Top module address map interface - -- --------------------------------------------------------------------------- - type t_addrmap_msk_top_regs_in is record - -- - Hash_ID_Low : t_reg_msk_hash_lo_in; -- - Hash_ID_High : t_reg_msk_hash_hi_in; -- - MSK_Init : t_reg_msk_init_in; -- - MSK_Control : t_reg_msk_ctrl_in; -- - MSK_Status : t_reg_msk_stat_0_in; -- - Tx_Bit_Count : t_reg_msk_stat_1_in; -- - Tx_Enable_Count : t_reg_msk_stat_2_in; -- - Fb_FreqWord : t_reg_config_nco_fw_in; -- - TX_F1_FreqWord : t_reg_config_nco_fw_in; -- - TX_F2_FreqWord : t_reg_config_nco_fw_in; -- - RX_F1_FreqWord : t_reg_config_nco_fw_in; -- - RX_F2_FreqWord : t_reg_config_nco_fw_in; -- - LPF_Config_0 : t_reg_lpf_config_0_in; -- - LPF_Config_1 : t_reg_lpf_config_1_in; -- - Tx_Data_Width : t_reg_data_width_in; -- - Rx_Data_Width : t_reg_data_width_in; -- - PRBS_Control : t_reg_prbs_ctrl_in; -- - PRBS_Initial_State : t_reg_config_prbs_seed_in; -- - PRBS_Polynomial : t_reg_config_prbs_poly_in; -- - PRBS_Error_Mask : t_reg_config_prbs_errmask_in; -- - PRBS_Bit_Count : t_reg_stat_32_bits_in; -- - PRBS_Error_Count : t_reg_stat_32_errs_in; -- - LPF_Accum_F1 : t_reg_stat_32_lpf_acc_in; -- - LPF_Accum_F2 : t_reg_stat_32_lpf_acc_in; -- - axis_xfer_count : t_reg_msk_stat_3_in; -- - Rx_Sample_Discard : t_reg_rx_sample_discard_in; -- - LPF_Config_2 : t_reg_lpf_config_2_in; -- - f1_nco_adjust : t_reg_observation_data_in; -- - f2_nco_adjust : t_reg_observation_data_in; -- - f1_error : t_reg_observation_data_in; -- - f2_error : t_reg_observation_data_in; -- - Tx_Sync_Ctrl : t_reg_tx_sync_ctrl_in; -- - Tx_Sync_Cnt : t_reg_tx_sync_cnt_in; -- - lowpass_ema_alpha1 : t_reg_lowpass_ema_alpha_in; -- - lowpass_ema_alpha2 : t_reg_lowpass_ema_alpha_in; -- - rx_power : t_reg_rx_power_in; -- - -- - -- - -- - end record; - - type t_addrmap_msk_top_regs_out is record - -- - Hash_ID_Low : t_reg_msk_hash_lo_out; -- - Hash_ID_High : t_reg_msk_hash_hi_out; -- - MSK_Init : t_reg_msk_init_out; -- - MSK_Control : t_reg_msk_ctrl_out; -- - MSK_Status : t_reg_msk_stat_0_out; -- - Tx_Bit_Count : t_reg_msk_stat_1_out; -- - Tx_Enable_Count : t_reg_msk_stat_2_out; -- - Fb_FreqWord : t_reg_config_nco_fw_out; -- - TX_F1_FreqWord : t_reg_config_nco_fw_out; -- - TX_F2_FreqWord : t_reg_config_nco_fw_out; -- - RX_F1_FreqWord : t_reg_config_nco_fw_out; -- - RX_F2_FreqWord : t_reg_config_nco_fw_out; -- - LPF_Config_0 : t_reg_lpf_config_0_out; -- - LPF_Config_1 : t_reg_lpf_config_1_out; -- - Tx_Data_Width : t_reg_data_width_out; -- - Rx_Data_Width : t_reg_data_width_out; -- - PRBS_Control : t_reg_prbs_ctrl_out; -- - PRBS_Initial_State : t_reg_config_prbs_seed_out; -- - PRBS_Polynomial : t_reg_config_prbs_poly_out; -- - PRBS_Error_Mask : t_reg_config_prbs_errmask_out; -- - PRBS_Bit_Count : t_reg_stat_32_bits_out; -- - PRBS_Error_Count : t_reg_stat_32_errs_out; -- - LPF_Accum_F1 : t_reg_stat_32_lpf_acc_out; -- - LPF_Accum_F2 : t_reg_stat_32_lpf_acc_out; -- - axis_xfer_count : t_reg_msk_stat_3_out; -- - Rx_Sample_Discard : t_reg_rx_sample_discard_out; -- - LPF_Config_2 : t_reg_lpf_config_2_out; -- - f1_nco_adjust : t_reg_observation_data_out; -- - f2_nco_adjust : t_reg_observation_data_out; -- - f1_error : t_reg_observation_data_out; -- - f2_error : t_reg_observation_data_out; -- - Tx_Sync_Ctrl : t_reg_tx_sync_ctrl_out; -- - Tx_Sync_Cnt : t_reg_tx_sync_cnt_out; -- - lowpass_ema_alpha1 : t_reg_lowpass_ema_alpha_out; -- - lowpass_ema_alpha2 : t_reg_lowpass_ema_alpha_out; -- - rx_power : t_reg_rx_power_out; -- - -- - -- - -- - end record; - - -- =========================================================================== - -- top level component declaration - -- must come after defining the interfaces - -- --------------------------------------------------------------------------- - subtype t_msk_top_regs_m2s is t_axi4l_m2s; - subtype t_msk_top_regs_s2m is t_axi4l_s2m; - - component msk_top_regs is - port ( - pi_clock : in std_logic; - pi_reset : in std_logic; - -- TOP subordinate memory mapped interface - pi_s_top : in t_msk_top_regs_m2s; - po_s_top : out t_msk_top_regs_s2m; - -- to logic interface - pi_addrmap : in t_addrmap_msk_top_regs_in; - po_addrmap : out t_addrmap_msk_top_regs_out - ); - end component msk_top_regs; - -end package pkg_msk_top_regs; --------------------------------------------------------------------------------- -package body pkg_msk_top_regs is -end package body; - ---============================================================================== - - --------------------------------------------------------------------------------- --- Register types directly in addmap --------------------------------------------------------------------------------- --- --- register type: msk_hash_lo ------------------------------------------------ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -library desyrdl; -use desyrdl.common.all; - -use work.pkg_msk_top_regs.all; - -entity msk_top_regs_msk_hash_lo is - port ( - pi_clock : in std_logic; - pi_reset : in std_logic; - -- to/from adapter - pi_decoder_rd_stb : in std_logic; - pi_decoder_wr_stb : in std_logic; - pi_decoder_data : in std_logic_vector(C_DATA_WIDTH-1 downto 0); - po_decoder_data : out std_logic_vector(C_DATA_WIDTH-1 downto 0); - - pi_reg : in t_reg_msk_hash_lo_in ; - po_reg : out t_reg_msk_hash_lo_out - ); -end entity msk_top_regs_msk_hash_lo; - -architecture rtl of msk_top_regs_msk_hash_lo is - - -- assign slices of data_out for each field, but force the rest to constant zeros - function fun_set_data_out ( -- - field_reg_hash_id_lo : std_logic_vector(32-1 downto 0)) -- - return std_logic_vector is - variable v_data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0); - begin - v_data_out := (others => '0'); - -- - v_data_out(31 downto 0) := field_reg_hash_id_lo; -- - return v_data_out; - end function fun_set_data_out; - - signal data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); - -- - signal field_reg_hash_id_lo : std_logic_vector(32-1 downto 0) - := std_logic_vector(to_signed(-1431677611,32)); -- -begin - - data_out <= fun_set_data_out( -- - field_reg_hash_id_lo -- - ); - - -- resize field data out to the register bus width - -- do only if 1 field and signed-- - po_decoder_data <= data_out; -- - ------------------------------------------------------------WIRE - hash_id_lo_wire : block -- - begin - -- - field_reg_hash_id_lo <= std_logic_vector(to_signed(-1431677611,32)); -- - --no signal to read by HW - po_reg.hash_id_lo.dummy <= '0'; -- - end block; -- -end rtl; ------------------------------------------------ --- register type: msk_hash_hi ------------------------------------------------ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -library desyrdl; -use desyrdl.common.all; - -use work.pkg_msk_top_regs.all; - -entity msk_top_regs_msk_hash_hi is - port ( - pi_clock : in std_logic; - pi_reset : in std_logic; - -- to/from adapter - pi_decoder_rd_stb : in std_logic; - pi_decoder_wr_stb : in std_logic; - pi_decoder_data : in std_logic_vector(C_DATA_WIDTH-1 downto 0); - po_decoder_data : out std_logic_vector(C_DATA_WIDTH-1 downto 0); - - pi_reg : in t_reg_msk_hash_hi_in ; - po_reg : out t_reg_msk_hash_hi_out - ); -end entity msk_top_regs_msk_hash_hi; - -architecture rtl of msk_top_regs_msk_hash_hi is - - -- assign slices of data_out for each field, but force the rest to constant zeros - function fun_set_data_out ( -- - field_reg_hash_id_hi : std_logic_vector(32-1 downto 0)) -- - return std_logic_vector is - variable v_data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0); - begin - v_data_out := (others => '0'); - -- - v_data_out(31 downto 0) := field_reg_hash_id_hi; -- - return v_data_out; - end function fun_set_data_out; - - signal data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); - -- - signal field_reg_hash_id_hi : std_logic_vector(32-1 downto 0) - := std_logic_vector(to_signed(1431677610,32)); -- -begin - - data_out <= fun_set_data_out( -- - field_reg_hash_id_hi -- - ); - - -- resize field data out to the register bus width - -- do only if 1 field and signed-- - po_decoder_data <= data_out; -- - ------------------------------------------------------------WIRE - hash_id_hi_wire : block -- - begin - -- - field_reg_hash_id_hi <= std_logic_vector(to_signed(1431677610,32)); -- - --no signal to read by HW - po_reg.hash_id_hi.dummy <= '0'; -- - end block; -- -end rtl; ------------------------------------------------ --- register type: msk_init ------------------------------------------------ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -library desyrdl; -use desyrdl.common.all; - -use work.pkg_msk_top_regs.all; - -entity msk_top_regs_msk_init is - port ( - pi_clock : in std_logic; - pi_reset : in std_logic; - -- to/from adapter - pi_decoder_rd_stb : in std_logic; - pi_decoder_wr_stb : in std_logic; - pi_decoder_data : in std_logic_vector(C_DATA_WIDTH-1 downto 0); - po_decoder_data : out std_logic_vector(C_DATA_WIDTH-1 downto 0); - - pi_reg : in t_reg_msk_init_in ; - po_reg : out t_reg_msk_init_out - ); -end entity msk_top_regs_msk_init; - -architecture rtl of msk_top_regs_msk_init is - - -- assign slices of data_out for each field, but force the rest to constant zeros - function fun_set_data_out ( -- - field_reg_txrxinit : std_logic_vector(1-1 downto 0); -- - field_reg_txinit : std_logic_vector(1-1 downto 0); -- - field_reg_rxinit : std_logic_vector(1-1 downto 0)) -- - return std_logic_vector is - variable v_data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0); - begin - v_data_out := (others => '0'); - -- - v_data_out(0 downto 0) := field_reg_txrxinit; -- - v_data_out(1 downto 1) := field_reg_txinit; -- - v_data_out(2 downto 2) := field_reg_rxinit; -- - return v_data_out; - end function fun_set_data_out; - - signal data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); - -- - signal field_reg_txrxinit : std_logic_vector(1-1 downto 0) - := std_logic_vector(to_signed(1,1)); -- - signal field_reg_txinit : std_logic_vector(1-1 downto 0) - := std_logic_vector(to_signed(1,1)); -- - signal field_reg_rxinit : std_logic_vector(1-1 downto 0) - := std_logic_vector(to_signed(1,1)); -- -begin - - data_out <= fun_set_data_out( -- - field_reg_txrxinit, -- - field_reg_txinit, -- - field_reg_rxinit -- - ); - - -- resize field data out to the register bus width - -- do only if 1 field and signed-- - po_decoder_data <= data_out; -- - ------------------------------------------------------------STORAGE - txrxinit_storage: block - begin - prs_write : process(pi_clock) - begin - if rising_edge(pi_clock) then - if pi_reset = '1' then - field_reg_txrxinit <= std_logic_vector(to_signed(1,1)); - else - -- HW -- - -- SW -- - if pi_decoder_wr_stb = '1' then - field_reg_txrxinit <= pi_decoder_data(0 downto 0); - end if; - end if; - end if; - end process; - -- - po_reg.txrxinit.data <= field_reg_txrxinit; -- - end block txrxinit_storage; - ------------------------------------------------------------STORAGE - txinit_storage: block - begin - prs_write : process(pi_clock) - begin - if rising_edge(pi_clock) then - if pi_reset = '1' then - field_reg_txinit <= std_logic_vector(to_signed(1,1)); - else - -- HW -- - -- SW -- - if pi_decoder_wr_stb = '1' then - field_reg_txinit <= pi_decoder_data(1 downto 1); - end if; - end if; - end if; - end process; - -- - po_reg.txinit.data <= field_reg_txinit; -- - end block txinit_storage; - ------------------------------------------------------------STORAGE - rxinit_storage: block - begin - prs_write : process(pi_clock) - begin - if rising_edge(pi_clock) then - if pi_reset = '1' then - field_reg_rxinit <= std_logic_vector(to_signed(1,1)); - else - -- HW -- - -- SW -- - if pi_decoder_wr_stb = '1' then - field_reg_rxinit <= pi_decoder_data(2 downto 2); - end if; - end if; - end if; - end process; - -- - po_reg.rxinit.data <= field_reg_rxinit; -- - end block rxinit_storage; - ---------------------------------------------------------- -end rtl; ------------------------------------------------ --- register type: msk_ctrl ------------------------------------------------ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -library desyrdl; -use desyrdl.common.all; - -use work.pkg_msk_top_regs.all; - -entity msk_top_regs_msk_ctrl is - port ( - pi_clock : in std_logic; - pi_reset : in std_logic; - -- to/from adapter - pi_decoder_rd_stb : in std_logic; - pi_decoder_wr_stb : in std_logic; - pi_decoder_data : in std_logic_vector(C_DATA_WIDTH-1 downto 0); - po_decoder_data : out std_logic_vector(C_DATA_WIDTH-1 downto 0); - - pi_reg : in t_reg_msk_ctrl_in ; - po_reg : out t_reg_msk_ctrl_out - ); -end entity msk_top_regs_msk_ctrl; - -architecture rtl of msk_top_regs_msk_ctrl is - - -- assign slices of data_out for each field, but force the rest to constant zeros - function fun_set_data_out ( -- - field_reg_ptt : std_logic_vector(1-1 downto 0); -- - field_reg_loopback_ena : std_logic_vector(1-1 downto 0); -- - field_reg_rx_invert : std_logic_vector(1-1 downto 0); -- - field_reg_clear_counts : std_logic_vector(1-1 downto 0); -- - field_reg_diff_encoder_loopback : std_logic_vector(1-1 downto 0)) -- - return std_logic_vector is - variable v_data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0); - begin - v_data_out := (others => '0'); - -- - v_data_out(0 downto 0) := field_reg_ptt; -- - v_data_out(1 downto 1) := field_reg_loopback_ena; -- - v_data_out(2 downto 2) := field_reg_rx_invert; -- - v_data_out(3 downto 3) := field_reg_clear_counts; -- - v_data_out(4 downto 4) := field_reg_diff_encoder_loopback; -- - return v_data_out; - end function fun_set_data_out; - - signal data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); - -- - signal field_reg_ptt : std_logic_vector(1-1 downto 0) - := std_logic_vector(to_signed(0,1)); -- - signal field_reg_loopback_ena : std_logic_vector(1-1 downto 0) - := std_logic_vector(to_signed(0,1)); -- - signal field_reg_rx_invert : std_logic_vector(1-1 downto 0) - := std_logic_vector(to_signed(0,1)); -- - signal field_reg_clear_counts : std_logic_vector(1-1 downto 0) - := std_logic_vector(to_signed(0,1)); -- - signal field_reg_diff_encoder_loopback : std_logic_vector(1-1 downto 0) - := std_logic_vector(to_signed(0,1)); -- -begin - - data_out <= fun_set_data_out( -- - field_reg_ptt, -- - field_reg_loopback_ena, -- - field_reg_rx_invert, -- - field_reg_clear_counts, -- - field_reg_diff_encoder_loopback -- - ); - - -- resize field data out to the register bus width - -- do only if 1 field and signed-- - po_decoder_data <= data_out; -- - ------------------------------------------------------------STORAGE - ptt_storage: block - begin - prs_write : process(pi_clock) - begin - if rising_edge(pi_clock) then - if pi_reset = '1' then - field_reg_ptt <= std_logic_vector(to_signed(0,1)); - else - -- HW -- - -- SW -- - if pi_decoder_wr_stb = '1' then - field_reg_ptt <= pi_decoder_data(0 downto 0); - end if; - end if; - end if; - end process; - -- - po_reg.ptt.data <= field_reg_ptt; -- - end block ptt_storage; - ------------------------------------------------------------STORAGE - loopback_ena_storage: block - begin - prs_write : process(pi_clock) - begin - if rising_edge(pi_clock) then - if pi_reset = '1' then - field_reg_loopback_ena <= std_logic_vector(to_signed(0,1)); - else - -- HW -- - -- SW -- - if pi_decoder_wr_stb = '1' then - field_reg_loopback_ena <= pi_decoder_data(1 downto 1); - end if; - end if; - end if; - end process; - -- - po_reg.loopback_ena.data <= field_reg_loopback_ena; -- - end block loopback_ena_storage; - ------------------------------------------------------------STORAGE - rx_invert_storage: block - begin - prs_write : process(pi_clock) - begin - if rising_edge(pi_clock) then - if pi_reset = '1' then - field_reg_rx_invert <= std_logic_vector(to_signed(0,1)); - else - -- HW -- - -- SW -- - if pi_decoder_wr_stb = '1' then - field_reg_rx_invert <= pi_decoder_data(2 downto 2); - end if; - end if; - end if; - end process; - -- - po_reg.rx_invert.data <= field_reg_rx_invert; -- - end block rx_invert_storage; - ------------------------------------------------------------STORAGE - clear_counts_storage: block - begin - prs_write : process(pi_clock) - begin - if rising_edge(pi_clock) then - if pi_reset = '1' then - field_reg_clear_counts <= std_logic_vector(to_signed(0,1)); - else - -- HW -- - -- This is a "singlepulse" register - clear on each clock, - -- unless it is written to with a 1 (see below) - field_reg_clear_counts <= (others => '0'); - -- SW -- - if pi_decoder_wr_stb = '1' then - field_reg_clear_counts <= pi_decoder_data(3 downto 3); - end if; - end if; - end if; - end process; - -- - po_reg.clear_counts.data <= field_reg_clear_counts; -- - end block clear_counts_storage; - ------------------------------------------------------------STORAGE - diff_encoder_loopback_storage: block - begin - prs_write : process(pi_clock) - begin - if rising_edge(pi_clock) then - if pi_reset = '1' then - field_reg_diff_encoder_loopback <= std_logic_vector(to_signed(0,1)); - else - -- HW -- - -- SW -- - if pi_decoder_wr_stb = '1' then - field_reg_diff_encoder_loopback <= pi_decoder_data(4 downto 4); - end if; - end if; - end if; - end process; - -- - po_reg.diff_encoder_loopback.data <= field_reg_diff_encoder_loopback; -- - end block diff_encoder_loopback_storage; - ---------------------------------------------------------- -end rtl; ------------------------------------------------ --- register type: msk_stat_0 ------------------------------------------------ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -library desyrdl; -use desyrdl.common.all; - -use work.pkg_msk_top_regs.all; - -entity msk_top_regs_msk_stat_0 is - port ( - pi_clock : in std_logic; - pi_reset : in std_logic; - -- to/from adapter - pi_decoder_rd_stb : in std_logic; - pi_decoder_wr_stb : in std_logic; - pi_decoder_data : in std_logic_vector(C_DATA_WIDTH-1 downto 0); - po_decoder_data : out std_logic_vector(C_DATA_WIDTH-1 downto 0); - - pi_reg : in t_reg_msk_stat_0_in ; - po_reg : out t_reg_msk_stat_0_out - ); -end entity msk_top_regs_msk_stat_0; - -architecture rtl of msk_top_regs_msk_stat_0 is - - -- assign slices of data_out for each field, but force the rest to constant zeros - function fun_set_data_out ( -- - field_reg_demod_sync_lock : std_logic_vector(1-1 downto 0); -- - field_reg_tx_enable : std_logic_vector(1-1 downto 0); -- - field_reg_rx_enable : std_logic_vector(1-1 downto 0); -- - field_reg_tx_axis_valid : std_logic_vector(1-1 downto 0)) -- - return std_logic_vector is - variable v_data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0); - begin - v_data_out := (others => '0'); - -- - v_data_out(0 downto 0) := field_reg_demod_sync_lock; -- - v_data_out(1 downto 1) := field_reg_tx_enable; -- - v_data_out(2 downto 2) := field_reg_rx_enable; -- - v_data_out(3 downto 3) := field_reg_tx_axis_valid; -- - return v_data_out; - end function fun_set_data_out; - - signal data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); - -- - signal field_reg_demod_sync_lock : std_logic_vector(1-1 downto 0) - := std_logic_vector(to_signed(0,1)); -- - signal field_reg_tx_enable : std_logic_vector(1-1 downto 0) - := std_logic_vector(to_signed(0,1)); -- - signal field_reg_rx_enable : std_logic_vector(1-1 downto 0) - := std_logic_vector(to_signed(0,1)); -- - signal field_reg_tx_axis_valid : std_logic_vector(1-1 downto 0) - := std_logic_vector(to_signed(0,1)); -- -begin - - data_out <= fun_set_data_out( -- - field_reg_demod_sync_lock, -- - field_reg_tx_enable, -- - field_reg_rx_enable, -- - field_reg_tx_axis_valid -- - ); - - -- resize field data out to the register bus width - -- do only if 1 field and signed-- - po_decoder_data <= data_out; -- - ------------------------------------------------------------WIRE - demod_sync_lock_wire : block -- - begin - -- - field_reg_demod_sync_lock <= pi_reg.demod_sync_lock.data(1-1 downto 0); -- - --no signal to read by HW - po_reg.demod_sync_lock.dummy <= '0'; -- - end block; ----WIRE - tx_enable_wire : block -- - begin - -- - field_reg_tx_enable <= pi_reg.tx_enable.data(1-1 downto 0); -- - --no signal to read by HW - po_reg.tx_enable.dummy <= '0'; -- - end block; ----WIRE - rx_enable_wire : block -- - begin - -- - field_reg_rx_enable <= pi_reg.rx_enable.data(1-1 downto 0); -- - --no signal to read by HW - po_reg.rx_enable.dummy <= '0'; -- - end block; ----WIRE - tx_axis_valid_wire : block -- - begin - -- - field_reg_tx_axis_valid <= pi_reg.tx_axis_valid.data(1-1 downto 0); -- - --no signal to read by HW - po_reg.tx_axis_valid.dummy <= '0'; -- - end block; -- -end rtl; ------------------------------------------------ --- register type: msk_stat_1 ------------------------------------------------ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -library desyrdl; -use desyrdl.common.all; - -use work.pkg_msk_top_regs.all; - -entity msk_top_regs_msk_stat_1 is - port ( - pi_clock : in std_logic; - pi_reset : in std_logic; - -- to/from adapter - pi_decoder_rd_stb : in std_logic; - pi_decoder_wr_stb : in std_logic; - pi_decoder_data : in std_logic_vector(C_DATA_WIDTH-1 downto 0); - po_decoder_data : out std_logic_vector(C_DATA_WIDTH-1 downto 0); - - pi_reg : in t_reg_msk_stat_1_in ; - po_reg : out t_reg_msk_stat_1_out - ); -end entity msk_top_regs_msk_stat_1; - -architecture rtl of msk_top_regs_msk_stat_1 is - - -- assign slices of data_out for each field, but force the rest to constant zeros - function fun_set_data_out ( -- - field_reg_tx_bit_counter : std_logic_vector(32-1 downto 0)) -- - return std_logic_vector is - variable v_data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0); - begin - v_data_out := (others => '0'); - -- - v_data_out(31 downto 0) := field_reg_tx_bit_counter; -- - return v_data_out; - end function fun_set_data_out; - - signal data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); - -- - signal field_reg_tx_bit_counter : std_logic_vector(32-1 downto 0) - := std_logic_vector(to_signed(0,32)); -- -begin - - data_out <= fun_set_data_out( -- - field_reg_tx_bit_counter -- - ); - - -- resize field data out to the register bus width - -- do only if 1 field and signed-- - po_decoder_data <= data_out; -- - ------------------------------------------------------------WIRE - tx_bit_counter_wire : block -- - begin - -- - field_reg_tx_bit_counter <= pi_reg.tx_bit_counter.data(32-1 downto 0); -- - --no signal to read by HW - po_reg.tx_bit_counter.dummy <= '0'; -- - end block; -- -end rtl; ------------------------------------------------ --- register type: msk_stat_2 ------------------------------------------------ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -library desyrdl; -use desyrdl.common.all; - -use work.pkg_msk_top_regs.all; - -entity msk_top_regs_msk_stat_2 is - port ( - pi_clock : in std_logic; - pi_reset : in std_logic; - -- to/from adapter - pi_decoder_rd_stb : in std_logic; - pi_decoder_wr_stb : in std_logic; - pi_decoder_data : in std_logic_vector(C_DATA_WIDTH-1 downto 0); - po_decoder_data : out std_logic_vector(C_DATA_WIDTH-1 downto 0); - - pi_reg : in t_reg_msk_stat_2_in ; - po_reg : out t_reg_msk_stat_2_out - ); -end entity msk_top_regs_msk_stat_2; - -architecture rtl of msk_top_regs_msk_stat_2 is - - -- assign slices of data_out for each field, but force the rest to constant zeros - function fun_set_data_out ( -- - field_reg_tx_ena_counter : std_logic_vector(32-1 downto 0)) -- - return std_logic_vector is - variable v_data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0); - begin - v_data_out := (others => '0'); - -- - v_data_out(31 downto 0) := field_reg_tx_ena_counter; -- - return v_data_out; - end function fun_set_data_out; - - signal data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); - -- - signal field_reg_tx_ena_counter : std_logic_vector(32-1 downto 0) - := std_logic_vector(to_signed(0,32)); -- -begin - - data_out <= fun_set_data_out( -- - field_reg_tx_ena_counter -- - ); - - -- resize field data out to the register bus width - -- do only if 1 field and signed-- - po_decoder_data <= data_out; -- - ------------------------------------------------------------WIRE - tx_ena_counter_wire : block -- - begin - -- - field_reg_tx_ena_counter <= pi_reg.tx_ena_counter.data(32-1 downto 0); -- - --no signal to read by HW - po_reg.tx_ena_counter.dummy <= '0'; -- - end block; -- -end rtl; ------------------------------------------------ --- register type: config_nco_fw ------------------------------------------------ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -library desyrdl; -use desyrdl.common.all; - -use work.pkg_msk_top_regs.all; - -entity msk_top_regs_config_nco_fw is - port ( - pi_clock : in std_logic; - pi_reset : in std_logic; - -- to/from adapter - pi_decoder_rd_stb : in std_logic; - pi_decoder_wr_stb : in std_logic; - pi_decoder_data : in std_logic_vector(C_DATA_WIDTH-1 downto 0); - po_decoder_data : out std_logic_vector(C_DATA_WIDTH-1 downto 0); - - pi_reg : in t_reg_config_nco_fw_in ; - po_reg : out t_reg_config_nco_fw_out - ); -end entity msk_top_regs_config_nco_fw; - -architecture rtl of msk_top_regs_config_nco_fw is - - -- assign slices of data_out for each field, but force the rest to constant zeros - function fun_set_data_out ( -- - field_reg_config_data : std_logic_vector(32-1 downto 0)) -- - return std_logic_vector is - variable v_data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0); - begin - v_data_out := (others => '0'); - -- - v_data_out(31 downto 0) := field_reg_config_data; -- - return v_data_out; - end function fun_set_data_out; - - signal data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); - -- - signal field_reg_config_data : std_logic_vector(32-1 downto 0) - := std_logic_vector(to_signed(0,32)); -- -begin - - data_out <= fun_set_data_out( -- - field_reg_config_data -- - ); - - -- resize field data out to the register bus width - -- do only if 1 field and signed-- - po_decoder_data <= data_out; -- - ------------------------------------------------------------STORAGE - config_data_storage: block - begin - prs_write : process(pi_clock) - begin - if rising_edge(pi_clock) then - if pi_reset = '1' then - field_reg_config_data <= std_logic_vector(to_signed(0,32)); - else - -- HW -- - -- SW -- - if pi_decoder_wr_stb = '1' then - field_reg_config_data <= pi_decoder_data(31 downto 0); - end if; - end if; - end if; - end process; - -- - po_reg.config_data.data <= field_reg_config_data; -- - end block config_data_storage; - ---------------------------------------------------------- -end rtl; ------------------------------------------------ --- register type: lpf_config_0 ------------------------------------------------ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -library desyrdl; -use desyrdl.common.all; - -use work.pkg_msk_top_regs.all; - -entity msk_top_regs_lpf_config_0 is - port ( - pi_clock : in std_logic; - pi_reset : in std_logic; - -- to/from adapter - pi_decoder_rd_stb : in std_logic; - pi_decoder_wr_stb : in std_logic; - pi_decoder_data : in std_logic_vector(C_DATA_WIDTH-1 downto 0); - po_decoder_data : out std_logic_vector(C_DATA_WIDTH-1 downto 0); - - pi_reg : in t_reg_lpf_config_0_in ; - po_reg : out t_reg_lpf_config_0_out - ); -end entity msk_top_regs_lpf_config_0; - -architecture rtl of msk_top_regs_lpf_config_0 is - - -- assign slices of data_out for each field, but force the rest to constant zeros - function fun_set_data_out ( -- - field_reg_lpf_freeze : std_logic_vector(1-1 downto 0); -- - field_reg_lpf_zero : std_logic_vector(1-1 downto 0); -- - field_reg_prbs_reserved : std_logic_vector(6-1 downto 0); -- - field_reg_lpf_alpha : std_logic_vector(24-1 downto 0)) -- - return std_logic_vector is - variable v_data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0); - begin - v_data_out := (others => '0'); - -- - v_data_out(0 downto 0) := field_reg_lpf_freeze; -- - v_data_out(1 downto 1) := field_reg_lpf_zero; -- - v_data_out(7 downto 2) := field_reg_prbs_reserved; -- - v_data_out(31 downto 8) := field_reg_lpf_alpha; -- - return v_data_out; - end function fun_set_data_out; - - signal data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); - -- - signal field_reg_lpf_freeze : std_logic_vector(1-1 downto 0) - := std_logic_vector(to_signed(0,1)); -- - signal field_reg_lpf_zero : std_logic_vector(1-1 downto 0) - := std_logic_vector(to_signed(0,1)); -- - signal field_reg_prbs_reserved : std_logic_vector(6-1 downto 0) - := std_logic_vector(to_signed(0,6)); -- - signal field_reg_lpf_alpha : std_logic_vector(24-1 downto 0) - := std_logic_vector(to_signed(0,24)); -- -begin - - data_out <= fun_set_data_out( -- - field_reg_lpf_freeze, -- - field_reg_lpf_zero, -- - field_reg_prbs_reserved, -- - field_reg_lpf_alpha -- - ); - - -- resize field data out to the register bus width - -- do only if 1 field and signed-- - po_decoder_data <= data_out; -- - ------------------------------------------------------------STORAGE - lpf_freeze_storage: block - begin - prs_write : process(pi_clock) - begin - if rising_edge(pi_clock) then - if pi_reset = '1' then - field_reg_lpf_freeze <= std_logic_vector(to_signed(0,1)); - else - -- HW -- - -- SW -- - if pi_decoder_wr_stb = '1' then - field_reg_lpf_freeze <= pi_decoder_data(0 downto 0); - end if; - end if; - end if; - end process; - -- - po_reg.lpf_freeze.data <= field_reg_lpf_freeze; -- - end block lpf_freeze_storage; - ------------------------------------------------------------STORAGE - lpf_zero_storage: block - begin - prs_write : process(pi_clock) - begin - if rising_edge(pi_clock) then - if pi_reset = '1' then - field_reg_lpf_zero <= std_logic_vector(to_signed(0,1)); - else - -- HW -- - -- SW -- - if pi_decoder_wr_stb = '1' then - field_reg_lpf_zero <= pi_decoder_data(1 downto 1); - end if; - end if; - end if; - end process; - -- - po_reg.lpf_zero.data <= field_reg_lpf_zero; -- - end block lpf_zero_storage; - ------------------------------------------------------------STORAGE - prbs_reserved_storage: block - begin - prs_write : process(pi_clock) - begin - if rising_edge(pi_clock) then - if pi_reset = '1' then - field_reg_prbs_reserved <= std_logic_vector(to_signed(0,6)); - else - -- HW -- - -- SW -- - if pi_decoder_wr_stb = '1' then - field_reg_prbs_reserved <= pi_decoder_data(7 downto 2); - end if; - end if; - end if; - end process; - -- - po_reg.prbs_reserved.data <= field_reg_prbs_reserved; -- - end block prbs_reserved_storage; - ------------------------------------------------------------STORAGE - lpf_alpha_storage: block - begin - prs_write : process(pi_clock) - begin - if rising_edge(pi_clock) then - if pi_reset = '1' then - field_reg_lpf_alpha <= std_logic_vector(to_signed(0,24)); - else - -- HW -- - -- SW -- - if pi_decoder_wr_stb = '1' then - field_reg_lpf_alpha <= pi_decoder_data(31 downto 8); - end if; - end if; - end if; - end process; - -- - po_reg.lpf_alpha.data <= field_reg_lpf_alpha; -- - end block lpf_alpha_storage; - ---------------------------------------------------------- -end rtl; ------------------------------------------------ --- register type: lpf_config_1 ------------------------------------------------ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -library desyrdl; -use desyrdl.common.all; - -use work.pkg_msk_top_regs.all; - -entity msk_top_regs_lpf_config_1 is - port ( - pi_clock : in std_logic; - pi_reset : in std_logic; - -- to/from adapter - pi_decoder_rd_stb : in std_logic; - pi_decoder_wr_stb : in std_logic; - pi_decoder_data : in std_logic_vector(C_DATA_WIDTH-1 downto 0); - po_decoder_data : out std_logic_vector(C_DATA_WIDTH-1 downto 0); - - pi_reg : in t_reg_lpf_config_1_in ; - po_reg : out t_reg_lpf_config_1_out - ); -end entity msk_top_regs_lpf_config_1; - -architecture rtl of msk_top_regs_lpf_config_1 is - - -- assign slices of data_out for each field, but force the rest to constant zeros - function fun_set_data_out ( -- - field_reg_i_gain : std_logic_vector(24-1 downto 0); -- - field_reg_i_shift : std_logic_vector(8-1 downto 0)) -- - return std_logic_vector is - variable v_data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0); - begin - v_data_out := (others => '0'); - -- - v_data_out(23 downto 0) := field_reg_i_gain; -- - v_data_out(31 downto 24) := field_reg_i_shift; -- - return v_data_out; - end function fun_set_data_out; - - signal data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); - -- - signal field_reg_i_gain : std_logic_vector(24-1 downto 0) - := std_logic_vector(to_signed(0,24)); -- - signal field_reg_i_shift : std_logic_vector(8-1 downto 0) - := std_logic_vector(to_signed(0,8)); -- -begin - - data_out <= fun_set_data_out( -- - field_reg_i_gain, -- - field_reg_i_shift -- - ); - - -- resize field data out to the register bus width - -- do only if 1 field and signed-- - po_decoder_data <= data_out; -- - ------------------------------------------------------------STORAGE - i_gain_storage: block - begin - prs_write : process(pi_clock) - begin - if rising_edge(pi_clock) then - if pi_reset = '1' then - field_reg_i_gain <= std_logic_vector(to_signed(0,24)); - else - -- HW -- - -- SW -- - if pi_decoder_wr_stb = '1' then - field_reg_i_gain <= pi_decoder_data(23 downto 0); - end if; - end if; - end if; - end process; - -- - po_reg.i_gain.data <= field_reg_i_gain; -- - end block i_gain_storage; - ------------------------------------------------------------STORAGE - i_shift_storage: block - begin - prs_write : process(pi_clock) - begin - if rising_edge(pi_clock) then - if pi_reset = '1' then - field_reg_i_shift <= std_logic_vector(to_signed(0,8)); - else - -- HW -- - -- SW -- - if pi_decoder_wr_stb = '1' then - field_reg_i_shift <= pi_decoder_data(31 downto 24); - end if; - end if; - end if; - end process; - -- - po_reg.i_shift.data <= field_reg_i_shift; -- - end block i_shift_storage; - ---------------------------------------------------------- -end rtl; ------------------------------------------------ --- register type: data_width ------------------------------------------------ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -library desyrdl; -use desyrdl.common.all; - -use work.pkg_msk_top_regs.all; - -entity msk_top_regs_data_width is - port ( - pi_clock : in std_logic; - pi_reset : in std_logic; - -- to/from adapter - pi_decoder_rd_stb : in std_logic; - pi_decoder_wr_stb : in std_logic; - pi_decoder_data : in std_logic_vector(C_DATA_WIDTH-1 downto 0); - po_decoder_data : out std_logic_vector(C_DATA_WIDTH-1 downto 0); - - pi_reg : in t_reg_data_width_in ; - po_reg : out t_reg_data_width_out - ); -end entity msk_top_regs_data_width; - -architecture rtl of msk_top_regs_data_width is - - -- assign slices of data_out for each field, but force the rest to constant zeros - function fun_set_data_out ( -- - field_reg_data_width : std_logic_vector(8-1 downto 0)) -- - return std_logic_vector is - variable v_data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0); - begin - v_data_out := (others => '0'); - -- - v_data_out(7 downto 0) := field_reg_data_width; -- - return v_data_out; - end function fun_set_data_out; - - signal data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); - -- - signal field_reg_data_width : std_logic_vector(8-1 downto 0) - := std_logic_vector(to_signed(8,8)); -- -begin - - data_out <= fun_set_data_out( -- - field_reg_data_width -- - ); - - -- resize field data out to the register bus width - -- do only if 1 field and signed-- - po_decoder_data <= data_out; -- - ------------------------------------------------------------STORAGE - data_width_storage: block - begin - prs_write : process(pi_clock) - begin - if rising_edge(pi_clock) then - if pi_reset = '1' then - field_reg_data_width <= std_logic_vector(to_signed(8,8)); - else - -- HW -- - -- SW -- - if pi_decoder_wr_stb = '1' then - field_reg_data_width <= pi_decoder_data(7 downto 0); - end if; - end if; - end if; - end process; - -- - po_reg.data_width.data <= field_reg_data_width; -- - end block data_width_storage; - ---------------------------------------------------------- -end rtl; ------------------------------------------------ --- register type: prbs_ctrl ------------------------------------------------ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -library desyrdl; -use desyrdl.common.all; - -use work.pkg_msk_top_regs.all; - -entity msk_top_regs_prbs_ctrl is - port ( - pi_clock : in std_logic; - pi_reset : in std_logic; - -- to/from adapter - pi_decoder_rd_stb : in std_logic; - pi_decoder_wr_stb : in std_logic; - pi_decoder_data : in std_logic_vector(C_DATA_WIDTH-1 downto 0); - po_decoder_data : out std_logic_vector(C_DATA_WIDTH-1 downto 0); - - pi_reg : in t_reg_prbs_ctrl_in ; - po_reg : out t_reg_prbs_ctrl_out - ); -end entity msk_top_regs_prbs_ctrl; - -architecture rtl of msk_top_regs_prbs_ctrl is - - -- assign slices of data_out for each field, but force the rest to constant zeros - function fun_set_data_out ( -- - field_reg_prbs_sel : std_logic_vector(1-1 downto 0); -- - field_reg_prbs_error_insert : std_logic_vector(1-1 downto 0); -- - field_reg_prbs_clear : std_logic_vector(1-1 downto 0); -- - field_reg_prbs_manual_sync : std_logic_vector(1-1 downto 0); -- - field_reg_prbs_reserved : std_logic_vector(12-1 downto 0); -- - field_reg_prbs_sync_threshold : std_logic_vector(16-1 downto 0)) -- - return std_logic_vector is - variable v_data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0); - begin - v_data_out := (others => '0'); - -- - v_data_out(0 downto 0) := field_reg_prbs_sel; -- - v_data_out(1 downto 1) := field_reg_prbs_error_insert; -- - v_data_out(2 downto 2) := field_reg_prbs_clear; -- - v_data_out(3 downto 3) := field_reg_prbs_manual_sync; -- - v_data_out(15 downto 4) := field_reg_prbs_reserved; -- - v_data_out(31 downto 16) := field_reg_prbs_sync_threshold; -- - return v_data_out; - end function fun_set_data_out; - - signal data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); - -- - signal field_reg_prbs_sel : std_logic_vector(1-1 downto 0) - := std_logic_vector(to_signed(0,1)); -- - signal field_reg_prbs_error_insert : std_logic_vector(1-1 downto 0) - := std_logic_vector(to_signed(0,1)); -- - signal field_reg_prbs_clear : std_logic_vector(1-1 downto 0) - := std_logic_vector(to_signed(0,1)); -- - signal field_reg_prbs_manual_sync : std_logic_vector(1-1 downto 0) - := std_logic_vector(to_signed(0,1)); -- - signal field_reg_prbs_reserved : std_logic_vector(12-1 downto 0) - := std_logic_vector(to_signed(0,12)); -- - signal field_reg_prbs_sync_threshold : std_logic_vector(16-1 downto 0) - := std_logic_vector(to_signed(0,16)); -- -begin - - data_out <= fun_set_data_out( -- - field_reg_prbs_sel, -- - field_reg_prbs_error_insert, -- - field_reg_prbs_clear, -- - field_reg_prbs_manual_sync, -- - field_reg_prbs_reserved, -- - field_reg_prbs_sync_threshold -- - ); - - -- resize field data out to the register bus width - -- do only if 1 field and signed-- - po_decoder_data <= data_out; -- - ------------------------------------------------------------STORAGE - prbs_sel_storage: block - begin - prs_write : process(pi_clock) - begin - if rising_edge(pi_clock) then - if pi_reset = '1' then - field_reg_prbs_sel <= std_logic_vector(to_signed(0,1)); - else - -- HW -- - -- SW -- - if pi_decoder_wr_stb = '1' then - field_reg_prbs_sel <= pi_decoder_data(0 downto 0); - end if; - end if; - end if; - end process; - -- - po_reg.prbs_sel.data <= field_reg_prbs_sel; -- - end block prbs_sel_storage; - ------------------------------------------------------------STORAGE - prbs_error_insert_storage: block - begin - prs_write : process(pi_clock) - begin - if rising_edge(pi_clock) then - if pi_reset = '1' then - field_reg_prbs_error_insert <= std_logic_vector(to_signed(0,1)); - else - -- HW -- - -- This is a "singlepulse" register - clear on each clock, - -- unless it is written to with a 1 (see below) - field_reg_prbs_error_insert <= (others => '0'); - -- SW -- - if pi_decoder_wr_stb = '1' then - field_reg_prbs_error_insert <= pi_decoder_data(1 downto 1); - end if; - end if; - end if; - end process; - -- - po_reg.prbs_error_insert.data <= field_reg_prbs_error_insert; -- - end block prbs_error_insert_storage; - ------------------------------------------------------------STORAGE - prbs_clear_storage: block - begin - prs_write : process(pi_clock) - begin - if rising_edge(pi_clock) then - if pi_reset = '1' then - field_reg_prbs_clear <= std_logic_vector(to_signed(0,1)); - else - -- HW -- - -- This is a "singlepulse" register - clear on each clock, - -- unless it is written to with a 1 (see below) - field_reg_prbs_clear <= (others => '0'); - -- SW -- - if pi_decoder_wr_stb = '1' then - field_reg_prbs_clear <= pi_decoder_data(2 downto 2); - end if; - end if; - end if; - end process; - -- - po_reg.prbs_clear.data <= field_reg_prbs_clear; -- - end block prbs_clear_storage; - ------------------------------------------------------------STORAGE - prbs_manual_sync_storage: block - begin - prs_write : process(pi_clock) - begin - if rising_edge(pi_clock) then - if pi_reset = '1' then - field_reg_prbs_manual_sync <= std_logic_vector(to_signed(0,1)); - else - -- HW -- - -- This is a "singlepulse" register - clear on each clock, - -- unless it is written to with a 1 (see below) - field_reg_prbs_manual_sync <= (others => '0'); - -- SW -- - if pi_decoder_wr_stb = '1' then - field_reg_prbs_manual_sync <= pi_decoder_data(3 downto 3); - end if; - end if; - end if; - end process; - -- - po_reg.prbs_manual_sync.data <= field_reg_prbs_manual_sync; -- - end block prbs_manual_sync_storage; - ------------------------------------------------------------STORAGE - prbs_reserved_storage: block - begin - prs_write : process(pi_clock) - begin - if rising_edge(pi_clock) then - if pi_reset = '1' then - field_reg_prbs_reserved <= std_logic_vector(to_signed(0,12)); - else - -- HW -- - -- SW -- - if pi_decoder_wr_stb = '1' then - field_reg_prbs_reserved <= pi_decoder_data(15 downto 4); - end if; - end if; - end if; - end process; - -- - po_reg.prbs_reserved.data <= field_reg_prbs_reserved; -- - end block prbs_reserved_storage; - ------------------------------------------------------------STORAGE - prbs_sync_threshold_storage: block - begin - prs_write : process(pi_clock) - begin - if rising_edge(pi_clock) then - if pi_reset = '1' then - field_reg_prbs_sync_threshold <= std_logic_vector(to_signed(0,16)); - else - -- HW -- - -- SW -- - if pi_decoder_wr_stb = '1' then - field_reg_prbs_sync_threshold <= pi_decoder_data(31 downto 16); - end if; - end if; - end if; - end process; - -- - po_reg.prbs_sync_threshold.data <= field_reg_prbs_sync_threshold; -- - end block prbs_sync_threshold_storage; - ---------------------------------------------------------- -end rtl; ------------------------------------------------ --- register type: config_prbs_seed ------------------------------------------------ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -library desyrdl; -use desyrdl.common.all; - -use work.pkg_msk_top_regs.all; - -entity msk_top_regs_config_prbs_seed is - port ( - pi_clock : in std_logic; - pi_reset : in std_logic; - -- to/from adapter - pi_decoder_rd_stb : in std_logic; - pi_decoder_wr_stb : in std_logic; - pi_decoder_data : in std_logic_vector(C_DATA_WIDTH-1 downto 0); - po_decoder_data : out std_logic_vector(C_DATA_WIDTH-1 downto 0); - - pi_reg : in t_reg_config_prbs_seed_in ; - po_reg : out t_reg_config_prbs_seed_out - ); -end entity msk_top_regs_config_prbs_seed; - -architecture rtl of msk_top_regs_config_prbs_seed is - - -- assign slices of data_out for each field, but force the rest to constant zeros - function fun_set_data_out ( -- - field_reg_config_data : std_logic_vector(32-1 downto 0)) -- - return std_logic_vector is - variable v_data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0); - begin - v_data_out := (others => '0'); - -- - v_data_out(31 downto 0) := field_reg_config_data; -- - return v_data_out; - end function fun_set_data_out; - - signal data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); - -- - signal field_reg_config_data : std_logic_vector(32-1 downto 0) - := std_logic_vector(to_signed(0,32)); -- -begin - - data_out <= fun_set_data_out( -- - field_reg_config_data -- - ); - - -- resize field data out to the register bus width - -- do only if 1 field and signed-- - po_decoder_data <= data_out; -- - ------------------------------------------------------------STORAGE - config_data_storage: block - begin - prs_write : process(pi_clock) - begin - if rising_edge(pi_clock) then - if pi_reset = '1' then - field_reg_config_data <= std_logic_vector(to_signed(0,32)); - else - -- HW -- - -- SW -- - if pi_decoder_wr_stb = '1' then - field_reg_config_data <= pi_decoder_data(31 downto 0); - end if; - end if; - end if; - end process; - -- - po_reg.config_data.data <= field_reg_config_data; -- - end block config_data_storage; - ---------------------------------------------------------- -end rtl; ------------------------------------------------ --- register type: config_prbs_poly ------------------------------------------------ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -library desyrdl; -use desyrdl.common.all; - -use work.pkg_msk_top_regs.all; - -entity msk_top_regs_config_prbs_poly is - port ( - pi_clock : in std_logic; - pi_reset : in std_logic; - -- to/from adapter - pi_decoder_rd_stb : in std_logic; - pi_decoder_wr_stb : in std_logic; - pi_decoder_data : in std_logic_vector(C_DATA_WIDTH-1 downto 0); - po_decoder_data : out std_logic_vector(C_DATA_WIDTH-1 downto 0); - - pi_reg : in t_reg_config_prbs_poly_in ; - po_reg : out t_reg_config_prbs_poly_out - ); -end entity msk_top_regs_config_prbs_poly; - -architecture rtl of msk_top_regs_config_prbs_poly is - - -- assign slices of data_out for each field, but force the rest to constant zeros - function fun_set_data_out ( -- - field_reg_config_data : std_logic_vector(32-1 downto 0)) -- - return std_logic_vector is - variable v_data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0); - begin - v_data_out := (others => '0'); - -- - v_data_out(31 downto 0) := field_reg_config_data; -- - return v_data_out; - end function fun_set_data_out; - - signal data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); - -- - signal field_reg_config_data : std_logic_vector(32-1 downto 0) - := std_logic_vector(to_signed(0,32)); -- -begin - - data_out <= fun_set_data_out( -- - field_reg_config_data -- - ); - - -- resize field data out to the register bus width - -- do only if 1 field and signed-- - po_decoder_data <= data_out; -- - ------------------------------------------------------------STORAGE - config_data_storage: block - begin - prs_write : process(pi_clock) - begin - if rising_edge(pi_clock) then - if pi_reset = '1' then - field_reg_config_data <= std_logic_vector(to_signed(0,32)); - else - -- HW -- - -- SW -- - if pi_decoder_wr_stb = '1' then - field_reg_config_data <= pi_decoder_data(31 downto 0); - end if; - end if; - end if; - end process; - -- - po_reg.config_data.data <= field_reg_config_data; -- - end block config_data_storage; - ---------------------------------------------------------- -end rtl; ------------------------------------------------ --- register type: config_prbs_errmask ------------------------------------------------ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -library desyrdl; -use desyrdl.common.all; - -use work.pkg_msk_top_regs.all; - -entity msk_top_regs_config_prbs_errmask is - port ( - pi_clock : in std_logic; - pi_reset : in std_logic; - -- to/from adapter - pi_decoder_rd_stb : in std_logic; - pi_decoder_wr_stb : in std_logic; - pi_decoder_data : in std_logic_vector(C_DATA_WIDTH-1 downto 0); - po_decoder_data : out std_logic_vector(C_DATA_WIDTH-1 downto 0); - - pi_reg : in t_reg_config_prbs_errmask_in ; - po_reg : out t_reg_config_prbs_errmask_out - ); -end entity msk_top_regs_config_prbs_errmask; - -architecture rtl of msk_top_regs_config_prbs_errmask is - - -- assign slices of data_out for each field, but force the rest to constant zeros - function fun_set_data_out ( -- - field_reg_config_data : std_logic_vector(32-1 downto 0)) -- - return std_logic_vector is - variable v_data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0); - begin - v_data_out := (others => '0'); - -- - v_data_out(31 downto 0) := field_reg_config_data; -- - return v_data_out; - end function fun_set_data_out; - - signal data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); - -- - signal field_reg_config_data : std_logic_vector(32-1 downto 0) - := std_logic_vector(to_signed(0,32)); -- -begin - - data_out <= fun_set_data_out( -- - field_reg_config_data -- - ); - - -- resize field data out to the register bus width - -- do only if 1 field and signed-- - po_decoder_data <= data_out; -- - ------------------------------------------------------------STORAGE - config_data_storage: block - begin - prs_write : process(pi_clock) - begin - if rising_edge(pi_clock) then - if pi_reset = '1' then - field_reg_config_data <= std_logic_vector(to_signed(0,32)); - else - -- HW -- - -- SW -- - if pi_decoder_wr_stb = '1' then - field_reg_config_data <= pi_decoder_data(31 downto 0); - end if; - end if; - end if; - end process; - -- - po_reg.config_data.data <= field_reg_config_data; -- - end block config_data_storage; - ---------------------------------------------------------- -end rtl; ------------------------------------------------ --- register type: stat_32_bits ------------------------------------------------ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -library desyrdl; -use desyrdl.common.all; - -use work.pkg_msk_top_regs.all; - -entity msk_top_regs_stat_32_bits is - port ( - pi_clock : in std_logic; - pi_reset : in std_logic; - -- to/from adapter - pi_decoder_rd_stb : in std_logic; - pi_decoder_wr_stb : in std_logic; - pi_decoder_data : in std_logic_vector(C_DATA_WIDTH-1 downto 0); - po_decoder_data : out std_logic_vector(C_DATA_WIDTH-1 downto 0); - - pi_reg : in t_reg_stat_32_bits_in ; - po_reg : out t_reg_stat_32_bits_out - ); -end entity msk_top_regs_stat_32_bits; - -architecture rtl of msk_top_regs_stat_32_bits is - - -- assign slices of data_out for each field, but force the rest to constant zeros - function fun_set_data_out ( -- - field_reg_status_data : std_logic_vector(32-1 downto 0)) -- - return std_logic_vector is - variable v_data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0); - begin - v_data_out := (others => '0'); - -- - v_data_out(31 downto 0) := field_reg_status_data; -- - return v_data_out; - end function fun_set_data_out; - - signal data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); - -- - signal field_reg_status_data : std_logic_vector(32-1 downto 0) - := std_logic_vector(to_signed(0,32)); -- -begin - - data_out <= fun_set_data_out( -- - field_reg_status_data -- - ); - - -- resize field data out to the register bus width - -- do only if 1 field and signed-- - po_decoder_data <= data_out; -- - ------------------------------------------------------------WIRE - status_data_wire : block -- - begin - -- - field_reg_status_data <= pi_reg.status_data.data(32-1 downto 0); -- - --no signal to read by HW - po_reg.status_data.dummy <= '0'; -- - end block; -- -end rtl; ------------------------------------------------ --- register type: stat_32_errs ------------------------------------------------ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -library desyrdl; -use desyrdl.common.all; - -use work.pkg_msk_top_regs.all; - -entity msk_top_regs_stat_32_errs is - port ( - pi_clock : in std_logic; - pi_reset : in std_logic; - -- to/from adapter - pi_decoder_rd_stb : in std_logic; - pi_decoder_wr_stb : in std_logic; - pi_decoder_data : in std_logic_vector(C_DATA_WIDTH-1 downto 0); - po_decoder_data : out std_logic_vector(C_DATA_WIDTH-1 downto 0); - - pi_reg : in t_reg_stat_32_errs_in ; - po_reg : out t_reg_stat_32_errs_out - ); -end entity msk_top_regs_stat_32_errs; - -architecture rtl of msk_top_regs_stat_32_errs is - - -- assign slices of data_out for each field, but force the rest to constant zeros - function fun_set_data_out ( -- - field_reg_status_data : std_logic_vector(32-1 downto 0)) -- - return std_logic_vector is - variable v_data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0); - begin - v_data_out := (others => '0'); - -- - v_data_out(31 downto 0) := field_reg_status_data; -- - return v_data_out; - end function fun_set_data_out; - - signal data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); - -- - signal field_reg_status_data : std_logic_vector(32-1 downto 0) - := std_logic_vector(to_signed(0,32)); -- -begin - - data_out <= fun_set_data_out( -- - field_reg_status_data -- - ); - - -- resize field data out to the register bus width - -- do only if 1 field and signed-- - po_decoder_data <= data_out; -- - ------------------------------------------------------------WIRE - status_data_wire : block -- - begin - -- - field_reg_status_data <= pi_reg.status_data.data(32-1 downto 0); -- - --no signal to read by HW - po_reg.status_data.dummy <= '0'; -- - end block; -- -end rtl; ------------------------------------------------ --- register type: stat_32_lpf_acc ------------------------------------------------ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -library desyrdl; -use desyrdl.common.all; - -use work.pkg_msk_top_regs.all; - -entity msk_top_regs_stat_32_lpf_acc is - port ( - pi_clock : in std_logic; - pi_reset : in std_logic; - -- to/from adapter - pi_decoder_rd_stb : in std_logic; - pi_decoder_wr_stb : in std_logic; - pi_decoder_data : in std_logic_vector(C_DATA_WIDTH-1 downto 0); - po_decoder_data : out std_logic_vector(C_DATA_WIDTH-1 downto 0); - - pi_reg : in t_reg_stat_32_lpf_acc_in ; - po_reg : out t_reg_stat_32_lpf_acc_out - ); -end entity msk_top_regs_stat_32_lpf_acc; - -architecture rtl of msk_top_regs_stat_32_lpf_acc is - - -- assign slices of data_out for each field, but force the rest to constant zeros - function fun_set_data_out ( -- - field_reg_status_data : std_logic_vector(32-1 downto 0)) -- - return std_logic_vector is - variable v_data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0); - begin - v_data_out := (others => '0'); - -- - v_data_out(31 downto 0) := field_reg_status_data; -- - return v_data_out; - end function fun_set_data_out; - - signal data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); - -- - signal field_reg_status_data : std_logic_vector(32-1 downto 0) - := std_logic_vector(to_signed(0,32)); -- -begin - - data_out <= fun_set_data_out( -- - field_reg_status_data -- - ); - - -- resize field data out to the register bus width - -- do only if 1 field and signed-- - po_decoder_data <= data_out; -- - ------------------------------------------------------------WIRE - status_data_wire : block -- - begin - -- - field_reg_status_data <= pi_reg.status_data.data(32-1 downto 0); -- - --no signal to read by HW - po_reg.status_data.dummy <= '0'; -- - end block; -- -end rtl; ------------------------------------------------ --- register type: msk_stat_3 ------------------------------------------------ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -library desyrdl; -use desyrdl.common.all; - -use work.pkg_msk_top_regs.all; - -entity msk_top_regs_msk_stat_3 is - port ( - pi_clock : in std_logic; - pi_reset : in std_logic; - -- to/from adapter - pi_decoder_rd_stb : in std_logic; - pi_decoder_wr_stb : in std_logic; - pi_decoder_data : in std_logic_vector(C_DATA_WIDTH-1 downto 0); - po_decoder_data : out std_logic_vector(C_DATA_WIDTH-1 downto 0); - - pi_reg : in t_reg_msk_stat_3_in ; - po_reg : out t_reg_msk_stat_3_out - ); -end entity msk_top_regs_msk_stat_3; - -architecture rtl of msk_top_regs_msk_stat_3 is - - -- assign slices of data_out for each field, but force the rest to constant zeros - function fun_set_data_out ( -- - field_reg_xfer_count : std_logic_vector(32-1 downto 0)) -- - return std_logic_vector is - variable v_data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0); - begin - v_data_out := (others => '0'); - -- - v_data_out(31 downto 0) := field_reg_xfer_count; -- - return v_data_out; - end function fun_set_data_out; - - signal data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); - -- - signal field_reg_xfer_count : std_logic_vector(32-1 downto 0) - := std_logic_vector(to_signed(0,32)); -- -begin - - data_out <= fun_set_data_out( -- - field_reg_xfer_count -- - ); - - -- resize field data out to the register bus width - -- do only if 1 field and signed-- - po_decoder_data <= data_out; -- - ------------------------------------------------------------WIRE - xfer_count_wire : block -- - begin - -- - field_reg_xfer_count <= pi_reg.xfer_count.data(32-1 downto 0); -- - --no signal to read by HW - po_reg.xfer_count.dummy <= '0'; -- - end block; -- -end rtl; ------------------------------------------------ --- register type: rx_sample_discard ------------------------------------------------ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -library desyrdl; -use desyrdl.common.all; - -use work.pkg_msk_top_regs.all; - -entity msk_top_regs_rx_sample_discard is - port ( - pi_clock : in std_logic; - pi_reset : in std_logic; - -- to/from adapter - pi_decoder_rd_stb : in std_logic; - pi_decoder_wr_stb : in std_logic; - pi_decoder_data : in std_logic_vector(C_DATA_WIDTH-1 downto 0); - po_decoder_data : out std_logic_vector(C_DATA_WIDTH-1 downto 0); - - pi_reg : in t_reg_rx_sample_discard_in ; - po_reg : out t_reg_rx_sample_discard_out - ); -end entity msk_top_regs_rx_sample_discard; - -architecture rtl of msk_top_regs_rx_sample_discard is - - -- assign slices of data_out for each field, but force the rest to constant zeros - function fun_set_data_out ( -- - field_reg_rx_sample_discard : std_logic_vector(8-1 downto 0); -- - field_reg_rx_nco_discard : std_logic_vector(8-1 downto 0)) -- - return std_logic_vector is - variable v_data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0); - begin - v_data_out := (others => '0'); - -- - v_data_out(7 downto 0) := field_reg_rx_sample_discard; -- - v_data_out(15 downto 8) := field_reg_rx_nco_discard; -- - return v_data_out; - end function fun_set_data_out; - - signal data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); - -- - signal field_reg_rx_sample_discard : std_logic_vector(8-1 downto 0) - := std_logic_vector(to_signed(0,8)); -- - signal field_reg_rx_nco_discard : std_logic_vector(8-1 downto 0) - := std_logic_vector(to_signed(0,8)); -- -begin - - data_out <= fun_set_data_out( -- - field_reg_rx_sample_discard, -- - field_reg_rx_nco_discard -- - ); - - -- resize field data out to the register bus width - -- do only if 1 field and signed-- - po_decoder_data <= data_out; -- - ------------------------------------------------------------STORAGE - rx_sample_discard_storage: block - begin - prs_write : process(pi_clock) - begin - if rising_edge(pi_clock) then - if pi_reset = '1' then - field_reg_rx_sample_discard <= std_logic_vector(to_signed(0,8)); - else - -- HW -- - -- SW -- - if pi_decoder_wr_stb = '1' then - field_reg_rx_sample_discard <= pi_decoder_data(7 downto 0); - end if; - end if; - end if; - end process; - -- - po_reg.rx_sample_discard.data <= field_reg_rx_sample_discard; -- - end block rx_sample_discard_storage; - ------------------------------------------------------------STORAGE - rx_nco_discard_storage: block - begin - prs_write : process(pi_clock) - begin - if rising_edge(pi_clock) then - if pi_reset = '1' then - field_reg_rx_nco_discard <= std_logic_vector(to_signed(0,8)); - else - -- HW -- - -- SW -- - if pi_decoder_wr_stb = '1' then - field_reg_rx_nco_discard <= pi_decoder_data(15 downto 8); - end if; - end if; - end if; - end process; - -- - po_reg.rx_nco_discard.data <= field_reg_rx_nco_discard; -- - end block rx_nco_discard_storage; - ---------------------------------------------------------- -end rtl; ------------------------------------------------ --- register type: lpf_config_2 ------------------------------------------------ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -library desyrdl; -use desyrdl.common.all; - -use work.pkg_msk_top_regs.all; - -entity msk_top_regs_lpf_config_2 is - port ( - pi_clock : in std_logic; - pi_reset : in std_logic; - -- to/from adapter - pi_decoder_rd_stb : in std_logic; - pi_decoder_wr_stb : in std_logic; - pi_decoder_data : in std_logic_vector(C_DATA_WIDTH-1 downto 0); - po_decoder_data : out std_logic_vector(C_DATA_WIDTH-1 downto 0); - - pi_reg : in t_reg_lpf_config_2_in ; - po_reg : out t_reg_lpf_config_2_out - ); -end entity msk_top_regs_lpf_config_2; - -architecture rtl of msk_top_regs_lpf_config_2 is - - -- assign slices of data_out for each field, but force the rest to constant zeros - function fun_set_data_out ( -- - field_reg_p_gain : std_logic_vector(24-1 downto 0); -- - field_reg_p_shift : std_logic_vector(8-1 downto 0)) -- - return std_logic_vector is - variable v_data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0); - begin - v_data_out := (others => '0'); - -- - v_data_out(23 downto 0) := field_reg_p_gain; -- - v_data_out(31 downto 24) := field_reg_p_shift; -- - return v_data_out; - end function fun_set_data_out; - - signal data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); - -- - signal field_reg_p_gain : std_logic_vector(24-1 downto 0) - := std_logic_vector(to_signed(0,24)); -- - signal field_reg_p_shift : std_logic_vector(8-1 downto 0) - := std_logic_vector(to_signed(0,8)); -- -begin - - data_out <= fun_set_data_out( -- - field_reg_p_gain, -- - field_reg_p_shift -- - ); - - -- resize field data out to the register bus width - -- do only if 1 field and signed-- - po_decoder_data <= data_out; -- - ------------------------------------------------------------STORAGE - p_gain_storage: block - begin - prs_write : process(pi_clock) - begin - if rising_edge(pi_clock) then - if pi_reset = '1' then - field_reg_p_gain <= std_logic_vector(to_signed(0,24)); - else - -- HW -- - -- SW -- - if pi_decoder_wr_stb = '1' then - field_reg_p_gain <= pi_decoder_data(23 downto 0); - end if; - end if; - end if; - end process; - -- - po_reg.p_gain.data <= field_reg_p_gain; -- - end block p_gain_storage; - ------------------------------------------------------------STORAGE - p_shift_storage: block - begin - prs_write : process(pi_clock) - begin - if rising_edge(pi_clock) then - if pi_reset = '1' then - field_reg_p_shift <= std_logic_vector(to_signed(0,8)); - else - -- HW -- - -- SW -- - if pi_decoder_wr_stb = '1' then - field_reg_p_shift <= pi_decoder_data(31 downto 24); - end if; - end if; - end if; - end process; - -- - po_reg.p_shift.data <= field_reg_p_shift; -- - end block p_shift_storage; - ---------------------------------------------------------- -end rtl; ------------------------------------------------ --- register type: observation_data ------------------------------------------------ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -library desyrdl; -use desyrdl.common.all; - -use work.pkg_msk_top_regs.all; - -entity msk_top_regs_observation_data is - port ( - pi_clock : in std_logic; - pi_reset : in std_logic; - -- to/from adapter - pi_decoder_rd_stb : in std_logic; - pi_decoder_wr_stb : in std_logic; - pi_decoder_data : in std_logic_vector(C_DATA_WIDTH-1 downto 0); - po_decoder_data : out std_logic_vector(C_DATA_WIDTH-1 downto 0); - - pi_reg : in t_reg_observation_data_in ; - po_reg : out t_reg_observation_data_out - ); -end entity msk_top_regs_observation_data; - -architecture rtl of msk_top_regs_observation_data is - - -- assign slices of data_out for each field, but force the rest to constant zeros - function fun_set_data_out ( -- - field_reg_data32 : std_logic_vector(32-1 downto 0)) -- - return std_logic_vector is - variable v_data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0); - begin - v_data_out := (others => '0'); - -- - v_data_out(31 downto 0) := field_reg_data32; -- - return v_data_out; - end function fun_set_data_out; - - signal data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); - -- - signal field_reg_data32 : std_logic_vector(32-1 downto 0) - := std_logic_vector(to_signed(0,32)); -- -begin - - data_out <= fun_set_data_out( -- - field_reg_data32 -- - ); - - -- resize field data out to the register bus width - -- do only if 1 field and signed-- - po_decoder_data <= data_out; -- - ------------------------------------------------------------WIRE - data32_wire : block -- - begin - -- - field_reg_data32 <= pi_reg.data.data(32-1 downto 0); -- - --no signal to read by HW - po_reg.data.dummy <= '0'; -- - end block; -- -end rtl; ------------------------------------------------ --- register type: tx_sync_ctrl ------------------------------------------------ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -library desyrdl; -use desyrdl.common.all; - -use work.pkg_msk_top_regs.all; - -entity msk_top_regs_tx_sync_ctrl is - port ( - pi_clock : in std_logic; - pi_reset : in std_logic; - -- to/from adapter - pi_decoder_rd_stb : in std_logic; - pi_decoder_wr_stb : in std_logic; - pi_decoder_data : in std_logic_vector(C_DATA_WIDTH-1 downto 0); - po_decoder_data : out std_logic_vector(C_DATA_WIDTH-1 downto 0); - - pi_reg : in t_reg_tx_sync_ctrl_in ; - po_reg : out t_reg_tx_sync_ctrl_out - ); -end entity msk_top_regs_tx_sync_ctrl; - -architecture rtl of msk_top_regs_tx_sync_ctrl is - - -- assign slices of data_out for each field, but force the rest to constant zeros - function fun_set_data_out ( -- - field_reg_tx_sync_ena : std_logic_vector(1-1 downto 0); -- - field_reg_tx_sync_force : std_logic_vector(1-1 downto 0); -- - field_reg_tx_sync_f1 : std_logic_vector(1-1 downto 0); -- - field_reg_tx_sync_f2 : std_logic_vector(1-1 downto 0)) -- - return std_logic_vector is - variable v_data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0); - begin - v_data_out := (others => '0'); - -- - v_data_out(0 downto 0) := field_reg_tx_sync_ena; -- - v_data_out(1 downto 1) := field_reg_tx_sync_force; -- - v_data_out(2 downto 2) := field_reg_tx_sync_f1; -- - v_data_out(3 downto 3) := field_reg_tx_sync_f2; -- - return v_data_out; - end function fun_set_data_out; - - signal data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); - -- - signal field_reg_tx_sync_ena : std_logic_vector(1-1 downto 0) - := std_logic_vector(to_signed(0,1)); -- - signal field_reg_tx_sync_force : std_logic_vector(1-1 downto 0) - := std_logic_vector(to_signed(0,1)); -- - signal field_reg_tx_sync_f1 : std_logic_vector(1-1 downto 0) - := std_logic_vector(to_signed(0,1)); -- - signal field_reg_tx_sync_f2 : std_logic_vector(1-1 downto 0) - := std_logic_vector(to_signed(0,1)); -- -begin - - data_out <= fun_set_data_out( -- - field_reg_tx_sync_ena, -- - field_reg_tx_sync_force, -- - field_reg_tx_sync_f1, -- - field_reg_tx_sync_f2 -- - ); - - -- resize field data out to the register bus width - -- do only if 1 field and signed-- - po_decoder_data <= data_out; -- - ------------------------------------------------------------STORAGE - tx_sync_ena_storage: block - begin - prs_write : process(pi_clock) - begin - if rising_edge(pi_clock) then - if pi_reset = '1' then - field_reg_tx_sync_ena <= std_logic_vector(to_signed(0,1)); - else - -- HW -- - -- SW -- - if pi_decoder_wr_stb = '1' then - field_reg_tx_sync_ena <= pi_decoder_data(0 downto 0); - end if; - end if; - end if; - end process; - -- - po_reg.tx_sync_ena.data <= field_reg_tx_sync_ena; -- - end block tx_sync_ena_storage; - ------------------------------------------------------------STORAGE - tx_sync_force_storage: block - begin - prs_write : process(pi_clock) - begin - if rising_edge(pi_clock) then - if pi_reset = '1' then - field_reg_tx_sync_force <= std_logic_vector(to_signed(0,1)); - else - -- HW -- - -- SW -- - if pi_decoder_wr_stb = '1' then - field_reg_tx_sync_force <= pi_decoder_data(1 downto 1); - end if; - end if; - end if; - end process; - -- - po_reg.tx_sync_force.data <= field_reg_tx_sync_force; -- - end block tx_sync_force_storage; - ------------------------------------------------------------STORAGE - tx_sync_f1_storage: block - begin - prs_write : process(pi_clock) - begin - if rising_edge(pi_clock) then - if pi_reset = '1' then - field_reg_tx_sync_f1 <= std_logic_vector(to_signed(0,1)); - else - -- HW -- - -- SW -- - if pi_decoder_wr_stb = '1' then - field_reg_tx_sync_f1 <= pi_decoder_data(2 downto 2); - end if; - end if; - end if; - end process; - -- - po_reg.tx_sync_f1.data <= field_reg_tx_sync_f1; -- - end block tx_sync_f1_storage; - ------------------------------------------------------------STORAGE - tx_sync_f2_storage: block - begin - prs_write : process(pi_clock) - begin - if rising_edge(pi_clock) then - if pi_reset = '1' then - field_reg_tx_sync_f2 <= std_logic_vector(to_signed(0,1)); - else - -- HW -- - -- SW -- - if pi_decoder_wr_stb = '1' then - field_reg_tx_sync_f2 <= pi_decoder_data(3 downto 3); - end if; - end if; - end if; - end process; - -- - po_reg.tx_sync_f2.data <= field_reg_tx_sync_f2; -- - end block tx_sync_f2_storage; - ---------------------------------------------------------- -end rtl; ------------------------------------------------ --- register type: tx_sync_cnt ------------------------------------------------ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -library desyrdl; -use desyrdl.common.all; - -use work.pkg_msk_top_regs.all; - -entity msk_top_regs_tx_sync_cnt is - port ( - pi_clock : in std_logic; - pi_reset : in std_logic; - -- to/from adapter - pi_decoder_rd_stb : in std_logic; - pi_decoder_wr_stb : in std_logic; - pi_decoder_data : in std_logic_vector(C_DATA_WIDTH-1 downto 0); - po_decoder_data : out std_logic_vector(C_DATA_WIDTH-1 downto 0); - - pi_reg : in t_reg_tx_sync_cnt_in ; - po_reg : out t_reg_tx_sync_cnt_out - ); -end entity msk_top_regs_tx_sync_cnt; - -architecture rtl of msk_top_regs_tx_sync_cnt is - - -- assign slices of data_out for each field, but force the rest to constant zeros - function fun_set_data_out ( -- - field_reg_tx_sync_cnt : std_logic_vector(24-1 downto 0)) -- - return std_logic_vector is - variable v_data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0); - begin - v_data_out := (others => '0'); - -- - v_data_out(23 downto 0) := field_reg_tx_sync_cnt; -- - return v_data_out; - end function fun_set_data_out; - - signal data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); - -- - signal field_reg_tx_sync_cnt : std_logic_vector(24-1 downto 0) - := std_logic_vector(to_signed(0,24)); -- -begin - - data_out <= fun_set_data_out( -- - field_reg_tx_sync_cnt -- - ); - - -- resize field data out to the register bus width - -- do only if 1 field and signed-- - po_decoder_data <= data_out; -- - ------------------------------------------------------------STORAGE - tx_sync_cnt_storage: block - begin - prs_write : process(pi_clock) - begin - if rising_edge(pi_clock) then - if pi_reset = '1' then - field_reg_tx_sync_cnt <= std_logic_vector(to_signed(0,24)); - else - -- HW -- - -- SW -- - if pi_decoder_wr_stb = '1' then - field_reg_tx_sync_cnt <= pi_decoder_data(23 downto 0); - end if; - end if; - end if; - end process; - -- - po_reg.tx_sync_cnt.data <= field_reg_tx_sync_cnt; -- - end block tx_sync_cnt_storage; - ---------------------------------------------------------- -end rtl; ------------------------------------------------ --- register type: lowpass_ema_alpha ------------------------------------------------ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -library desyrdl; -use desyrdl.common.all; - -use work.pkg_msk_top_regs.all; - -entity msk_top_regs_lowpass_ema_alpha is - port ( - pi_clock : in std_logic; - pi_reset : in std_logic; - -- to/from adapter - pi_decoder_rd_stb : in std_logic; - pi_decoder_wr_stb : in std_logic; - pi_decoder_data : in std_logic_vector(C_DATA_WIDTH-1 downto 0); - po_decoder_data : out std_logic_vector(C_DATA_WIDTH-1 downto 0); - - pi_reg : in t_reg_lowpass_ema_alpha_in ; - po_reg : out t_reg_lowpass_ema_alpha_out - ); -end entity msk_top_regs_lowpass_ema_alpha; - -architecture rtl of msk_top_regs_lowpass_ema_alpha is - - -- assign slices of data_out for each field, but force the rest to constant zeros - function fun_set_data_out ( -- - field_reg_alpha : std_logic_vector(18-1 downto 0)) -- - return std_logic_vector is - variable v_data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0); - begin - v_data_out := (others => '0'); - -- - v_data_out(17 downto 0) := field_reg_alpha; -- - return v_data_out; - end function fun_set_data_out; - - signal data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); - -- - signal field_reg_alpha : std_logic_vector(18-1 downto 0) - := std_logic_vector(to_signed(0,18)); -- -begin - - data_out <= fun_set_data_out( -- - field_reg_alpha -- - ); - - -- resize field data out to the register bus width - -- do only if 1 field and signed-- - po_decoder_data <= data_out; -- - ------------------------------------------------------------STORAGE - alpha_storage: block - begin - prs_write : process(pi_clock) - begin - if rising_edge(pi_clock) then - if pi_reset = '1' then - field_reg_alpha <= std_logic_vector(to_signed(0,18)); - else - -- HW -- - -- SW -- - if pi_decoder_wr_stb = '1' then - field_reg_alpha <= pi_decoder_data(17 downto 0); - end if; - end if; - end if; - end process; - -- - po_reg.alpha.data <= field_reg_alpha; -- - end block alpha_storage; - ---------------------------------------------------------- -end rtl; ------------------------------------------------ --- register type: rx_power ------------------------------------------------ -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -library desyrdl; -use desyrdl.common.all; - -use work.pkg_msk_top_regs.all; - -entity msk_top_regs_rx_power is - port ( - pi_clock : in std_logic; - pi_reset : in std_logic; - -- to/from adapter - pi_decoder_rd_stb : in std_logic; - pi_decoder_wr_stb : in std_logic; - pi_decoder_data : in std_logic_vector(C_DATA_WIDTH-1 downto 0); - po_decoder_data : out std_logic_vector(C_DATA_WIDTH-1 downto 0); - - pi_reg : in t_reg_rx_power_in ; - po_reg : out t_reg_rx_power_out - ); -end entity msk_top_regs_rx_power; - -architecture rtl of msk_top_regs_rx_power is - - -- assign slices of data_out for each field, but force the rest to constant zeros - function fun_set_data_out ( -- - field_reg_rx_power : std_logic_vector(23-1 downto 0)) -- - return std_logic_vector is - variable v_data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0); - begin - v_data_out := (others => '0'); - -- - v_data_out(22 downto 0) := field_reg_rx_power; -- - return v_data_out; - end function fun_set_data_out; - - signal data_out : std_logic_vector(C_DATA_WIDTH-1 downto 0) := (others => '0'); - -- - signal field_reg_rx_power : std_logic_vector(23-1 downto 0) - := std_logic_vector(to_signed(0,23)); -- -begin - - data_out <= fun_set_data_out( -- - field_reg_rx_power -- - ); - - -- resize field data out to the register bus width - -- do only if 1 field and signed-- - po_decoder_data <= data_out; -- - ------------------------------------------------------------WIRE - rx_power_wire : block -- - begin - -- - field_reg_rx_power <= pi_reg.rx_power.data(23-1 downto 0); -- - --no signal to read by HW - po_reg.rx_power.dummy <= '0'; -- - end block; -- -end rtl; ------------------------------------------------ - --------------------------------------------------------------------------------- --- Register types in regfiles --------------------------------------------------------------------------------- --- \ No newline at end of file diff --git a/sim/Makefile b/sim/Makefile index ea1aa80..672cb30 100644 --- a/sim/Makefile +++ b/sim/Makefile @@ -17,16 +17,20 @@ ifeq ($(SIM),nvc) endif SRC = ../src -RDL = ../rdl/vhdl/msk_top_regs - -VHDL_SOURCES_desyrdl = ../rdl/vhdl/desyrdl/pkg_desyrdl_common.vhd - -VHDL_LIB_ORDER = desyrdl +RDL = ../rdl/ # use VHDL_SOURCES for VHDL files -VHDL_SOURCES += $(RDL)/msk_top_regs_decoder_axi4l.vhd \ - $(RDL)/pkg_msk_top_regs.vhd \ - $(RDL)/msk_top_regs.vhd \ +VHDL_SOURCES += $(RDL)/src/axi4lite_intf_pkg.vhd \ + $(RDL)/src/reg_utils.vhd \ + $(RDL)/outputs/rtl/msk_top_regs_pkg.vhd \ + $(RDL)/outputs/rtl/msk_top_regs.vhd \ + $(SRC)/pulse_detect.vhd \ + $(SRC)/data_capture.vhd \ + $(SRC)/cdc_resync.vhd \ + $(SRC)/frame_sync_detector.vhd \ + $(SRC)/axis_async_fifo.vhd \ + $(SRC)/axis_dma_adapter.vhd \ + $(SRC)/byte_to_bit_deserializer.vhd \ $(SRC)/msk_top_csr.vhd \ ../lowpass_ema/src/lowpass_ema.vhd \ ../power_detector/src/power_detector.vhd \ diff --git a/sim/desyrdl b/sim/desyrdl deleted file mode 120000 index 3ef65d1..0000000 --- a/sim/desyrdl +++ /dev/null @@ -1 +0,0 @@ -../rdl/cocotb/desyrdl \ No newline at end of file diff --git a/sim/msk_test.py b/sim/msk_test.py index d3d02e5..7792c44 100755 --- a/sim/msk_test.py +++ b/sim/msk_test.py @@ -65,7 +65,8 @@ import sys import inspect -from desyrdl import addrmap_ch0 +from msk_top_regs.reg_model.msk_top_regs import msk_top_regs_cls +from msk_top_regs.lib import AsyncCallbackSet, AsyncCallbackSetLegacy #------------------------------------------------------------------------------------------------------ # __ __ ___ __ __ ___ __ __ @@ -129,9 +130,11 @@ def __init__(self, dut): self.aclk = dut.s_axis_aclk self.aresetn = dut.s_axis_aresetn - self.tvalid = dut.s_axis_valid - self.tready = dut.s_axis_ready - self.tdata = dut.s_axis_data + self.tvalid = dut.s_axis_tvalid + self.tready = dut.s_axis_tready + self.tdata = dut.s_axis_tdata + self.tlast = dut.s_axis_tlast + self.tkeep = dut.s_axis_tkeep self.aresetn.value = 1 self.tvalid.value = 0 @@ -259,9 +262,11 @@ async def write_dwords(self,addr, data): await self.write(addr, data[0]) - async def read(self, addr): + async def read(self, addr, width, accesswidth): await RisingEdge(self.aclk) + await RisingEdge(self.aclk) + await RisingEdge(self.aclk) self.arvalid.value = 1 self.araddr.value = addr @@ -280,15 +285,17 @@ async def read(self, addr): self.rready.value = 0 - await RisingEdge(self.aclk) - await RisingEdge(self.aclk) + read_data = self.rdata.value.integer + await RisingEdge(self.aclk) - return self.rdata.value.integer + return read_data - async def write(self, addr, data): + async def write(self, addr, width, accesswidth, data): + self.dut.s_axi_awvalid.value = 1 + self.dut.s_axi_wvalid.value = 1 self.awaddr.value = addr self.wdata.value = data self.wstrb.value = 15 @@ -296,9 +303,6 @@ async def write(self, addr, data): await RisingEdge(self.aclk) - self.dut.s_axi_awvalid.value = 1 - self.dut.s_axi_wvalid.value = 1 - while self.awready.value == 0 and self.wready.value == 0: await RisingEdge(self.aclk) @@ -497,7 +501,7 @@ async def generate_data(self): while self.sim_run: data = await self.gen() - print("Data: ", data) + self.dut._log.info("Data: %s", hex(data)) await self.saxis.send(data) self.dut._log.info("...prbs generator - done") @@ -670,7 +674,7 @@ async def msk_test_1(dut): print("Instantiate registers") axi = axi_bus(dut) - regs = addrmap_ch0.Addrmap(axi) + regs = msk_top_regs_cls(callbacks=AsyncCallbackSet(read_callback=axi.read, write_callback=axi.write)) tx_samples = [] tx_time = [] @@ -679,8 +683,8 @@ async def msk_test_1(dut): rx_sample_rate = tx_sample_rate / tx_rx_sample_ratio - tx_data_width = 32 - rx_data_width = 32 + tx_data_width = 8 + rx_data_width = 8 await cocotb.start(Clock(dut.clk, tx_sample_per, units="fs").start()) @@ -718,110 +722,50 @@ async def msk_test_1(dut): dut.rx_samples_I.value = 0 dut.rx_samples_Q.value = 0 - hash_id = await regs.read("msk_top_regs", "Hash_ID_Low") - - dut.s_axi_wvalid.value = 1 - dut.s_axi_awvalid.value = 1 - await regs.write("msk_top_regs", "Fb_FreqWord", br_fcw) - # await axi.write(20, int(f1 / sample_rate * 2.0**32)) # F1 frequency word - dut.s_axi_wvalid.value = 1 - dut.s_axi_awvalid.value = 1 - await regs.write("msk_top_regs", "TX_F1_FreqWord", f1_fcw_tx) - dut.s_axi_wvalid.value = 1 - dut.s_axi_awvalid.value = 1 - await regs.write("msk_top_regs", "TX_F2_FreqWord", f2_fcw_tx) - dut.s_axi_wvalid.value = 1 - dut.s_axi_awvalid.value = 1 - await regs.write("msk_top_regs", "RX_F1_FreqWord", f1_fcw_rx) - dut.s_axi_wvalid.value = 1 - dut.s_axi_awvalid.value = 1 - await regs.write("msk_top_regs", "RX_F2_FreqWord", f2_fcw_rx) - dut.s_axi_wvalid.value = 1 - dut.s_axi_awvalid.value = 1 - await regs.write("msk_top_regs", "Rx_Sample_Discard", (tx_rx_sample_ratio-1 << 8) + tx_rx_sample_ratio-1) - # await axi.write(28, (50 << 16) + 20) # p-gain / i-gain - dut.s_axi_wvalid.value = 1 - dut.s_axi_awvalid.value = 1 - await regs.write("msk_top_regs", "LPF_Config_0", (lpf_alpha << 8)) - # await axi.write(32, (2 << 16)) # low-pass filter alpha - dut.s_axi_wvalid.value = 1 - dut.s_axi_awvalid.value = 1 - await regs.write("msk_top_regs", "LPF_Config_1", (i_shift << 24) + i_gain) - # await axi.write(36, 8) - dut.s_axi_wvalid.value = 1 - dut.s_axi_awvalid.value = 1 - await regs.write("msk_top_regs", "LPF_Config_2", (p_shift << 24) + p_gain) - # await axi.write(36, 8) - dut.s_axi_wvalid.value = 1 - dut.s_axi_awvalid.value = 1 - await regs.write("msk_top_regs", "Tx_Data_Width", tx_data_width) - # await axi.write(40, 8) - dut.s_axi_wvalid.value = 1 - dut.s_axi_awvalid.value = 1 - await regs.write("msk_top_regs", "Rx_Data_Width", rx_data_width) - # await axi.write(44, 1) # Select PRBS data path - dut.s_axi_wvalid.value = 1 - dut.s_axi_awvalid.value = 1 - await regs.write("msk_top_regs", "PRBS_Control", (autosync_threshold << 16) + 1) - # await axi.write(48, (1 << 31) + (1 << 28)) # Polynomial - dut.s_axi_wvalid.value = 1 - dut.s_axi_awvalid.value = 1 - await regs.write("msk_top_regs", "PRBS_Polynomial", (1 << 30) + (1 << 27)) - # await axi.write(52, 65535) # initial state - dut.s_axi_wvalid.value = 1 - dut.s_axi_awvalid.value = 1 - await regs.write("msk_top_regs", "PRBS_Initial_State", 0x8E7589FD) - # await axi.write(56, 1) # Error Mask - dut.s_axi_wvalid.value = 1 - dut.s_axi_awvalid.value = 1 - await regs.write("msk_top_regs", "PRBS_Error_Mask", 1) - # await axi.write(60, 0) - dut.s_axi_wvalid.value = 1 - dut.s_axi_awvalid.value = 1 - await regs.write("msk_top_regs", "lowpass_ema_alpha1", 64) - # await axi.write(60, 0) - dut.s_axi_wvalid.value = 1 - dut.s_axi_awvalid.value = 1 - await regs.write("msk_top_regs", "lowpass_ema_alpha2", 64) - # await axi.write(60, 0) - dut.s_axi_wvalid.value = 1 - dut.s_axi_awvalid.value = 1 - await regs.write("msk_top_regs", "Tx_Sync_Ctrl", 0b0001) - # await axi.write(60, 0) - dut.s_axi_wvalid.value = 1 - dut.s_axi_awvalid.value = 1 - await regs.write("msk_top_regs", "Tx_Sync_Cnt", 192) - # await axi.write(60, 0) - - - hash_id = await regs.read("msk_top_regs", "Hash_ID_Low") - #print("Hash ID: ", hex(hash_id)) - hash_id = await regs.read("msk_top_regs", "Hash_ID_Low") - #print("Hash ID: ", hex(hash_id)) - hash_id = await regs.read("msk_top_regs", "Hash_ID_Low") - #print("Hash ID: ", hex(hash_id)) - hash_id = await regs.read("msk_top_regs", "Hash_ID_Low") - #print("Hash ID: ", hex(hash_id)) - hash_id = await regs.read("msk_top_regs", "Hash_ID_Low") + hash_low = await regs.Hash_ID_Low.read() + hash_high = await regs.Hash_ID_High.read() + + await regs.Fb_FreqWord.write(br_fcw) + await regs.TX_F1_FreqWord.write(f1_fcw_tx) + await regs.TX_F2_FreqWord.write(f2_fcw_tx) + await regs.RX_F1_FreqWord.write(f1_fcw_rx) + await regs.RX_F2_FreqWord.write(f2_fcw_rx) + await regs.Rx_Sample_Discard.write((tx_rx_sample_ratio-1 << 8) + tx_rx_sample_ratio-1) + await regs.LPF_Config_0.write((lpf_alpha << 8)) + await regs.LPF_Config_1.write((i_shift << 24) + i_gain) + await regs.LPF_Config_2.write((p_shift << 24) + p_gain) + await regs.Tx_Data_Width.write(tx_data_width) + await regs.Rx_Data_Width.write(rx_data_width) + await regs.PRBS_Control.write((autosync_threshold << 16) + 1) + await regs.PRBS_Polynomial.write((1 << 30) + (1 << 27)) + await regs.PRBS_Initial_State.write(0x8E7589FD) + await regs.PRBS_Error_Mask.write(1) + await regs.lowpass_ema_alpha1.write(64) + await regs.lowpass_ema_alpha2.write(64) + await regs.Tx_Sync_Ctrl.write(0b0001) + await regs.Tx_Sync_Cnt.write(192) + + + hash_id = await regs.Hash_ID_Low.read() + hash_id = await regs.Hash_ID_Low.read() + hash_id = await regs.Hash_ID_Low.read() + hash_id = await regs.Hash_ID_Low.read() + hash_id = await regs.Hash_ID_Low.read() print("Hash ID Low: ", hex(hash_id)) - hash_id = await regs.read("msk_top_regs", "Hash_ID_High") + hash_id = await regs.Hash_ID_High.read() print("Hash ID High: ", hex(hash_id)) await Timer(100, units="ns") await RisingEdge(dut.clk) - dut.s_axi_wvalid.value = 1 - dut.s_axi_awvalid.value = 1 - await regs.write("msk_top_regs", "MSK_Init", 0) - dut.s_axi_wvalid.value = 1 - dut.s_axi_awvalid.value = 1 - await regs.write("msk_top_regs", "MSK_Control", (diff_enc_loopback << 4) + (rx_invert <<2) + ptt) + await regs.MSK_Init.write(0) + await regs.MSK_Control.write((diff_enc_loopback << 4) + (rx_invert <<2) + ptt) await RisingEdge(dut.clk) msksim = msk(dut, dut.clk, dut.tx_samples_I, dut.tx_samples_Q, dut.rx_sample_clk, dut.rx_samples_dec) - #pn = prbs(dut, dut.clk, axis, tx_data_width, rx_data_width, dut.rx_data, dut.rx_dvalid) + pn = prbs(dut, dut.clk, axis, tx_data_width, rx_data_width, dut.m_axis_tdata, dut.m_axis_tvalid) ducsim = duc(dut, msksim, local_osc, tx_sample_period) ddcsim = ddc(dut, msksim, ducsim, local_osc, tx_sample_period) @@ -830,8 +774,8 @@ async def msk_test_1(dut): await cocotb.start(msksim.rx_sample_capture()) await cocotb.start(ducsim.upconvert()) await cocotb.start(ddcsim.downconvert()) - #await cocotb.start(pn.generate_data()) - #await cocotb.start(pn.check_data()) + await cocotb.start(pn.generate_data()) + await cocotb.start(pn.check_data()) sim_time = get_sim_time("us") sim_start = sim_time @@ -841,8 +785,8 @@ async def msk_test_1(dut): msksim.sim_run = True - #pn.sim_run = True - #pn.sync = 100 + pn.sim_run = True + pn.sync = 100 while sim_time < run_time: #sim_start + run_time: @@ -853,19 +797,18 @@ async def msk_test_1(dut): # dut.s_axi_awvalid.value = 1 # await regs.write("msk_top_regs", "PRBS_Control", data) - # if sim_time_d <= sim_start + 20000 and sim_time >= sim_start + 20000: - # data = await regs.read("msk_top_regs", "PRBS_Control") - # data = data ^ 0x8 - # dut.s_axi_wvalid.value = 1 - # dut.s_axi_awvalid.value = 1 - # await regs.write("msk_top_regs", "PRBS_Control", data) + # if sim_time_d <= sim_start + 30000 and sim_time >= sim_start + 30000: + # data = await regs.tx_async_fifo_rd_wr_ptr.read() + # print("Tx FIFO Pointers", hex(data)) + # data = await regs.rx_async_fifo_rd_wr_ptr.read() + # print("Rx FIFO Pointers", hex(data)) if sim_time_d <= sim_start + 20000 and sim_time >= sim_start + 20000: - data = await regs.read("msk_top_regs", "PRBS_Control") + data = await regs.PRBS_Control.read() data = data | 0x2 dut.s_axi_wvalid.value = 1 dut.s_axi_awvalid.value = 1 - await regs.write("msk_top_regs", "PRBS_Control", data) + await regs.PRBS_Control.write(data) # if sim_time_d <= sim_start + 3000 and sim_time >= sim_start + 3000: # await pn.resync() @@ -885,14 +828,30 @@ async def msk_test_1(dut): sim_time_d = sim_time sim_time = get_sim_time("us") - data = await regs.read("msk_top_regs", "f1_nco_adjust") + await regs.f1_nco_adjust.write(0) + data = await regs.f1_nco_adjust.read() print("F1 NCO Adjust: ", hex(data)) - data = await regs.read("msk_top_regs", "f2_nco_adjust") + await regs.f2_nco_adjust.write(0) + data = await regs.f2_nco_adjust.read() print("F2 NCO Adjust: ", hex(data)) - data = await regs.read("msk_top_regs", "f1_error") + await regs.f1_error.write(0) + data = await regs.f1_error.read() print("F1 Error: ", hex(data)) - data = await regs.read("msk_top_regs", "f2_error") + await regs.f2_error.write(0) + data = await regs.f2_error.read() print("F2 Error: ", hex(data)) + await regs.tx_async_fifo_rd_wr_ptr.write(0) + data = await regs.tx_async_fifo_rd_wr_ptr.read() + print("Tx FIFO Pointers", hex(data)) + await regs.rx_async_fifo_rd_wr_ptr.write(0) + data = await regs.rx_async_fifo_rd_wr_ptr.read() + print("Rx FIFO Pointers", hex(data)) + await regs.rx_power.write(0) + data = await regs.rx_power.read() + print("Rx Power", hex(data)) + await regs.rx_frame_sync_status.write(0xFFFF_0000) + data = await regs.rx_frame_sync_status.read() + print("Frame Sync Status", hex(data)) #data = await regs.read("msk_top_regs", "LPF_Accum_F1") # print("F1 Acc: ", hex(data)) # data = await regs.read("msk_top_regs", "LPF_Accum_F2") @@ -929,9 +888,9 @@ async def msk_test_1(dut): # print("Ones: ", pn.ones_count) # print("Zeros: ", pn.zeros_count) - errs = await regs.read("msk_top_regs", "PRBS_Error_Count") + errs = await regs.PRBS_Error_Count.read() print("Bit errors: ", errs) - bits = await regs.read("msk_top_regs", "PRBS_Bit_Count") + bits = await regs.PRBS_Bit_Count.read() print("Bit count: ", bits) print("BER: ", (1.0*errs)/bits) diff --git a/sim/msk_top_nvc.gtkw b/sim/msk_top_nvc.gtkw index b0ef9ee..4c86d96 100644 --- a/sim/msk_top_nvc.gtkw +++ b/sim/msk_top_nvc.gtkw @@ -1,15 +1,15 @@ [*] [*] GTKWave Analyzer v3.4.0 (w)1999-2022 BSI -[*] Fri Oct 10 05:31:31 2025 +[*] Sun Oct 26 04:27:27 2025 [*] [dumpfile] "/Users/nonlinear/dev/pluto_msk/sim/msk_top.ghw" -[dumpfile_mtime] "Fri Oct 10 05:30:38 2025" -[dumpfile_size] 217869621 +[dumpfile_mtime] "Sun Oct 26 04:27:24 2025" +[dumpfile_size] 1112248 [savefile] "/Users/nonlinear/dev/pluto_msk/sim/msk_top_nvc.gtkw" [timestart] 0 [size] 1504 828 [pos] -1 -1 -*-42.987041 3950520428800 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +*-33.240414 190000000 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 [markername] AA [markername] BB [markername] CC @@ -42,6 +42,8 @@ [treeopen] msk_top.u_dem.u_f2. [treeopen] msk_top.u_mod. [treeopen] msk_top.u_msk_top_csr. +[treeopen] msk_top.u_msk_top_csr.u_msk_regs. +[treeopen] msk_top.u_msk_top_csr.u_msk_regs.field_storage.fb_freqword. [sst_width] 298 [signals_width] 383 [sst_expanded] 1 @@ -69,6 +71,9 @@ msk_top.u_mod.tx_sync_force @22 msk_top.u_mod.sync_counter[23:0] msk_top.u_mod.sync_counter_next[23:0] +msk_top.u_mod.freq_word_f1[31:0] +msk_top.u_mod.freq_word_f2[31:0] +msk_top.u_mod.freq_word_tclk[31:0] @200 - @22 @@ -366,7 +371,7 @@ msk_top.u_dem.rx_data -Differential Coder Loopback @c00200 -PRBS Generator -@29 +@28 msk_top.u_prbs_gen.clk msk_top.u_prbs_gen.data_in[0] msk_top.u_prbs_gen.data_out[0] @@ -375,11 +380,11 @@ msk_top.u_prbs_gen.error_arm msk_top.u_prbs_gen.error_insert msk_top.u_prbs_gen.error_insert_d msk_top.u_prbs_gen.init -@23 +@22 msk_top.u_prbs_gen.initial_state[30:0] msk_top.u_prbs_gen.lfsr[30:0] msk_top.u_prbs_gen.polynomial[30:0] -@29 +@28 msk_top.u_prbs_gen.prbs_sel @1401200 -PRBS Generator @@ -416,5 +421,605 @@ msk_top.u_prbs_mon.sync_now msk_top.u_prbs_mon.sync_threshold[15:0] @1000200 -PRBS Monitor +@28 +msk_top.u_msk_top_csr.clear_counts +msk_top.u_msk_top_csr.clk +msk_top.u_msk_top_csr.demod_sync_lock +msk_top.u_msk_top_csr.diff_encdec_lbk_ena +@22 +msk_top.u_msk_top_csr.discard_rxnco[7:0] +msk_top.u_msk_top_csr.discard_rxsamples[7:0] +msk_top.u_msk_top_csr.f1_error[31:0] +msk_top.u_msk_top_csr.f1_nco_adjust[31:0] +msk_top.u_msk_top_csr.f2_error[31:0] +msk_top.u_msk_top_csr.f2_nco_adjust[31:0] +msk_top.u_msk_top_csr.freq_word_ft[31:0] +msk_top.u_msk_top_csr.freq_word_rx_f1[31:0] +msk_top.u_msk_top_csr.freq_word_rx_f2[31:0] +msk_top.u_msk_top_csr.freq_word_tx_f1[31:0] +msk_top.u_msk_top_csr.freq_word_tx_f2[31:0] +msk_top.u_msk_top_csr.hwif_in.axis_xfer_count.xfer_count.next_q[31:0] +msk_top.u_msk_top_csr.hwif_in.f1_error.data.next_q[31:0] +msk_top.u_msk_top_csr.hwif_in.f1_nco_adjust.data.next_q[31:0] +msk_top.u_msk_top_csr.hwif_in.f2_error.data.next_q[31:0] +msk_top.u_msk_top_csr.hwif_in.f2_nco_adjust.data.next_q[31:0] +msk_top.u_msk_top_csr.hwif_in.lpf_accum_f1.status_data.next_q[31:0] +msk_top.u_msk_top_csr.hwif_in.lpf_accum_f2.status_data.next_q[31:0] +@28 +msk_top.u_msk_top_csr.hwif_in.msk_status.demod_sync_lock.next_q +msk_top.u_msk_top_csr.hwif_in.msk_status.rx_enable.next_q +msk_top.u_msk_top_csr.hwif_in.msk_status.tx_axis_valid.next_q +msk_top.u_msk_top_csr.hwif_in.msk_status.tx_enable.next_q +@22 +msk_top.u_msk_top_csr.hwif_in.prbs_bit_count.status_data.next_q[31:0] +msk_top.u_msk_top_csr.hwif_in.prbs_error_count.status_data.next_q[31:0] +msk_top.u_msk_top_csr.hwif_in.rx_power.rx_power.next_q[22:0] +msk_top.u_msk_top_csr.hwif_in.tx_enable_count.tx_ena_counter.next_q[31:0] +msk_top.u_msk_top_csr.hwif_out.fb_freqword.config_data.value[31:0] +msk_top.u_msk_top_csr.hwif_out.lowpass_ema_alpha1.alpha.value[17:0] +msk_top.u_msk_top_csr.hwif_out.lowpass_ema_alpha2.alpha.value[17:0] +msk_top.u_msk_top_csr.hwif_out.lpf_config_0.lpf_alpha.value[23:0] +@28 +msk_top.u_msk_top_csr.hwif_out.lpf_config_0.lpf_freeze.value +msk_top.u_msk_top_csr.hwif_out.lpf_config_0.lpf_zero.value +@22 +msk_top.u_msk_top_csr.hwif_out.lpf_config_0.prbs_reserved.value[5:0] +msk_top.u_msk_top_csr.hwif_out.lpf_config_1.i_gain.value[23:0] +msk_top.u_msk_top_csr.hwif_out.lpf_config_1.i_shift.value[7:0] +msk_top.u_msk_top_csr.hwif_out.lpf_config_2.p_gain.value[23:0] +msk_top.u_msk_top_csr.hwif_out.lpf_config_2.p_shift.value[7:0] +@28 +msk_top.u_msk_top_csr.hwif_out.msk_control.clear_counts.value +msk_top.u_msk_top_csr.hwif_out.msk_control.diff_encoder_loopback.value +msk_top.u_msk_top_csr.hwif_out.msk_control.loopback_ena.value +msk_top.u_msk_top_csr.hwif_out.msk_control.ptt.value +msk_top.u_msk_top_csr.hwif_out.msk_control.rx_invert.value +msk_top.u_msk_top_csr.hwif_out.msk_init.rxinit.value +msk_top.u_msk_top_csr.hwif_out.msk_init.txinit.value +msk_top.u_msk_top_csr.hwif_out.msk_init.txrxinit.value +msk_top.u_msk_top_csr.hwif_out.prbs_control.prbs_clear.value +msk_top.u_msk_top_csr.hwif_out.prbs_control.prbs_error_insert.value +msk_top.u_msk_top_csr.hwif_out.prbs_control.prbs_manual_sync.value +@22 +msk_top.u_msk_top_csr.hwif_out.prbs_control.prbs_reserved.value[11:0] +@28 +msk_top.u_msk_top_csr.hwif_out.prbs_control.prbs_sel.value +@22 +msk_top.u_msk_top_csr.hwif_out.prbs_control.prbs_sync_threshold.value[15:0] +msk_top.u_msk_top_csr.hwif_out.prbs_error_mask.config_data.value[31:0] +msk_top.u_msk_top_csr.hwif_out.prbs_initial_state.config_data.value[31:0] +msk_top.u_msk_top_csr.hwif_out.prbs_polynomial.config_data.value[31:0] +msk_top.u_msk_top_csr.hwif_out.rx_data_width.data_width.value[7:0] +msk_top.u_msk_top_csr.hwif_out.rx_f1_freqword.config_data.value[31:0] +msk_top.u_msk_top_csr.hwif_out.rx_f2_freqword.config_data.value[31:0] +msk_top.u_msk_top_csr.hwif_out.rx_sample_discard.rx_nco_discard.value[7:0] +msk_top.u_msk_top_csr.hwif_out.rx_sample_discard.rx_sample_discard.value[7:0] +msk_top.u_msk_top_csr.hwif_out.tx_data_width.data_width.value[7:0] +msk_top.u_msk_top_csr.hwif_out.tx_f1_freqword.config_data.value[31:0] +msk_top.u_msk_top_csr.hwif_out.tx_f2_freqword.config_data.value[31:0] +msk_top.u_msk_top_csr.hwif_out.tx_sync_cnt.tx_sync_cnt.value[23:0] +@28 +msk_top.u_msk_top_csr.hwif_out.tx_sync_ctrl.tx_sync_ena.value +msk_top.u_msk_top_csr.hwif_out.tx_sync_ctrl.tx_sync_f1.value +msk_top.u_msk_top_csr.hwif_out.tx_sync_ctrl.tx_sync_f2.value +msk_top.u_msk_top_csr.hwif_out.tx_sync_ctrl.tx_sync_force.value +msk_top.u_msk_top_csr.loopback_ena +@22 +msk_top.u_msk_top_csr.lpf_accum_f1[31:0] +msk_top.u_msk_top_csr.lpf_accum_f2[31:0] +msk_top.u_msk_top_csr.lpf_alpha[23:0] +@28 +msk_top.u_msk_top_csr.lpf_freeze +@22 +msk_top.u_msk_top_csr.lpf_i_gain[23:0] +msk_top.u_msk_top_csr.lpf_i_shift[7:0] +msk_top.u_msk_top_csr.lpf_p_gain[23:0] +msk_top.u_msk_top_csr.lpf_p_shift[7:0] +@28 +msk_top.u_msk_top_csr.lpf_zero +@22 +msk_top.u_msk_top_csr.pd_alpha1[17:0] +msk_top.u_msk_top_csr.pd_alpha2[17:0] +msk_top.u_msk_top_csr.pd_power[22:0] +msk_top.u_msk_top_csr.prbs_bits[31:0] +@28 +msk_top.u_msk_top_csr.prbs_clear +msk_top.u_msk_top_csr.prbs_err_insert +@22 +msk_top.u_msk_top_csr.prbs_err_mask[31:0] +msk_top.u_msk_top_csr.prbs_errs[31:0] +msk_top.u_msk_top_csr.prbs_initial[31:0] +@28 +msk_top.u_msk_top_csr.prbs_manual_sync +@22 +msk_top.u_msk_top_csr.prbs_poly[31:0] +@28 +msk_top.u_msk_top_csr.prbs_sel +@22 +msk_top.u_msk_top_csr.prbs_sync_threshold[15:0] +@28 +msk_top.u_msk_top_csr.ptt +@22 +msk_top.u_msk_top_csr.rx_data_w[7:0] +@28 +msk_top.u_msk_top_csr.rx_enable +msk_top.u_msk_top_csr.rx_invert +msk_top.u_msk_top_csr.rxinit +msk_top.u_msk_top_csr.s_axi_aclk +@22 +msk_top.u_msk_top_csr.s_axi_araddr[31:0] +@28 +msk_top.u_msk_top_csr.s_axi_aresetn +msk_top.u_msk_top_csr.s_axi_arprot[2:0] +msk_top.u_msk_top_csr.s_axi_arready +msk_top.u_msk_top_csr.s_axi_arvalid +@22 +msk_top.u_msk_top_csr.s_axi_awaddr[31:0] +@28 +msk_top.u_msk_top_csr.s_axi_awprot[2:0] +msk_top.u_msk_top_csr.s_axi_awready +msk_top.u_msk_top_csr.s_axi_awvalid +msk_top.u_msk_top_csr.s_axi_bready +msk_top.u_msk_top_csr.s_axi_bresp[1:0] +msk_top.u_msk_top_csr.s_axi_bvalid +@22 +msk_top.u_msk_top_csr.s_axi_rdata[31:0] +@28 +msk_top.u_msk_top_csr.s_axi_rready +msk_top.u_msk_top_csr.s_axi_rresp[1:0] +msk_top.u_msk_top_csr.s_axi_rvalid +@22 +msk_top.u_msk_top_csr.s_axi_wdata[31:0] +@28 +msk_top.u_msk_top_csr.s_axi_wready +@22 +msk_top.u_msk_top_csr.s_axi_wstrb[3:0] +@28 +msk_top.u_msk_top_csr.s_axi_wvalid +@c00023 +msk_top.u_msk_top_csr.s_axil_i.araddr[7:0] +@28 +(0)msk_top.u_msk_top_csr.s_axil_i.araddr[7:0] +(1)msk_top.u_msk_top_csr.s_axil_i.araddr[7:0] +(2)msk_top.u_msk_top_csr.s_axil_i.araddr[7:0] +(3)msk_top.u_msk_top_csr.s_axil_i.araddr[7:0] +(4)msk_top.u_msk_top_csr.s_axil_i.araddr[7:0] +(5)msk_top.u_msk_top_csr.s_axil_i.araddr[7:0] +(6)msk_top.u_msk_top_csr.s_axil_i.araddr[7:0] +(7)msk_top.u_msk_top_csr.s_axil_i.araddr[7:0] +@1401201 +-group_end +@28 +msk_top.u_msk_top_csr.s_axil_i.arprot[2:0] +msk_top.u_msk_top_csr.s_axil_i.arvalid +@22 +msk_top.u_msk_top_csr.s_axil_i.awaddr[7:0] +@28 +msk_top.u_msk_top_csr.s_axil_i.awprot[2:0] +msk_top.u_msk_top_csr.s_axil_i.awvalid +msk_top.u_msk_top_csr.s_axil_i.bready +msk_top.u_msk_top_csr.s_axil_i.rready +@22 +msk_top.u_msk_top_csr.s_axil_i.wdata[31:0] +msk_top.u_msk_top_csr.s_axil_i.wstrb[3:0] +@28 +msk_top.u_msk_top_csr.s_axil_i.wvalid +msk_top.u_msk_top_csr.s_axil_o.arready +msk_top.u_msk_top_csr.u_msk_regs.decoded_reg_strb.tx_f1_freqword +msk_top.u_msk_top_csr.s_axil_o.awready +msk_top.u_msk_top_csr.s_axil_o.bresp[1:0] +msk_top.u_msk_top_csr.s_axil_o.bvalid +@22 +msk_top.u_msk_top_csr.s_axil_o.rdata[31:0] +@28 +msk_top.u_msk_top_csr.s_axil_o.rresp[1:0] +msk_top.u_msk_top_csr.s_axil_o.rvalid +msk_top.u_msk_top_csr.s_axil_o.wready +msk_top.u_msk_top_csr.tx_axis_valid +@22 +msk_top.u_msk_top_csr.tx_bit_counter[31:0] +msk_top.u_msk_top_csr.tx_data_w[7:0] +msk_top.u_msk_top_csr.tx_ena_counter[31:0] +@28 +msk_top.u_msk_top_csr.tx_enable +msk_top.u_msk_top_csr.tx_req +@22 +msk_top.u_msk_top_csr.tx_sync_cnt[23:0] +@28 +msk_top.u_msk_top_csr.tx_sync_ena +msk_top.u_msk_top_csr.tx_sync_f1 +msk_top.u_msk_top_csr.tx_sync_f2 +msk_top.u_msk_top_csr.tx_sync_force +msk_top.u_msk_top_csr.txinit +msk_top.u_msk_top_csr.txrxinit +msk_top.u_msk_top_csr.u01s.clk +msk_top.u_msk_top_csr.u01s.di +msk_top.u_msk_top_csr.u01s.di_s[0:1] +msk_top.u_msk_top_csr.u01s.do +msk_top.u_msk_top_csr.u02s.clk +msk_top.u_msk_top_csr.u02s.di_s[0:1] +msk_top.u_msk_top_csr.u02s.do +msk_top.u_msk_top_csr.u03s.clk +msk_top.u_msk_top_csr.u03s.di_s[0:1] +msk_top.u_msk_top_csr.u03s.do +msk_top.u_msk_top_csr.u04s.clk +msk_top.u_msk_top_csr.u04s.di +msk_top.u_msk_top_csr.u04s.di_s[0:1] +msk_top.u_msk_top_csr.u04s.do +msk_top.u_msk_top_csr.u05s.clk +msk_top.u_msk_top_csr.u05s.di +msk_top.u_msk_top_csr.u05s.di_s[0:1] +msk_top.u_msk_top_csr.u05s.do +msk_top.u_msk_top_csr.u06s.clk +msk_top.u_msk_top_csr.u06s.di +msk_top.u_msk_top_csr.u06s.di_s[0:1] +msk_top.u_msk_top_csr.u06s.do +msk_top.u_msk_top_csr.u07s.clk +msk_top.u_msk_top_csr.u07s.di +msk_top.u_msk_top_csr.u07s.di_s[0:1] +msk_top.u_msk_top_csr.u07s.do +msk_top.u_msk_top_csr.u08s.clk +msk_top.u_msk_top_csr.u08s.di +msk_top.u_msk_top_csr.u08s.di_s[0:1] +msk_top.u_msk_top_csr.u08s.do +msk_top.u_msk_top_csr.u09s.clk +msk_top.u_msk_top_csr.u09s.di +msk_top.u_msk_top_csr.u09s.di_s[0:1] +msk_top.u_msk_top_csr.u09s.do +msk_top.u_msk_top_csr.u10s.clk +msk_top.u_msk_top_csr.u10s.di +msk_top.u_msk_top_csr.u10s.di_s[0:1] +msk_top.u_msk_top_csr.u10s.do +msk_top.u_msk_top_csr.u11s.clk +msk_top.u_msk_top_csr.u11s.di +msk_top.u_msk_top_csr.u11s.di_s[0:1] +msk_top.u_msk_top_csr.u11s.do +msk_top.u_msk_top_csr.u12s.clk +msk_top.u_msk_top_csr.u12s.di +msk_top.u_msk_top_csr.u12s.di_s[0:1] +msk_top.u_msk_top_csr.u12s.do +msk_top.u_msk_top_csr.u13s.clk +msk_top.u_msk_top_csr.u13s.di +msk_top.u_msk_top_csr.u13s.di_s[0:1] +msk_top.u_msk_top_csr.u13s.do +msk_top.u_msk_top_csr.u14s.clk +msk_top.u_msk_top_csr.u14s.di +msk_top.u_msk_top_csr.u14s.di_s[0:1] +msk_top.u_msk_top_csr.u14s.do +msk_top.u_msk_top_csr.u15s.clk +msk_top.u_msk_top_csr.u15s.di +msk_top.u_msk_top_csr.u15s.di_s[0:1] +msk_top.u_msk_top_csr.u15s.do +msk_top.u_msk_top_csr.u16s.clk +msk_top.u_msk_top_csr.u16s.di +msk_top.u_msk_top_csr.u16s.di_s[0:1] +msk_top.u_msk_top_csr.u16s.do +msk_top.u_msk_top_csr.u_msk_regs.axil_ar_accept +@22 +msk_top.u_msk_top_csr.u_msk_regs.axil_araddr[7:0] +msk_top.u_msk_top_csr.s_axil_i.araddr[7:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.axil_arvalid +msk_top.u_msk_top_csr.u_msk_regs.axil_aw_accept +@22 +msk_top.u_msk_top_csr.u_msk_regs.axil_awaddr[7:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.axil_awvalid +msk_top.u_msk_top_csr.u_msk_regs.axil_n_in_flight[1:0] +msk_top.u_msk_top_csr.u_msk_regs.axil_prev_was_rd +msk_top.u_msk_top_csr.u_msk_regs.axil_resp_acked +msk_top.u_msk_top_csr.u_msk_regs.axil_resp_rptr[1:0] +msk_top.u_msk_top_csr.u_msk_regs.axil_resp_wptr[1:0] +@22 +msk_top.u_msk_top_csr.u_msk_regs.axil_wdata[31:0] +msk_top.u_msk_top_csr.u_msk_regs.axil_wstrb[3:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.axil_wvalid +msk_top.u_msk_top_csr.u_msk_regs.clk +@22 +msk_top.u_msk_top_csr.u_msk_regs.cpuif_addr[7:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.cpuif_rd_ack +@22 +msk_top.u_msk_top_csr.u_msk_regs.cpuif_rd_data[31:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.cpuif_rd_err +msk_top.u_msk_top_csr.u_msk_regs.cpuif_req +msk_top.u_msk_top_csr.u_msk_regs.cpuif_req_is_wr +msk_top.u_msk_top_csr.u_msk_regs.cpuif_req_masked +msk_top.u_msk_top_csr.u_msk_regs.cpuif_req_stall_rd +msk_top.u_msk_top_csr.u_msk_regs.cpuif_req_stall_wr +msk_top.u_msk_top_csr.u_msk_regs.cpuif_wr_ack +@22 +msk_top.u_msk_top_csr.u_msk_regs.cpuif_wr_biten[31:0] +msk_top.u_msk_top_csr.u_msk_regs.cpuif_wr_data[31:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.cpuif_wr_err +msk_top.u_msk_top_csr.u_msk_regs.decoded_reg_strb.axis_xfer_count +msk_top.u_msk_top_csr.u_msk_regs.decoded_reg_strb.f1_error +msk_top.u_msk_top_csr.u_msk_regs.decoded_reg_strb.f1_nco_adjust +msk_top.u_msk_top_csr.u_msk_regs.decoded_reg_strb.f2_error +msk_top.u_msk_top_csr.u_msk_regs.decoded_reg_strb.f2_nco_adjust +msk_top.u_msk_top_csr.u_msk_regs.decoded_reg_strb.fb_freqword +msk_top.u_msk_top_csr.u_msk_regs.decoded_reg_strb.hash_id_high +msk_top.u_msk_top_csr.u_msk_regs.decoded_reg_strb.hash_id_low +msk_top.u_msk_top_csr.u_msk_regs.decoded_reg_strb.lowpass_ema_alpha1 +msk_top.u_msk_top_csr.u_msk_regs.decoded_reg_strb.lowpass_ema_alpha2 +msk_top.u_msk_top_csr.u_msk_regs.decoded_reg_strb.lpf_accum_f1 +msk_top.u_msk_top_csr.u_msk_regs.decoded_reg_strb.lpf_accum_f2 +msk_top.u_msk_top_csr.u_msk_regs.decoded_reg_strb.lpf_config_0 +msk_top.u_msk_top_csr.u_msk_regs.decoded_reg_strb.lpf_config_1 +msk_top.u_msk_top_csr.u_msk_regs.decoded_reg_strb.lpf_config_2 +msk_top.u_msk_top_csr.u_msk_regs.decoded_reg_strb.msk_control +msk_top.u_msk_top_csr.u_msk_regs.decoded_reg_strb.msk_init +msk_top.u_msk_top_csr.u_msk_regs.decoded_reg_strb.msk_status +msk_top.u_msk_top_csr.u_msk_regs.decoded_reg_strb.prbs_bit_count +msk_top.u_msk_top_csr.u_msk_regs.decoded_reg_strb.prbs_control +msk_top.u_msk_top_csr.u_msk_regs.decoded_reg_strb.prbs_error_count +msk_top.u_msk_top_csr.u_msk_regs.decoded_reg_strb.prbs_error_mask +msk_top.u_msk_top_csr.u_msk_regs.decoded_reg_strb.prbs_initial_state +msk_top.u_msk_top_csr.u_msk_regs.decoded_reg_strb.prbs_polynomial +msk_top.u_msk_top_csr.u_msk_regs.decoded_reg_strb.rx_data_width +msk_top.u_msk_top_csr.u_msk_regs.decoded_reg_strb.rx_f1_freqword +msk_top.u_msk_top_csr.u_msk_regs.decoded_reg_strb.rx_f2_freqword +msk_top.u_msk_top_csr.u_msk_regs.decoded_reg_strb.rx_power +msk_top.u_msk_top_csr.u_msk_regs.decoded_reg_strb.rx_sample_discard +msk_top.u_msk_top_csr.u_msk_regs.decoded_reg_strb.tx_bit_count +msk_top.u_msk_top_csr.u_msk_regs.decoded_reg_strb.tx_data_width +msk_top.u_msk_top_csr.u_msk_regs.decoded_reg_strb.tx_enable_count +msk_top.u_msk_top_csr.u_msk_regs.decoded_reg_strb.tx_f1_freqword +msk_top.u_msk_top_csr.u_msk_regs.decoded_reg_strb.tx_f2_freqword +msk_top.u_msk_top_csr.u_msk_regs.decoded_reg_strb.tx_sync_cnt +msk_top.u_msk_top_csr.u_msk_regs.decoded_reg_strb.tx_sync_ctrl +msk_top.u_msk_top_csr.u_msk_regs.decoded_req +msk_top.u_msk_top_csr.u_msk_regs.decoded_req_is_wr +@22 +msk_top.u_msk_top_csr.u_msk_regs.decoded_wr_biten[31:0] +msk_top.u_msk_top_csr.u_msk_regs.decoded_wr_data[31:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.fb_freqword.config_data.load_next +@22 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.fb_freqword.config_data.next_q[31:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.lowpass_ema_alpha1.alpha.load_next +@22 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.lowpass_ema_alpha1.alpha.next_q[17:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.lowpass_ema_alpha2.alpha.load_next +@22 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.lowpass_ema_alpha2.alpha.next_q[17:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.lpf_config_0.lpf_alpha.load_next +@22 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.lpf_config_0.lpf_alpha.next_q[23:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.lpf_config_0.lpf_freeze.load_next +msk_top.u_msk_top_csr.u_msk_regs.field_combo.lpf_config_0.lpf_freeze.next_q +msk_top.u_msk_top_csr.u_msk_regs.field_combo.lpf_config_0.lpf_zero.load_next +msk_top.u_msk_top_csr.u_msk_regs.field_combo.lpf_config_0.lpf_zero.next_q +msk_top.u_msk_top_csr.u_msk_regs.field_combo.lpf_config_0.prbs_reserved.load_next +@22 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.lpf_config_0.prbs_reserved.next_q[5:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.lpf_config_1.i_gain.load_next +@22 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.lpf_config_1.i_gain.next_q[23:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.lpf_config_1.i_shift.load_next +@22 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.lpf_config_1.i_shift.next_q[7:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.lpf_config_2.p_gain.load_next +@22 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.lpf_config_2.p_gain.next_q[23:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.lpf_config_2.p_shift.load_next +@22 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.lpf_config_2.p_shift.next_q[7:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.msk_control.clear_counts.load_next +msk_top.u_msk_top_csr.u_msk_regs.field_combo.msk_control.clear_counts.next_q +msk_top.u_msk_top_csr.u_msk_regs.field_combo.msk_control.diff_encoder_loopback.load_next +msk_top.u_msk_top_csr.u_msk_regs.field_combo.msk_control.diff_encoder_loopback.next_q +msk_top.u_msk_top_csr.u_msk_regs.field_combo.msk_control.loopback_ena.load_next +msk_top.u_msk_top_csr.u_msk_regs.field_combo.msk_control.loopback_ena.next_q +msk_top.u_msk_top_csr.u_msk_regs.field_combo.msk_control.ptt.load_next +msk_top.u_msk_top_csr.u_msk_regs.field_combo.msk_control.ptt.next_q +msk_top.u_msk_top_csr.u_msk_regs.field_combo.msk_control.rx_invert.load_next +msk_top.u_msk_top_csr.u_msk_regs.field_combo.msk_control.rx_invert.next_q +msk_top.u_msk_top_csr.u_msk_regs.field_combo.msk_init.rxinit.load_next +msk_top.u_msk_top_csr.u_msk_regs.field_combo.msk_init.rxinit.next_q +msk_top.u_msk_top_csr.u_msk_regs.field_combo.msk_init.txinit.load_next +msk_top.u_msk_top_csr.u_msk_regs.field_combo.msk_init.txinit.next_q +msk_top.u_msk_top_csr.u_msk_regs.field_combo.msk_init.txrxinit.load_next +msk_top.u_msk_top_csr.u_msk_regs.field_combo.msk_init.txrxinit.next_q +msk_top.u_msk_top_csr.u_msk_regs.field_combo.prbs_control.prbs_clear.load_next +msk_top.u_msk_top_csr.u_msk_regs.field_combo.prbs_control.prbs_clear.next_q +msk_top.u_msk_top_csr.u_msk_regs.field_combo.prbs_control.prbs_error_insert.load_next +msk_top.u_msk_top_csr.u_msk_regs.field_combo.prbs_control.prbs_error_insert.next_q +msk_top.u_msk_top_csr.u_msk_regs.field_combo.prbs_control.prbs_manual_sync.load_next +msk_top.u_msk_top_csr.u_msk_regs.field_combo.prbs_control.prbs_manual_sync.next_q +msk_top.u_msk_top_csr.u_msk_regs.field_combo.prbs_control.prbs_reserved.load_next +@22 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.prbs_control.prbs_reserved.next_q[11:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.prbs_control.prbs_sel.load_next +msk_top.u_msk_top_csr.u_msk_regs.field_combo.prbs_control.prbs_sel.next_q +msk_top.u_msk_top_csr.u_msk_regs.field_combo.prbs_control.prbs_sync_threshold.load_next +@22 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.prbs_control.prbs_sync_threshold.next_q[15:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.prbs_error_mask.config_data.load_next +@22 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.prbs_error_mask.config_data.next_q[31:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.prbs_initial_state.config_data.load_next +@22 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.prbs_initial_state.config_data.next_q[31:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.prbs_polynomial.config_data.load_next +@22 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.prbs_polynomial.config_data.next_q[31:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.rx_data_width.data_width.load_next +@22 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.rx_data_width.data_width.next_q[7:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.rx_f1_freqword.config_data.load_next +@22 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.rx_f1_freqword.config_data.next_q[31:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.rx_f2_freqword.config_data.load_next +@22 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.rx_f2_freqword.config_data.next_q[31:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.rx_sample_discard.rx_nco_discard.load_next +@22 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.rx_sample_discard.rx_nco_discard.next_q[7:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.rx_sample_discard.rx_sample_discard.load_next +@22 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.rx_sample_discard.rx_sample_discard.next_q[7:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.tx_data_width.data_width.load_next +@22 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.tx_data_width.data_width.next_q[7:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.tx_f1_freqword.config_data.load_next +@22 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.tx_f1_freqword.config_data.next_q[31:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.tx_f2_freqword.config_data.load_next +@22 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.tx_f2_freqword.config_data.next_q[31:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.tx_sync_cnt.tx_sync_cnt.load_next +@22 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.tx_sync_cnt.tx_sync_cnt.next_q[23:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.field_combo.tx_sync_ctrl.tx_sync_ena.load_next +msk_top.u_msk_top_csr.u_msk_regs.field_combo.tx_sync_ctrl.tx_sync_ena.next_q +msk_top.u_msk_top_csr.u_msk_regs.field_combo.tx_sync_ctrl.tx_sync_f1.load_next +msk_top.u_msk_top_csr.u_msk_regs.field_combo.tx_sync_ctrl.tx_sync_f1.next_q +msk_top.u_msk_top_csr.u_msk_regs.field_combo.tx_sync_ctrl.tx_sync_f2.load_next +msk_top.u_msk_top_csr.u_msk_regs.field_combo.tx_sync_ctrl.tx_sync_f2.next_q +msk_top.u_msk_top_csr.u_msk_regs.field_combo.tx_sync_ctrl.tx_sync_force.load_next +msk_top.u_msk_top_csr.u_msk_regs.field_combo.tx_sync_ctrl.tx_sync_force.next_q +@22 +msk_top.u_msk_top_csr.u_msk_regs.field_storage.fb_freqword.config_data.value[31:0] +msk_top.u_msk_top_csr.u_msk_regs.field_storage.lowpass_ema_alpha1.alpha.value[17:0] +msk_top.u_msk_top_csr.u_msk_regs.field_storage.lowpass_ema_alpha2.alpha.value[17:0] +msk_top.u_msk_top_csr.u_msk_regs.field_storage.lpf_config_0.lpf_alpha.value[23:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.field_storage.lpf_config_0.lpf_freeze.value +msk_top.u_msk_top_csr.u_msk_regs.field_storage.lpf_config_0.lpf_zero.value +@22 +msk_top.u_msk_top_csr.u_msk_regs.field_storage.lpf_config_0.prbs_reserved.value[5:0] +msk_top.u_msk_top_csr.u_msk_regs.field_storage.lpf_config_1.i_gain.value[23:0] +msk_top.u_msk_top_csr.u_msk_regs.field_storage.lpf_config_1.i_shift.value[7:0] +msk_top.u_msk_top_csr.u_msk_regs.field_storage.lpf_config_2.p_gain.value[23:0] +msk_top.u_msk_top_csr.u_msk_regs.field_storage.lpf_config_2.p_shift.value[7:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.field_storage.msk_control.clear_counts.value +msk_top.u_msk_top_csr.u_msk_regs.field_storage.msk_control.diff_encoder_loopback.value +msk_top.u_msk_top_csr.u_msk_regs.field_storage.msk_control.loopback_ena.value +msk_top.u_msk_top_csr.u_msk_regs.field_storage.msk_control.ptt.value +msk_top.u_msk_top_csr.u_msk_regs.field_storage.msk_control.rx_invert.value +msk_top.u_msk_top_csr.u_msk_regs.field_storage.msk_init.rxinit.value +msk_top.u_msk_top_csr.u_msk_regs.field_storage.msk_init.txinit.value +msk_top.u_msk_top_csr.u_msk_regs.field_storage.msk_init.txrxinit.value +msk_top.u_msk_top_csr.u_msk_regs.field_storage.prbs_control.prbs_clear.value +msk_top.u_msk_top_csr.u_msk_regs.field_storage.prbs_control.prbs_error_insert.value +msk_top.u_msk_top_csr.u_msk_regs.field_storage.prbs_control.prbs_manual_sync.value +@22 +msk_top.u_msk_top_csr.u_msk_regs.field_storage.prbs_control.prbs_reserved.value[11:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.field_storage.prbs_control.prbs_sel.value +@22 +msk_top.u_msk_top_csr.u_msk_regs.field_storage.prbs_control.prbs_sync_threshold.value[15:0] +msk_top.u_msk_top_csr.u_msk_regs.field_storage.prbs_error_mask.config_data.value[31:0] +msk_top.u_msk_top_csr.u_msk_regs.field_storage.prbs_initial_state.config_data.value[31:0] +msk_top.u_msk_top_csr.u_msk_regs.field_storage.prbs_polynomial.config_data.value[31:0] +msk_top.u_msk_top_csr.u_msk_regs.field_storage.rx_data_width.data_width.value[7:0] +msk_top.u_msk_top_csr.u_msk_regs.field_storage.rx_f1_freqword.config_data.value[31:0] +msk_top.u_msk_top_csr.u_msk_regs.field_storage.rx_f2_freqword.config_data.value[31:0] +msk_top.u_msk_top_csr.u_msk_regs.field_storage.rx_sample_discard.rx_nco_discard.value[7:0] +msk_top.u_msk_top_csr.u_msk_regs.field_storage.rx_sample_discard.rx_sample_discard.value[7:0] +msk_top.u_msk_top_csr.u_msk_regs.field_storage.tx_data_width.data_width.value[7:0] +msk_top.u_msk_top_csr.u_msk_regs.field_storage.tx_f1_freqword.config_data.value[31:0] +msk_top.u_msk_top_csr.u_msk_regs.field_storage.tx_f2_freqword.config_data.value[31:0] +msk_top.u_msk_top_csr.u_msk_regs.field_storage.tx_sync_cnt.tx_sync_cnt.value[23:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.field_storage.tx_sync_ctrl.tx_sync_ena.value +msk_top.u_msk_top_csr.u_msk_regs.field_storage.tx_sync_ctrl.tx_sync_f1.value +msk_top.u_msk_top_csr.u_msk_regs.field_storage.tx_sync_ctrl.tx_sync_f2.value +msk_top.u_msk_top_csr.u_msk_regs.field_storage.tx_sync_ctrl.tx_sync_force.value +@22 +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.fb_freqword.config_data.value[31:0] +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.lowpass_ema_alpha1.alpha.value[17:0] +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.lowpass_ema_alpha2.alpha.value[17:0] +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.lpf_config_0.lpf_alpha.value[23:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.lpf_config_0.lpf_freeze.value +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.lpf_config_0.lpf_zero.value +@22 +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.lpf_config_0.prbs_reserved.value[5:0] +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.lpf_config_1.i_gain.value[23:0] +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.lpf_config_1.i_shift.value[7:0] +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.lpf_config_2.p_gain.value[23:0] +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.lpf_config_2.p_shift.value[7:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.msk_control.clear_counts.value +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.msk_control.diff_encoder_loopback.value +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.msk_control.loopback_ena.value +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.msk_control.ptt.value +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.msk_control.rx_invert.value +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.msk_init.rxinit.value +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.msk_init.txinit.value +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.msk_init.txrxinit.value +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.prbs_control.prbs_clear.value +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.prbs_control.prbs_error_insert.value +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.prbs_control.prbs_manual_sync.value +@22 +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.prbs_control.prbs_reserved.value[11:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.prbs_control.prbs_sel.value +@22 +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.prbs_control.prbs_sync_threshold.value[15:0] +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.prbs_error_mask.config_data.value[31:0] +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.prbs_initial_state.config_data.value[31:0] +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.prbs_polynomial.config_data.value[31:0] +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.rx_data_width.data_width.value[7:0] +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.rx_f1_freqword.config_data.value[31:0] +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.rx_f2_freqword.config_data.value[31:0] +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.rx_sample_discard.rx_nco_discard.value[7:0] +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.rx_sample_discard.rx_sample_discard.value[7:0] +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.tx_data_width.data_width.value[7:0] +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.tx_f1_freqword.config_data.value[31:0] +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.tx_f2_freqword.config_data.value[31:0] +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.tx_sync_cnt.tx_sync_cnt.value[23:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.tx_sync_ctrl.tx_sync_ena.value +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.tx_sync_ctrl.tx_sync_f1.value +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.tx_sync_ctrl.tx_sync_f2.value +msk_top.u_msk_top_csr.u_msk_regs.hwif_out.tx_sync_ctrl.tx_sync_force.value +@22 +msk_top.u_msk_top_csr.u_msk_regs.readback_data[31:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.readback_done +msk_top.u_msk_top_csr.u_msk_regs.readback_err +msk_top.u_msk_top_csr.u_msk_regs.rst +msk_top.u_msk_top_csr.u_msk_regs.s_axil_o.arready +msk_top.u_msk_top_csr.u_msk_regs.s_axil_o.awready +msk_top.u_msk_top_csr.u_msk_regs.s_axil_o.bresp[1:0] +msk_top.u_msk_top_csr.u_msk_regs.s_axil_o.bvalid +@22 +msk_top.u_msk_top_csr.u_msk_regs.s_axil_o.rdata[31:0] +@28 +msk_top.u_msk_top_csr.u_msk_regs.s_axil_o.rresp[1:0] +msk_top.u_msk_top_csr.u_msk_regs.s_axil_o.rvalid +msk_top.u_msk_top_csr.u_msk_regs.s_axil_o.wready +@22 +msk_top.u_msk_top_csr.xfer_count[31:0] [pattern_trace] 1 [pattern_trace] 0 diff --git a/sim/msk_top_regs b/sim/msk_top_regs new file mode 120000 index 0000000..43bc91d --- /dev/null +++ b/sim/msk_top_regs @@ -0,0 +1 @@ +../rdl/outputs/python/msk_top_regs \ No newline at end of file diff --git a/src/axis_async_fifo.vhd b/src/axis_async_fifo.vhd index 5079ebf..8cb417c 100644 --- a/src/axis_async_fifo.vhd +++ b/src/axis_async_fifo.vhd @@ -1,8 +1,19 @@ ------------------------------------------------------------------------------------------------------ --- AXIS-Compliant Asynchronous FIFO - SYNC LAG FIX +-- AXIS-Compliant Asynchronous FIFO ------------------------------------------------------------------------------------------------------ --- FIX: Added safety margin to empty detection to account for 2-cycle synchronization lag --- This prevents reading past actual data and hitting stale tlast markers +-- FIX v4: Pipelined Gray-to-binary conversion for 245 MHz timing closure +-- +-- Change: wr_ptr_bin_sync is now a registered signal instead of a combinational variable. +-- This adds one cycle of latency on empty detection, which is safe because: +-- 1. The write pointer is already 2+ cycles stale from the CDC synchronizer +-- 2. One extra cycle of "false not-empty" just means we check again next cycle +-- 3. The FIFO depth provides margin for this additional latency +------------------------------------------------------------------------------------------------------ +-- Previous versions: +-- FIX v3: Proper three-state handling +-- State A: Becoming valid (empty→non-empty): Present first byte, assert tvalid +-- State B: Handshake completes (tvalid='1', tready='1'): Advance pointer, present next byte +-- State C: Valid but not consumed (tvalid='1', tready='0'): HOLD STABLE ------------------------------------------------------------------------------------------------------ LIBRARY ieee; @@ -37,7 +48,15 @@ ENTITY axis_async_fifo IS -- Status signals prog_full : OUT std_logic; - prog_empty : OUT std_logic + prog_empty : OUT std_logic; + status_aclk : IN std_logic; + status_aresetn : IN std_logic; + status_req : IN std_logic; + status_ack : OUT std_logic; + fifo_overflow : OUT std_logic; + fifo_underflow : OUT std_logic; + fifo_wr_ptr : OUT std_logic_vector(ADDR_WIDTH DOWNTO 0); + fifo_rd_ptr : OUT std_logic_vector(ADDR_WIDTH DOWNTO 0) ); END ENTITY axis_async_fifo; @@ -45,6 +64,10 @@ ARCHITECTURE rtl OF axis_async_fifo IS CONSTANT DEPTH : NATURAL := 2**ADDR_WIDTH; + -- Frame-aware programmable full threshold + CONSTANT FRAME_SIZE : NATURAL := 134; -- OV frame payload size (bytes) + CONSTANT ALERT_THRESHOLD : NATURAL := DEPTH MOD FRAME_SIZE; + -- Separate arrays for Block RAM inference TYPE ram_data_type IS ARRAY (0 TO DEPTH-1) OF std_logic_vector(DATA_WIDTH-1 DOWNTO 0); TYPE ram_last_type IS ARRAY (0 TO DEPTH-1) OF std_logic; @@ -52,30 +75,49 @@ ARCHITECTURE rtl OF axis_async_fifo IS SIGNAL ram_data : ram_data_type; SIGNAL ram_last : ram_last_type; - ATTRIBUTE ram_style : STRING; - ATTRIBUTE ram_style OF ram_data : SIGNAL IS "block"; - ATTRIBUTE ram_style OF ram_last : SIGNAL IS "block"; + -- Gray code pointers (reset-initialized in respective clock domains) + SIGNAL wr_ptr_gray : std_logic_vector(ADDR_WIDTH DOWNTO 0); + SIGNAL wr_ptr_bin : std_logic_vector(ADDR_WIDTH DOWNTO 0); + SIGNAL rd_ptr_gray : std_logic_vector(ADDR_WIDTH DOWNTO 0); + SIGNAL rd_ptr_bin : std_logic_vector(ADDR_WIDTH DOWNTO 0); - -- Gray code pointers - SIGNAL wr_ptr_gray : std_logic_vector(ADDR_WIDTH DOWNTO 0) := (OTHERS => '0'); - SIGNAL wr_ptr_bin : std_logic_vector(ADDR_WIDTH DOWNTO 0) := (OTHERS => '0'); - SIGNAL rd_ptr_gray : std_logic_vector(ADDR_WIDTH DOWNTO 0) := (OTHERS => '0'); - SIGNAL rd_ptr_bin : std_logic_vector(ADDR_WIDTH DOWNTO 0) := (OTHERS => '0'); + -- CDC Synchronizers (intentionally not reset - avoids cross-domain reset timing issues) + SIGNAL wr_ptr_gray_sync1 : std_logic_vector(ADDR_WIDTH DOWNTO 0); + SIGNAL wr_ptr_gray_sync2 : std_logic_vector(ADDR_WIDTH DOWNTO 0); + SIGNAL rd_ptr_gray_sync1 : std_logic_vector(ADDR_WIDTH DOWNTO 0); + SIGNAL rd_ptr_gray_sync2 : std_logic_vector(ADDR_WIDTH DOWNTO 0); - -- Synchronized pointers - SIGNAL wr_ptr_gray_sync1 : std_logic_vector(ADDR_WIDTH DOWNTO 0) := (OTHERS => '0'); - SIGNAL wr_ptr_gray_sync2 : std_logic_vector(ADDR_WIDTH DOWNTO 0) := (OTHERS => '0'); - SIGNAL rd_ptr_gray_sync1 : std_logic_vector(ADDR_WIDTH DOWNTO 0) := (OTHERS => '0'); - SIGNAL rd_ptr_gray_sync2 : std_logic_vector(ADDR_WIDTH DOWNTO 0) := (OTHERS => '0'); + -- FIX v4: Registered binary pointers after Gray-to-binary conversion + -- This breaks the critical path: sync2 -> gray_to_bin -> comparison -> output + -- Into: sync2 -> gray_to_bin -> REG -> comparison -> output + SIGNAL wr_ptr_bin_sync : std_logic_vector(ADDR_WIDTH DOWNTO 0); -- Now a signal, not variable + SIGNAL rd_ptr_bin_sync : std_logic_vector(ADDR_WIDTH DOWNTO 0); -- For symmetry in write domain - -- Status flags - SIGNAL full_int : std_logic := '0'; - SIGNAL empty_int : std_logic := '1'; - SIGNAL tready_int : std_logic := '0'; - SIGNAL tvalid_int : std_logic := '0'; - SIGNAL prog_full_int : std_logic := '0'; - SIGNAL prog_empty_int : std_logic := '0'; + -- Status flags (reset-initialized in respective clock domains) + SIGNAL full_int : std_logic; + SIGNAL empty_int : std_logic; + SIGNAL tready_int : std_logic; + SIGNAL tvalid_int : std_logic; + SIGNAL prog_full_int : std_logic; + SIGNAL prog_empty_int : std_logic; + -- Status resync to AXI + SIGNAL wr_status_ack : std_logic; + SIGNAL wr_status_ack_sync1 : std_logic; + SIGNAL wr_status_ack_sync2 : std_logic; + SIGNAL wr_status_req_sync1 : std_logic; + SIGNAL wr_status_req_sync2 : std_logic; + SIGNAL rd_status_ack : std_logic; + SIGNAL rd_status_ack_sync1 : std_logic; + SIGNAL rd_status_ack_sync2 : std_logic; + SIGNAL rd_status_req_sync1 : std_logic; + SIGNAL rd_status_req_sync2 : std_logic; + + SIGNAL srequest : std_logic; + + TYPE state_type IS (IDLE, WAIT_FOR_WR_ACK, WAIT_FOR_RD_ACK); + SIGNAL status_state : state_type; + -- Binary to Gray conversion FUNCTION bin_to_gray(bin : std_logic_vector) RETURN std_logic_vector IS VARIABLE gray : std_logic_vector(bin'RANGE); @@ -107,7 +149,6 @@ BEGIN ------------------------------------------------------------------------------ write_proc: PROCESS(wr_aclk) VARIABLE wr_ptr_bin_next : std_logic_vector(ADDR_WIDTH DOWNTO 0); - VARIABLE rd_ptr_bin_sync : std_logic_vector(ADDR_WIDTH DOWNTO 0); BEGIN IF rising_edge(wr_aclk) THEN IF wr_aresetn = '0' THEN @@ -116,12 +157,18 @@ BEGIN full_int <= '0'; tready_int <= '0'; prog_full_int <= '0'; + rd_ptr_gray_sync1 <= (OTHERS => '0'); + rd_ptr_gray_sync2 <= (OTHERS => '0'); + rd_ptr_bin_sync <= (OTHERS => '0'); -- FIX v4: Initialize registered signal ELSE - -- Synchronize read pointer + -- Synchronize read pointer (2-stage synchronizer) rd_ptr_gray_sync1 <= rd_ptr_gray; rd_ptr_gray_sync2 <= rd_ptr_gray_sync1; - rd_ptr_bin_sync := gray_to_bin(rd_ptr_gray_sync2); + + -- FIX v4: Register the Gray-to-binary conversion output + -- This is the key timing fix - breaks the combinational path + rd_ptr_bin_sync <= gray_to_bin(rd_ptr_gray_sync2); -- AXIS write handshake IF s_axis_tvalid = '1' AND tready_int = '1' THEN @@ -133,7 +180,7 @@ BEGIN wr_ptr_gray <= bin_to_gray(wr_ptr_bin_next); END IF; - -- Full detection + -- Full detection (now uses registered rd_ptr_bin_sync) IF wr_ptr_bin(ADDR_WIDTH) /= rd_ptr_bin_sync(ADDR_WIDTH) AND wr_ptr_bin(ADDR_WIDTH-1 DOWNTO 0) = rd_ptr_bin_sync(ADDR_WIDTH-1 DOWNTO 0) THEN full_int <= '1'; @@ -141,8 +188,8 @@ BEGIN full_int <= '0'; END IF; - -- Programmable full - IF DEPTH - (unsigned(wr_ptr_bin) - unsigned(rd_ptr_bin_sync)) <= 512 THEN + -- Programmable full - frame-aware threshold (now uses registered rd_ptr_bin_sync) + IF DEPTH - (unsigned(wr_ptr_bin) - unsigned(rd_ptr_bin_sync)) <= ALERT_THRESHOLD THEN prog_full_int <= '1'; ELSE prog_full_int <= '0'; @@ -159,12 +206,15 @@ BEGIN END PROCESS write_proc; ------------------------------------------------------------------------------ - -- Read Clock Domain - WITH SYNC LAG FIX + -- Read Clock Domain - CORRECTED THREE-STATE LOGIC + ------------------------------------------------------------------------------ + -- State A: Becoming valid (tvalid_int='0' → '1'): Present first byte + -- State B: Handshake completes (tvalid='1', tready='1'): Advance, present next + -- State C: Valid but stalled (tvalid='1', tready='0'): HOLD STABLE ------------------------------------------------------------------------------ read_proc: PROCESS(rd_aclk) VARIABLE rd_ptr_bin_next : std_logic_vector(ADDR_WIDTH DOWNTO 0); - VARIABLE wr_ptr_bin_sync : std_logic_vector(ADDR_WIDTH DOWNTO 0); - VARIABLE empty_next : std_logic; + VARIABLE empty_current : std_logic; BEGIN IF rising_edge(rd_aclk) THEN IF rd_aresetn = '0' THEN @@ -175,54 +225,81 @@ BEGIN prog_empty_int <= '1'; m_axis_tdata <= (OTHERS => '0'); m_axis_tlast <= '0'; + wr_ptr_gray_sync1 <= (OTHERS => '0'); + wr_ptr_gray_sync2 <= (OTHERS => '0'); + wr_ptr_bin_sync <= (OTHERS => '0'); -- FIX v4: Initialize registered signal ELSE - -- Synchronize write pointer + -- Synchronize write pointer (2-stage synchronizer) wr_ptr_gray_sync1 <= wr_ptr_gray; wr_ptr_gray_sync2 <= wr_ptr_gray_sync1; - wr_ptr_bin_sync := gray_to_bin(wr_ptr_gray_sync2); - -- Calculate next empty status based on CURRENT pointers + -- FIX v4: Register the Gray-to-binary conversion output + -- This breaks the critical path that was failing timing: + -- wr_ptr_gray_sync2 -> gray_to_bin -> comparison -> m_axis_tdata + -- Now becomes: + -- wr_ptr_gray_sync2 -> gray_to_bin -> wr_ptr_bin_sync (REG) + -- wr_ptr_bin_sync -> comparison -> m_axis_tdata + wr_ptr_bin_sync <= gray_to_bin(wr_ptr_gray_sync2); + + -- Check if FIFO is currently empty (now uses registered wr_ptr_bin_sync) IF wr_ptr_bin_sync = rd_ptr_bin THEN - empty_next := '1'; + empty_current := '1'; ELSE - empty_next := '0'; + empty_current := '0'; END IF; - -- Present data when not empty - -- This sets up tdata, tlast, and tvalid for the CURRENT cycle - IF empty_next = '0' THEN + ---------------------------------------------------------------------- + -- THREE STATE LOGIC + ---------------------------------------------------------------------- + + -- STATE A: Becoming valid (was invalid, now have data) + -- Action: Present first byte, assert tvalid, DO NOT advance pointer + IF tvalid_int = '0' AND empty_current = '0' THEN m_axis_tdata <= ram_data(to_integer(unsigned(rd_ptr_bin(ADDR_WIDTH-1 DOWNTO 0)))); m_axis_tlast <= ram_last(to_integer(unsigned(rd_ptr_bin(ADDR_WIDTH-1 DOWNTO 0)))); tvalid_int <= '1'; - ELSE - -- When empty, deassert tvalid and clear tlast - -- (tdata is don't care per AXI-Stream spec, but we clear it for cleanliness) - tvalid_int <= '0'; - m_axis_tlast <= '0'; - m_axis_tdata <= (OTHERS => '0'); - END IF; + empty_int <= '0'; + -- rd_ptr_bin stays same! This is the first presentation - -- AXIS read handshake - advance pointer only when: - -- 1. We're presenting valid data (empty_next = '0') - -- 2. Downstream is ready (m_axis_tready = '1') - IF empty_next = '0' AND m_axis_tready = '1' THEN + -- STATE B: Handshake completes (valid and ready) + -- Action: Advance pointer, present next byte OR deassert tvalid + ELSIF tvalid_int = '1' AND m_axis_tready = '1' THEN rd_ptr_bin_next := std_logic_vector(unsigned(rd_ptr_bin) + 1); rd_ptr_bin <= rd_ptr_bin_next; rd_ptr_gray <= bin_to_gray(rd_ptr_bin_next); - -- Update empty status based on where we'll be AFTER this read + -- Check if we'll be empty after this read (uses registered wr_ptr_bin_sync) IF wr_ptr_bin_sync = rd_ptr_bin_next THEN + -- Going empty empty_int <= '1'; + tvalid_int <= '0'; + m_axis_tlast <= '0'; + m_axis_tdata <= (OTHERS => '0'); ELSE + -- More data available - present next byte empty_int <= '0'; + tvalid_int <= '1'; + m_axis_tdata <= ram_data(to_integer(unsigned(rd_ptr_bin_next(ADDR_WIDTH-1 DOWNTO 0)))); + m_axis_tlast <= ram_last(to_integer(unsigned(rd_ptr_bin_next(ADDR_WIDTH-1 DOWNTO 0)))); END IF; + + -- STATE C: Valid but NOT ready (tvalid='1', tready='0') + -- Action: HOLD EVERYTHING STABLE - no changes to tdata, tlast, tvalid, rd_ptr + ELSIF tvalid_int = '1' AND m_axis_tready = '0' THEN + -- Explicitly do nothing - all signals hold their values + -- This is the critical fix: maintain protocol compliance + empty_int <= '0'; -- We know we're not empty if tvalid='1' + + -- All other cases: remain invalid ELSE - -- No advancement - empty_int <= empty_next; + empty_int <= '1'; + tvalid_int <= '0'; + m_axis_tlast <= '0'; + m_axis_tdata <= (OTHERS => '0'); END IF; - -- Programmable empty + -- Programmable empty (uses registered wr_ptr_bin_sync) IF unsigned(wr_ptr_bin_sync) <= unsigned(rd_ptr_bin) + 271 THEN prog_empty_int <= '1'; ELSE @@ -232,4 +309,94 @@ BEGIN END IF; END PROCESS read_proc; + ------------------------------------------------------------------------------ + -- Status Clock Domain + ------------------------------------------------------------------------------ + + status_proc : PROCESS (status_aclk) + BEGIN + IF rising_edge(status_aclk) THEN + IF status_aresetn = '0' THEN + fifo_overflow <= '0'; + fifo_underflow <= '0'; + status_ack <= '0'; + status_state <= IDLE; + ELSE + + CASE status_state IS + WHEN IDLE => + srequest <= '0'; + status_ack <= '0'; + IF status_req = '1' THEN + srequest <= '1'; + status_state <= WAIT_FOR_WR_ACK; + END IF; + + WHEN WAIT_FOR_WR_ACK => + IF wr_status_ack_sync2 = '1' THEN + status_state <= WAIT_FOR_RD_ACK; + END IF; + + WHEN WAIT_FOR_RD_ACK => + IF rd_status_ack_sync2 = '1' THEN + status_ack <= '1'; + srequest <= '0'; + status_state <= IDLE; + END IF; + + WHEN OTHERS => + status_state <= IDLE; + + END CASE; + + wr_status_ack_sync1 <= wr_status_ack; + wr_status_ack_sync2 <= wr_status_ack_sync1; + + rd_status_ack_sync1 <= rd_status_ack; + rd_status_ack_sync2 <= rd_status_ack_sync1; + + END IF; + END IF; + END PROCESS status_proc; + + status_wrclk : PROCESS (wr_aclk) + BEGIN + IF rising_edge(wr_aclk) THEN + IF wr_aresetn = '0' THEN + wr_status_req_sync1 <= '0'; + wr_status_req_sync2 <= '0'; + wr_status_ack <= '0'; + fifo_wr_ptr <= (OTHERS => '0'); + ELSE + wr_status_req_sync1 <= srequest; + wr_status_req_sync2 <= wr_status_req_sync1; + wr_status_ack <= wr_status_req_sync2; + + IF wr_status_req_sync2 = '1' THEN + fifo_wr_ptr <= wr_ptr_bin; + END IF; + END IF; + END IF; + END PROCESS status_wrclk; + + status_rdclk : PROCESS (rd_aclk) + BEGIN + IF rising_edge(rd_aclk) THEN + IF rd_aresetn = '0' THEN + rd_status_req_sync1 <= '0'; + rd_status_req_sync2 <= '0'; + rd_status_ack <= '0'; + fifo_rd_ptr <= (OTHERS => '0'); + ELSE + rd_status_req_sync1 <= srequest; + rd_status_req_sync2 <= rd_status_req_sync1; + rd_status_ack <= rd_status_req_sync2; + + IF rd_status_req_sync2 = '1' THEN + fifo_rd_ptr <= rd_ptr_bin; + END IF; + END IF; + END IF; + END PROCESS status_rdclk; + END ARCHITECTURE rtl; diff --git a/src/bit_to_byte_serializer.vhd b/src/bit_to_byte_serializer.vhd deleted file mode 100644 index 2e1711a..0000000 --- a/src/bit_to_byte_serializer.vhd +++ /dev/null @@ -1,67 +0,0 @@ ------------------------------------------------------------------------------------------------------- --- Bit to Byte Serializer for MSK Demodulator ------------------------------------------------------------------------------------------------------- --- Collects individual bits from demodulator into 8-bit bytes --- LSB-first ordering to match transmit side ------------------------------------------------------------------------------------------------------- - -LIBRARY ieee; -USE ieee.std_logic_1164.ALL; -USE ieee.numeric_std.ALL; - -ENTITY bit_to_byte_serializer IS - GENERIC ( - BYTE_WIDTH : NATURAL := 8 - ); - PORT ( - clk : IN std_logic; - reset : IN std_logic; - - rx_bit : IN std_logic; - rx_bit_valid : IN std_logic; - - rx_byte : OUT std_logic_vector(BYTE_WIDTH-1 DOWNTO 0); - rx_byte_valid : OUT std_logic - ); -END ENTITY bit_to_byte_serializer; - -ARCHITECTURE rtl OF bit_to_byte_serializer IS - - SIGNAL shift_reg : std_logic_vector(BYTE_WIDTH-1 DOWNTO 0); - SIGNAL ser_bit_counter : unsigned(2 DOWNTO 0); - -BEGIN - - serializer_proc: PROCESS(clk) - BEGIN - IF rising_edge(clk) THEN - IF reset = '1' THEN - shift_reg <= (OTHERS => '0'); - ser_bit_counter <= (OTHERS => '0'); - rx_byte <= (OTHERS => '0'); - rx_byte_valid <= '0'; - - ELSE - -- Default - rx_byte_valid <= '0'; - - IF rx_bit_valid = '1' THEN - -- Shift in new bit (LSB first) - shift_reg <= shift_reg(BYTE_WIDTH-2 DOWNTO 0) & rx_bit; - - IF ser_bit_counter = 7 THEN - -- Byte complete - output it - rx_byte <= shift_reg(BYTE_WIDTH-2 DOWNTO 0) & rx_bit; - rx_byte_valid <= '1'; - ser_bit_counter <= (OTHERS => '0'); - ELSE - -- Keep counting - ser_bit_counter <= ser_bit_counter + 1; - END IF; - END IF; - - END IF; - END IF; - END PROCESS serializer_proc; - -END ARCHITECTURE rtl; diff --git a/src/byte_to_bit_deserializer.vhd b/src/byte_to_bit_deserializer.vhd index 74cc3f6..b054a88 100644 --- a/src/byte_to_bit_deserializer.vhd +++ b/src/byte_to_bit_deserializer.vhd @@ -48,6 +48,14 @@ ARCHITECTURE rtl OF byte_to_bit_deserializer IS TYPE state_t IS (IDLE, SENDING_SYNC, SHIFTING_DATA); SIGNAL state : state_t; + ATTRIBUTE dont_touch : STRING; + ATTRIBUTE dont_touch OF state : SIGNAL IS "true"; + ATTRIBUTE dont_touch OF ready_int : SIGNAL IS "true"; + ATTRIBUTE dont_touch OF last_byte : SIGNAL IS "true"; + ATTRIBUTE dont_touch OF shift_reg : SIGNAL IS "true"; + ATTRIBUTE dont_touch OF bit_counter : SIGNAL IS "true"; + + BEGIN s_axis_tready <= ready_int; @@ -91,7 +99,8 @@ BEGIN bit_counter <= 7; -- Prepare for data bits (start at bit 7) state <= SHIFTING_DATA; ready_int <= '1'; - tx_data_int <= '0'; -- Default for next state + -- Keep last sync bit on output until new byte loads + -- (don't force to '0' - that could cause glitch) ELSE -- Prepare NEXT bit for output (count down from MSB) bit_counter <= bit_counter - 1; @@ -123,7 +132,8 @@ BEGIN ELSE bit_counter <= 7; -- Reset for next byte ready_int <= '1'; - tx_data_int <= '0'; -- Will be updated when new byte arrives + -- Keep last bit on output until new byte loads + -- (don't force to '0' - that could cause glitch) END IF; ELSE -- Prepare NEXT bit for output (count down) diff --git a/src/cdc_resync.vhd b/src/cdc_resync.vhd new file mode 100644 index 0000000..d5f7128 --- /dev/null +++ b/src/cdc_resync.vhd @@ -0,0 +1,102 @@ +------------------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------ +-- _______ ________ ______ +-- __ __ \________ _____ _______ ___ __ \_____ _____________ ______ ___________________ /_ +-- _ / / /___ __ \_ _ \__ __ \ __ /_/ /_ _ \__ ___/_ _ \_ __ `/__ ___/_ ___/__ __ \ +-- / /_/ / __ /_/ // __/_ / / / _ _, _/ / __/_(__ ) / __// /_/ / _ / / /__ _ / / / +-- \____/ _ .___/ \___/ /_/ /_/ /_/ |_| \___/ /____/ \___/ \__,_/ /_/ \___/ /_/ /_/ +-- /_/ +-- ________ _____ _____ _____ _____ +-- ____ _/_______ __________ /____(_)__ /_____ ____ /______ +-- __ / __ __ \__ ___/_ __/__ / _ __/_ / / /_ __/_ _ \ +-- __/ / _ / / /_(__ ) / /_ _ / / /_ / /_/ / / /_ / __/ +-- /___/ /_/ /_/ /____/ \__/ /_/ \__/ \__,_/ \__/ \___/ +-- +------------------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------ +-- Copyright +------------------------------------------------------------------------------------------------------ +-- +-- Copyright 2025 by M. Wishek +-- +------------------------------------------------------------------------------------------------------ +-- License +------------------------------------------------------------------------------------------------------ +-- +-- This source describes Open Hardware and is licensed under the CERN-OHL-W v2. +-- +-- You may redistribute and modify this source and make products using it under +-- the terms of the CERN-OHL-W v2 (https://ohwr.org/cern_ohl_w_v2.txt). +-- +-- This source is distributed WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING +-- OF MERCHANTABILITY, SATISFACTORY QUALITY AND FITNESS FOR A PARTICULAR PURPOSE. +-- Please see the CERN-OHL-W v2 for applicable conditions. +-- +-- Source location: TBD +-- +-- As per CERN-OHL-W v2 section 4.1, should You produce hardware based on this +-- source, You must maintain the Source Location visible on the external case of +-- the products you make using this source. +-- +------------------------------------------------------------------------------------------------------ +-- Block name and description +------------------------------------------------------------------------------------------------------ +-- +-- This is a wrapper block for the register module generated by DesyRDL. +-- +-- Documentation location: TBD +-- +------------------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------ + + +------------------------------------------------------------------------------------------------------ +-- ╦ ┬┌┐ ┬─┐┌─┐┬─┐┬┌─┐┌─┐ +-- ║ │├┴┐├┬┘├─┤├┬┘│├┤ └─┐ +-- ╩═╝┴└─┘┴└─┴ ┴┴└─┴└─┘└─┘ +------------------------------------------------------------------------------------------------------ +-- Libraries + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +------------------------------------------------------------------------------------------------------ +-- ╔═╗┌┐┌┌┬┐┬┌┬┐┬ ┬ +-- ║╣ │││ │ │ │ └┬┘ +-- ╚═╝┘└┘ ┴ ┴ ┴ ┴ +------------------------------------------------------------------------------------------------------ +-- Entity + +ENTITY cdc_resync IS + PORT ( + clk : IN std_logic; + sync_reset : IN std_logic; + + di : IN std_logic; + do : OUT std_logic + ); +END ENTITY cdc_resync; + +ARCHITECTURE rtl OF cdc_resync IS + + SIGNAL di_s : std_logic_vector(0 TO 1); + +BEGIN + + do <= di_s(1); + + resync : PROCESS (clk) + BEGIN + IF clk'EVENT AND clk = '1' THEN + IF sync_reset = '1' THEN + di_s <= (OTHERS => '0'); + ELSE + di_s <= di & di_s(0 TO 0); + END IF; + END IF; + END PROCESS resync; + +END ARCHITECTURE rtl; + + diff --git a/src/clk_div_by4.vhd b/src/clk_div_by4.vhd new file mode 100644 index 0000000..26a3bbf --- /dev/null +++ b/src/clk_div_by4.vhd @@ -0,0 +1,90 @@ +------------------------------------------------------------------------------------------------------ +-- Clock Divider by 4 with Pulse Stretchers +------------------------------------------------------------------------------------------------------ +-- Divides 245.76 MHz l_clk to 61.44 MHz for MSK modem on LibreSDR +-- Also stretches dac_valid and adc_valid pulses from 1 to 2 l_clk cycles +-- so msk_top (running at 61.44 MHz) doesn't miss them +------------------------------------------------------------------------------------------------------ +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; +library UNISIM; +use UNISIM.VComponents.all; + +entity clk_div_by4 is + port ( + clk_in : in std_logic; -- 245.76 MHz from axi_ad9361/l_clk + clk_out : out std_logic; -- 61.44 MHz divided clock + + -- TX pulse stretcher + dac_valid_in : in std_logic; -- 1 l_clk cycle pulse from AD9361 + dac_valid_out : out std_logic; -- 2 l_clk cycles stretched for msk_top + + -- RX pulse stretcher + adc_valid_in : in std_logic; -- 1 l_clk cycle pulse from AD9361 + adc_valid_out : out std_logic; -- 2 l_clk cycles stretched for msk_top + + -- Debug ports + dbg_counter : out std_logic_vector(1 downto 0); + dbg_clk_ff : out std_logic + ); +end entity clk_div_by4; + +architecture rtl of clk_div_by4 is + signal counter : unsigned(1 downto 0) := "00"; + signal clk_div_ff : std_logic := '0'; + signal clk_div_bufg : std_logic; + signal dac_valid_d1 : std_logic := '0'; + signal dac_valid_d2 : std_logic := '0'; + signal adc_valid_d1 : std_logic := '0'; + signal adc_valid_d2 : std_logic := '0'; + + attribute DONT_TOUCH : string; + attribute DONT_TOUCH of counter : signal is "TRUE"; + attribute DONT_TOUCH of clk_div_ff : signal is "TRUE"; + + attribute MARK_DEBUG : string; + attribute MARK_DEBUG of counter : signal is "TRUE"; + attribute MARK_DEBUG of clk_div_ff : signal is "TRUE"; +begin + + process(clk_in) + begin + if rising_edge(clk_in) then + -- Clock divider: count 0,1,2,3,0,1,2,3... + counter <= counter + 1; + if counter = "01" then + clk_div_ff <= '1'; + elsif counter = "11" then + clk_div_ff <= '0'; + end if; + + -- Pulse stretchers: 2-stage delay + dac_valid_d1 <= dac_valid_in; + dac_valid_d2 <= dac_valid_d1; + adc_valid_d1 <= adc_valid_in; + adc_valid_d2 <= adc_valid_d1; + end if; + end process; + + -- Stretched pulses: 3 cycles wide (covers phases 0, 1, 2) + --dac_valid_out <= dac_valid_in OR dac_valid_d1 OR dac_valid_d2; + --adc_valid_out <= adc_valid_in OR adc_valid_d1 OR adc_valid_d2; + -- TEMPORARY: bypass stretcher, hardcode high (equivalent to VCC) + dac_valid_out <= '1'; + adc_valid_out <= '1'; + + -- BUFG for global clock distribution + U_BUFG : BUFG + port map ( + I => clk_div_ff, + O => clk_div_bufg + ); + + clk_out <= clk_div_bufg; + + -- Debug outputs + dbg_counter <= std_logic_vector(counter); + dbg_clk_ff <= clk_div_ff; + +end architecture rtl; diff --git a/src/conv_encoder_k7.vhd b/src/conv_encoder_k7.vhd new file mode 100644 index 0000000..a73127a --- /dev/null +++ b/src/conv_encoder_k7.vhd @@ -0,0 +1,188 @@ +------------------------------------------------------------------------------------------------------ +-- K=7 Convolutional Encoder - Shift Register Version (Corrected Polynomials) +------------------------------------------------------------------------------------------------------ +-- Rate 1/2, constraint length K=7 +-- Generator polynomials: G1 = 171 octal, G2 = 133 octal +-- +-- CRITICAL: The polynomial tap interpretation must match the original! +-- G1_POLY = "1111001" with loop using full_state(6-i) means: +-- G1 = curr_bit XOR sr(3) XOR sr(2) XOR sr(1) XOR sr(0) +-- G2_POLY = "1011011" means: +-- G2 = curr_bit XOR sr(5) XOR sr(3) XOR sr(2) XOR sr(0) +-- +-- RESOURCE OPTIMIZATION: +-- Original version: ~3000 LUTs (variable bit indexing creates massive mux/demux) +-- This version: ~200-400 LUTs (shift registers, fixed-position access only) +------------------------------------------------------------------------------------------------------ + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +ENTITY conv_encoder_k7 IS + GENERIC ( + PAYLOAD_BYTES : NATURAL := 134; + ENCODED_BYTES : NATURAL := 268 + ); + PORT ( + clk : IN std_logic; + aresetn : IN std_logic; + + start : IN std_logic; + busy : OUT std_logic; + done : OUT std_logic; + + input_buffer : IN std_logic_vector(PAYLOAD_BYTES*8-1 DOWNTO 0); + output_buffer : OUT std_logic_vector(ENCODED_BYTES*8-1 DOWNTO 0) + ); +END ENTITY conv_encoder_k7; + +ARCHITECTURE rtl OF conv_encoder_k7 IS + + CONSTANT INPUT_BITS : NATURAL := PAYLOAD_BYTES * 8; -- 1072 + CONSTANT OUTPUT_BITS : NATURAL := ENCODED_BYTES * 8; -- 2144 + + TYPE state_t IS (IDLE, ENCODE, COMPLETE); + SIGNAL state : state_t := IDLE; + + -- Input shift register - shifts MSB out first + SIGNAL in_sr : std_logic_vector(INPUT_BITS-1 DOWNTO 0); + + -- Output shift register - accumulates encoded bits + SIGNAL out_sr : std_logic_vector(OUTPUT_BITS-1 DOWNTO 0); + + -- Encoder shift register (6 bits of history for K=7) + -- sr(0) = most recent previous bit, sr(5) = oldest + SIGNAL enc_sr : std_logic_vector(5 DOWNTO 0); + + -- Bit counter + SIGNAL bit_count : unsigned(10 DOWNTO 0); -- counts 0 to 1071 + + -- Latched output (stable while not encoding) + SIGNAL out_latched : std_logic_vector(OUTPUT_BITS-1 DOWNTO 0); + + ATTRIBUTE dont_touch : STRING; + ATTRIBUTE dont_touch OF in_sr : SIGNAL IS "true"; + ATTRIBUTE dont_touch OF out_sr : SIGNAL IS "true"; + ATTRIBUTE dont_touch OF enc_sr : SIGNAL IS "true"; + ATTRIBUTE dont_touch OF out_latched : SIGNAL IS "true"; + ATTRIBUTE dont_touch OF state : SIGNAL IS "true"; + ATTRIBUTE dont_touch OF bit_count : SIGNAL IS "true"; + + ATTRIBUTE ram_style : STRING; + ATTRIBUTE ram_style OF in_sr : SIGNAL IS "block"; + ATTRIBUTE ram_style OF out_sr : SIGNAL IS "true"; + ATTRIBUTE ram_style OF out_latched : SIGNAL IS "block"; + + + +BEGIN + + PROCESS(clk, aresetn) + VARIABLE curr_bit : std_logic; + VARIABLE g1, g2 : std_logic; + BEGIN + IF aresetn = '0' THEN + state <= IDLE; + busy <= '0'; + done <= '0'; + in_sr <= (OTHERS => '0'); + out_sr <= (OTHERS => '0'); + enc_sr <= (OTHERS => '0'); + bit_count <= (OTHERS => '0'); + out_latched <= (OTHERS => '0'); + + ELSIF rising_edge(clk) THEN + -- Default: done is single-cycle pulse + done <= '0'; + + CASE state IS + + WHEN IDLE => + busy <= '0'; + IF start = '1' THEN + -- Parallel load input shift register + in_sr <= input_buffer; + out_sr <= (OTHERS => '0'); + enc_sr <= (OTHERS => '0'); + bit_count <= (OTHERS => '0'); + busy <= '1'; + state <= ENCODE; + END IF; + + WHEN ENCODE => + -- Get current input bit from MSB of shift register + curr_bit := in_sr(INPUT_BITS - 1); + + ---------------------------------------------------------------- + -- POLYNOMIAL COMPUTATION - Must match original exactly! + ---------------------------------------------------------------- + -- Original uses: full_state = curr_bit & enc_sr + -- With loop: g1 XOR= full_state(6-i) when G1_POLY(i)='1' + -- + -- G1_POLY = "1111001" (bits 6,5,4,3,0 are '1') + -- i=0: full_state(6) = curr_bit + -- i=3: full_state(3) = enc_sr(3) + -- i=4: full_state(2) = enc_sr(2) + -- i=5: full_state(1) = enc_sr(1) + -- i=6: full_state(0) = enc_sr(0) + -- G1 = curr_bit XOR enc_sr(3) XOR enc_sr(2) XOR enc_sr(1) XOR enc_sr(0) + -- + -- G2_POLY = "1011011" (bits 6,4,3,1,0 are '1') + -- i=0: full_state(6) = curr_bit + -- i=1: full_state(5) = enc_sr(5) + -- i=3: full_state(3) = enc_sr(3) + -- i=4: full_state(2) = enc_sr(2) + -- i=6: full_state(0) = enc_sr(0) + -- G2 = curr_bit XOR enc_sr(5) XOR enc_sr(3) XOR enc_sr(2) XOR enc_sr(0) + ---------------------------------------------------------------- + + --------------------------------------- + -- So You Say You Want A Duplication -- + -- Bypass? Set g1 and g2 to curr_bit -- + -- here. Uncomment this and comment -- + -- out the full g1 and g2 equation -- + -- to drop FEC out of the design. -- + -- The interleaver etc. will then -- + -- have the right number of bits, -- + -- but we won't have any FEC. -- + --------------------------------------- + + --g1 := curr_bit; -- for "fake" FEC + --g2 := curr_bit; -- for "fake" FEC, or NOT curr_bit + + g1 := curr_bit XOR enc_sr(3) XOR enc_sr(2) XOR enc_sr(1) XOR enc_sr(0); + g2 := curr_bit XOR enc_sr(5) XOR enc_sr(3) XOR enc_sr(2) XOR enc_sr(0); + + -- Update encoder shift register (shift in current bit at LSB) + enc_sr <= enc_sr(4 DOWNTO 0) & curr_bit; + + -- Shift input register left (next bit moves to MSB position) + in_sr <= in_sr(INPUT_BITS-2 DOWNTO 0) & '0'; + + -- Shift output register left by 2, insert g1 and g2 at LSB + -- g1 goes to higher bit position (matches original out_buf indexing) + out_sr <= out_sr(OUTPUT_BITS-3 DOWNTO 0) & g1 & g2; + + -- Count bits processed + IF bit_count = INPUT_BITS - 1 THEN + -- All bits encoded, latch output + out_latched <= out_sr(OUTPUT_BITS-3 DOWNTO 0) & g1 & g2; + state <= COMPLETE; + ELSE + bit_count <= bit_count + 1; + END IF; + + WHEN COMPLETE => + done <= '1'; + busy <= '0'; + state <= IDLE; + + END CASE; + END IF; + END PROCESS; + + -- Output is latched value (stable during next encoding) + output_buffer <= out_latched; + +END ARCHITECTURE rtl; diff --git a/src/conv_encoder_k7.vhd.backup b/src/conv_encoder_k7.vhd.backup new file mode 100644 index 0000000..1d6a617 --- /dev/null +++ b/src/conv_encoder_k7.vhd.backup @@ -0,0 +1,168 @@ +------------------------------------------------------------------------------------------------------ +-- K=7 Convolutional Encoder (FIXED - No Signal Timing Bugs) +------------------------------------------------------------------------------------------------------ +-- Rate 1/2, constraint length K=7 +-- Generator polynomials: G1 = 171 octal = 1111001 binary +-- G2 = 133 octal = 1011011 binary +------------------------------------------------------------------------------------------------------ + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +ENTITY conv_encoder_k7 IS + GENERIC ( + PAYLOAD_BYTES : NATURAL := 134; -- Input size in bytes + ENCODED_BYTES : NATURAL := 268 -- Output size in bytes (2x for rate 1/2) + ); + PORT ( + clk : IN std_logic; + aresetn : IN std_logic; + + start : IN std_logic; + busy : OUT std_logic; + done : OUT std_logic; + + input_buffer : IN std_logic_vector(PAYLOAD_BYTES*8-1 DOWNTO 0); + output_buffer : OUT std_logic_vector(ENCODED_BYTES*8-1 DOWNTO 0) + ); +END ENTITY conv_encoder_k7; + +ARCHITECTURE rtl OF conv_encoder_k7 IS + + -- TYPE state_t IS (IDLE, ENCODE_DATA, FLUSH_TRELLIS, COMPLETE); + TYPE state_t IS (IDLE, ENCODE_DATA, COMPLETE); + SIGNAL state : state_t := IDLE; + + SIGNAL input_bit_count : NATURAL RANGE 0 TO PAYLOAD_BYTES*8; + SIGNAL output_bit_count : NATURAL RANGE 0 TO ENCODED_BYTES*8; + + CONSTANT G1_POLY : std_logic_vector(6 DOWNTO 0) := "1111001"; + CONSTANT G2_POLY : std_logic_vector(6 DOWNTO 0) := "1011011"; + + SIGNAL out_buf : std_logic_vector(ENCODED_BYTES*8-1 DOWNTO 0); + + ATTRIBUTE ram_style : STRING; + ATTRIBUTE ram_style OF out_buf : SIGNAL IS "block"; + + -- defend against synthesis optimizing our signals out + ATTRIBUTE dont_touch : STRING; + ATTRIBUTE dont_touch OF out_buf : SIGNAL IS "true"; + + -- Function to compute encoder outputs + FUNCTION compute_outputs( + current_bit : std_logic; + shift_reg : std_logic_vector(5 DOWNTO 0) + ) RETURN std_logic_vector IS + VARIABLE full_state : std_logic_vector(6 DOWNTO 0); + VARIABLE g1, g2 : std_logic; + BEGIN + full_state := current_bit & shift_reg; + + -- G1 output + g1 := '0'; + FOR i IN 0 TO 6 LOOP + IF G1_POLY(i) = '1' THEN + g1 := g1 XOR full_state(6-i); + END IF; + END LOOP; + + -- G2 output + g2 := '0'; + FOR i IN 0 TO 6 LOOP + IF G2_POLY(i) = '1' THEN + g2 := g2 XOR full_state(6-i); + END IF; + END LOOP; + + RETURN g1 & g2; -- Return as 2-bit vector + END FUNCTION; + +BEGIN + + PROCESS(clk, aresetn) + VARIABLE shift_reg : std_logic_vector(5 DOWNTO 0); + VARIABLE current_bit : std_logic; + VARIABLE outputs : std_logic_vector(1 DOWNTO 0); + BEGIN + IF aresetn = '0' THEN + state <= IDLE; + shift_reg := (OTHERS => '0'); + input_bit_count <= 0; + output_bit_count <= 0; + busy <= '0'; + done <= '0'; + out_buf <= (OTHERS => '0'); + + ELSIF rising_edge(clk) THEN + done <= '0'; + + CASE state IS + + WHEN IDLE => + busy <= '0'; + IF start = '1' THEN + state <= ENCODE_DATA; + busy <= '1'; + shift_reg := (OTHERS => '0'); + input_bit_count <= 0; + output_bit_count <= 0; + END IF; + + WHEN ENCODE_DATA => + -- Process 1,070 bits (stop 2 bits early for tail) + IF input_bit_count < PAYLOAD_BYTES*8 THEN + -- Read input bit (MSB first) + current_bit := input_buffer(PAYLOAD_BYTES*8 - 1 - input_bit_count); + + -- Compute outputs using current state + outputs := compute_outputs(current_bit, shift_reg); + + -- Store outputs (g1 first, then g2) + out_buf(ENCODED_BYTES*8 - 1 - output_bit_count) <= outputs(1); -- g1 + out_buf(ENCODED_BYTES*8 - 2 - output_bit_count) <= outputs(0); -- g2 + + -- Update shift register + shift_reg := shift_reg(4 DOWNTO 0) & current_bit; + + input_bit_count <= input_bit_count + 1; + output_bit_count <= output_bit_count + 2; + ELSE + -- state <= FLUSH_TRELLIS; + -- input_bit_count <= 0; + state <= COMPLETE; + END IF; + +-- WHEN FLUSH_TRELLIS => +-- -- Add 2 tail bits (produces 4 encoded bits) +-- IF input_bit_count < 2 THEN +-- current_bit := '0'; +-- +-- -- Compute outputs +-- outputs := compute_outputs(current_bit, shift_reg); +-- +-- -- Store outputs +-- out_buf(ENCODED_BYTES*8 - 1 - output_bit_count) <= outputs(1); +-- out_buf(ENCODED_BYTES*8 - 2 - output_bit_count) <= outputs(0); +-- +-- -- Update shift register +-- shift_reg := shift_reg(4 DOWNTO 0) & '0'; +-- +-- input_bit_count <= input_bit_count + 1; +-- output_bit_count <= output_bit_count + 2; +-- ELSE +-- state <= COMPLETE; +-- END IF; + + WHEN COMPLETE => + done <= '1'; + busy <= '0'; + state <= IDLE; + + END CASE; + END IF; + END PROCESS; + + output_buffer <= out_buf; + +END ARCHITECTURE rtl; diff --git a/src/conv_encoder_k7.vhd.new b/src/conv_encoder_k7.vhd.new new file mode 100644 index 0000000..14dacfe --- /dev/null +++ b/src/conv_encoder_k7.vhd.new @@ -0,0 +1,237 @@ +------------------------------------------------------------------------------------------------------ +-- K=7 Convolutional Encoder - BRAM Optimized Version +------------------------------------------------------------------------------------------------------ +-- Rate 1/2, constraint length K=7 +-- Generator polynomials: G1 = 171 octal = 1111001 binary +-- G2 = 133 octal = 1011011 binary +-- +-- RESOURCE OPTIMIZATION: +-- Original version: ~3000 LUTs (bit-level indexing creates massive mux/demux) +-- This version: ~100-200 LUTs (byte-level BRAM addressing) +-- +-- TIMING: +-- Original: ~1072 clocks (1 bit/clock encoding only) +-- This version: ~134 (load) + 1072 (encode) + 268 (unload) = ~1474 clocks +-- Still completes in < 25 µs at 61.44 MHz, well under frame time +-- +-- KEY INSIGHT: +-- BRAM cannot do variable bit-level addressing. The expression: +-- buffer(TOTAL_BITS - 1 - bit_index) +-- creates a TOTAL_BITS:1 mux in LUTs. Instead, we use byte addressing: +-- ram(byte_index) +-- which Vivado can implement in BRAM. +------------------------------------------------------------------------------------------------------ + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +ENTITY conv_encoder_k7 IS + GENERIC ( + PAYLOAD_BYTES : NATURAL := 134; -- Input size in bytes + ENCODED_BYTES : NATURAL := 268 -- Output size in bytes (2x for rate 1/2) + ); + PORT ( + clk : IN std_logic; + aresetn : IN std_logic; + + start : IN std_logic; + busy : OUT std_logic; + done : OUT std_logic; + + input_buffer : IN std_logic_vector(PAYLOAD_BYTES*8-1 DOWNTO 0); + output_buffer : OUT std_logic_vector(ENCODED_BYTES*8-1 DOWNTO 0) + ); +END ENTITY conv_encoder_k7; + +ARCHITECTURE rtl OF conv_encoder_k7 IS + + -- State machine + TYPE state_t IS (IDLE, LOAD_INPUT, ENCODE, UNLOAD_OUTPUT, COMPLETE); + SIGNAL state : state_t := IDLE; + + -- BRAM for input storage (byte-addressable) + TYPE input_ram_t IS ARRAY(0 TO PAYLOAD_BYTES-1) OF std_logic_vector(7 DOWNTO 0); + SIGNAL input_ram : input_ram_t; + + -- BRAM for output storage (byte-addressable) + TYPE output_ram_t IS ARRAY(0 TO ENCODED_BYTES-1) OF std_logic_vector(7 DOWNTO 0); + SIGNAL output_ram : output_ram_t; + + -- Force BRAM inference + ATTRIBUTE ram_style : STRING; + ATTRIBUTE ram_style OF input_ram : SIGNAL IS "block"; + ATTRIBUTE ram_style OF output_ram : SIGNAL IS "block"; + + -- General byte counter (reused across states) + SIGNAL byte_cnt : NATURAL RANGE 0 TO ENCODED_BYTES; + + -- Encoding state + SIGNAL in_byte_addr : NATURAL RANGE 0 TO PAYLOAD_BYTES-1; + SIGNAL in_bit_pos : NATURAL RANGE 0 TO 7; -- Which bit within current input byte + SIGNAL total_in_bits: NATURAL RANGE 0 TO PAYLOAD_BYTES*8; + + -- Current input byte register + SIGNAL in_byte_reg : std_logic_vector(7 DOWNTO 0); + + -- Output accumulator (shift register, fills LSB-first then we reverse on write) + SIGNAL out_accum : std_logic_vector(7 DOWNTO 0); + SIGNAL out_bit_cnt : NATURAL RANGE 0 TO 7; -- 0-7, wraps after writing byte + SIGNAL out_byte_addr: NATURAL RANGE 0 TO ENCODED_BYTES-1; + + -- Encoder shift register (6 bits of history for K=7) + SIGNAL enc_sr : std_logic_vector(5 DOWNTO 0); + + -- Parallel output buffer + SIGNAL out_buf : std_logic_vector(ENCODED_BYTES*8-1 DOWNTO 0); + +BEGIN + + PROCESS(clk, aresetn) + VARIABLE curr_bit : std_logic; + VARIABLE g1, g2 : std_logic; + VARIABLE enc_state : std_logic_vector(6 DOWNTO 0); + VARIABLE new_accum : std_logic_vector(7 DOWNTO 0); + BEGIN + IF aresetn = '0' THEN + state <= IDLE; + busy <= '0'; + done <= '0'; + byte_cnt <= 0; + in_byte_addr <= 0; + in_bit_pos <= 0; + total_in_bits <= 0; + in_byte_reg <= (OTHERS => '0'); + out_accum <= (OTHERS => '0'); + out_bit_cnt <= 0; + out_byte_addr <= 0; + enc_sr <= (OTHERS => '0'); + out_buf <= (OTHERS => '0'); + + ELSIF rising_edge(clk) THEN + done <= '0'; + + CASE state IS + + ------------------------------------------------------------------------- + -- IDLE: Wait for start signal + ------------------------------------------------------------------------- + WHEN IDLE => + busy <= '0'; + IF start = '1' THEN + state <= LOAD_INPUT; + busy <= '1'; + byte_cnt <= 0; + END IF; + + ------------------------------------------------------------------------- + -- LOAD_INPUT: Sequential load from parallel input into BRAM + -- This takes PAYLOAD_BYTES cycles but eliminates the giant mux + ------------------------------------------------------------------------- + WHEN LOAD_INPUT => + IF byte_cnt < PAYLOAD_BYTES THEN + -- Byte 0 of input_buffer is MSB (bits 1071:1064) + input_ram(byte_cnt) <= input_buffer( + (PAYLOAD_BYTES - byte_cnt) * 8 - 1 DOWNTO + (PAYLOAD_BYTES - byte_cnt - 1) * 8 + ); + byte_cnt <= byte_cnt + 1; + ELSE + -- Done loading, initialize encoding + state <= ENCODE; + in_byte_addr <= 0; + in_bit_pos <= 0; + total_in_bits <= 0; + out_accum <= (OTHERS => '0'); + out_bit_cnt <= 0; + out_byte_addr <= 0; + enc_sr <= (OTHERS => '0'); + -- Pre-load first byte + in_byte_reg <= input_ram(0); + END IF; + + ------------------------------------------------------------------------- + -- ENCODE: Process one input bit per clock, output two encoded bits + -- Every 4 input bits produces 8 output bits (one byte) + ------------------------------------------------------------------------- + WHEN ENCODE => + IF total_in_bits < PAYLOAD_BYTES * 8 THEN + -- Extract current input bit (MSB first within each byte) + curr_bit := in_byte_reg(7 - in_bit_pos); + + -- Compute encoded outputs + enc_state := curr_bit & enc_sr; + -- G1 polynomial: 1111001 (octal 171) + g1 := enc_state(6) XOR enc_state(5) XOR enc_state(4) XOR + enc_state(3) XOR enc_state(0); + -- G2 polynomial: 1011011 (octal 133) + g2 := enc_state(6) XOR enc_state(4) XOR enc_state(3) XOR + enc_state(1) XOR enc_state(0); + + -- Update encoder shift register + enc_sr <= enc_sr(4 DOWNTO 0) & curr_bit; + + -- Accumulate output bits (MSB first: g1 then g2) + -- Shift left by 2, insert g1 and g2 at LSBs + new_accum := out_accum(5 DOWNTO 0) & g1 & g2; + out_accum <= new_accum; + + -- Every 4 input bits (8 output bits), write to output BRAM + IF out_bit_cnt = 6 THEN -- After this we'll have 8 bits + output_ram(out_byte_addr) <= new_accum; + out_byte_addr <= out_byte_addr + 1; + out_bit_cnt <= 0; + out_accum <= (OTHERS => '0'); + ELSE + out_bit_cnt <= out_bit_cnt + 2; + END IF; + + -- Advance to next input bit + IF in_bit_pos = 7 THEN + -- Move to next input byte + in_bit_pos <= 0; + IF in_byte_addr < PAYLOAD_BYTES - 1 THEN + in_byte_addr <= in_byte_addr + 1; + in_byte_reg <= input_ram(in_byte_addr + 1); + END IF; + ELSE + in_bit_pos <= in_bit_pos + 1; + END IF; + + total_in_bits <= total_in_bits + 1; + + ELSE + -- Encoding complete + state <= UNLOAD_OUTPUT; + byte_cnt <= 0; + END IF; + + ------------------------------------------------------------------------- + -- UNLOAD_OUTPUT: Sequential read from BRAM to parallel output + ------------------------------------------------------------------------- + WHEN UNLOAD_OUTPUT => + IF byte_cnt < ENCODED_BYTES THEN + out_buf( + (ENCODED_BYTES - byte_cnt) * 8 - 1 DOWNTO + (ENCODED_BYTES - byte_cnt - 1) * 8 + ) <= output_ram(byte_cnt); + byte_cnt <= byte_cnt + 1; + ELSE + state <= COMPLETE; + END IF; + + ------------------------------------------------------------------------- + -- COMPLETE: Assert done for one cycle + ------------------------------------------------------------------------- + WHEN COMPLETE => + done <= '1'; + busy <= '0'; + state <= IDLE; + + END CASE; + END IF; + END PROCESS; + + output_buffer <= out_buf; + +END ARCHITECTURE rtl; diff --git a/src/data_capture.vhd b/src/data_capture.vhd new file mode 100644 index 0000000..71a3bc8 --- /dev/null +++ b/src/data_capture.vhd @@ -0,0 +1,102 @@ +------------------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------ +-- _______ ________ ______ +-- __ __ \________ _____ _______ ___ __ \_____ _____________ ______ ___________________ /_ +-- _ / / /___ __ \_ _ \__ __ \ __ /_/ /_ _ \__ ___/_ _ \_ __ `/__ ___/_ ___/__ __ \ +-- / /_/ / __ /_/ // __/_ / / / _ _, _/ / __/_(__ ) / __// /_/ / _ / / /__ _ / / / +-- \____/ _ .___/ \___/ /_/ /_/ /_/ |_| \___/ /____/ \___/ \__,_/ /_/ \___/ /_/ /_/ +-- /_/ +-- ________ _____ _____ _____ _____ +-- ____ _/_______ __________ /____(_)__ /_____ ____ /______ +-- __ / __ __ \__ ___/_ __/__ / _ __/_ / / /_ __/_ _ \ +-- __/ / _ / / /_(__ ) / /_ _ / / /_ / /_/ / / /_ / __/ +-- /___/ /_/ /_/ /____/ \__/ /_/ \__/ \__,_/ \__/ \___/ +-- +------------------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------ +-- Copyright +------------------------------------------------------------------------------------------------------ +-- +-- Copyright 2025 by M. Wishek +-- +------------------------------------------------------------------------------------------------------ +-- License +------------------------------------------------------------------------------------------------------ +-- +-- This source describes Open Hardware and is licensed under the CERN-OHL-W v2. +-- +-- You may redistribute and modify this source and make products using it under +-- the terms of the CERN-OHL-W v2 (https://ohwr.org/cern_ohl_w_v2.txt). +-- +-- This source is distributed WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING +-- OF MERCHANTABILITY, SATISFACTORY QUALITY AND FITNESS FOR A PARTICULAR PURPOSE. +-- Please see the CERN-OHL-W v2 for applicable conditions. +-- +-- Source location: TBD +-- +-- As per CERN-OHL-W v2 section 4.1, should You produce hardware based on this +-- source, You must maintain the Source Location visible on the external case of +-- the products you make using this source. +-- +------------------------------------------------------------------------------------------------------ +-- Block name and description +------------------------------------------------------------------------------------------------------ +-- +-- This is a wrapper block for the register module generated by DesyRDL. +-- +-- Documentation location: TBD +-- +------------------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------ + + +------------------------------------------------------------------------------------------------------ +-- ╦ ┬┌┐ ┬─┐┌─┐┬─┐┬┌─┐┌─┐ +-- ║ │├┴┐├┬┘├─┤├┬┘│├┤ └─┐ +-- ╩═╝┴└─┘┴└─┴ ┴┴└─┴└─┘└─┘ +------------------------------------------------------------------------------------------------------ +-- Libraries + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +------------------------------------------------------------------------------------------------------ +-- ╔═╗┌┐┌┌┬┐┬┌┬┐┬ ┬ +-- ║╣ │││ │ │ │ └┬┘ +-- ╚═╝┘└┘ ┴ ┴ ┴ ┴ +------------------------------------------------------------------------------------------------------ +-- Entity + +ENTITY data_capture IS + GENERIC ( + data_width : natural := 32 + ); + PORT ( + clk : IN std_logic; + sync_reset : IN std_logic; + + capture : IN std_logic; + + di : IN std_logic_vector(data_width -1 DOWNTO 0); + do : OUT std_logic_vector(data_width -1 DOWNTO 0) + ); +END ENTITY data_capture; + +ARCHITECTURE rtl OF data_capture IS +BEGIN + + capture_proc : PROCESS (clk) + BEGIN + IF clk'EVENT AND clk = '1' THEN + IF sync_reset = '1' THEN + do <= (OTHERS => '0'); + ELSIF capture = '1' THEN + do <= di; + END IF; + END IF; + END PROCESS capture_proc; + +END ARCHITECTURE rtl; + + diff --git a/src/frame_sync_detector.vhd b/src/frame_sync_detector.vhd index a346a49..4581af8 100644 --- a/src/frame_sync_detector.vhd +++ b/src/frame_sync_detector.vhd @@ -1,16 +1,26 @@ ------------------------------------------------------------------------------------------------------ --- Frame Sync Detector with Frame Tracking and Flywheel - IMPROVED VERSION +-- Frame Sync Detector with Correlator (Soft Decision) ------------------------------------------------------------------------------------------------------ --- IMPROVEMENTS OVER ORIGINAL: +-- UPGRADE FROM HAMMING DISTANCE TO CORRELATION: +-- Instead of counting bit mismatches (hard decision), we now compute: +-- correlation = ?(soft_sample[i] × sync_bipolar[i]) +-- Where sync_bipolar[i] = +1 if SYNC_WORD bit is '1', -1 if '0' +-- +-- This preserves confidence information from the demodulator, giving us: +-- - Better detection at low SNR +-- - Full benefit of optimized PSLR sync word +-- - Sharp correlation peak with suppressed sidelobes +------------------------------------------------------------------------------------------------------ +-- FEATURES: -- 1. Frame Tracking: Knows exactly where to expect next sync word -- 2. Flywheel: Tolerates missed syncs during brief interference (stays locked) -- 3. Adaptive Threshold: Stricter when hunting, more relaxed when locked -- 4. Better lock management: Distinguishes between acquiring lock vs maintaining lock +-- 5. NEW: Correlation-based detection using soft decisions ------------------------------------------------------------------------------------------------------ --- Based on original by Open Research Institute --- Enhanced with robust sync tracking for low-SNR operation +-- by Open Research Institute +-- Enhanced with soft-decision correlation for improved sync detection ------------------------------------------------------------------------------------------------------ - LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; @@ -18,14 +28,37 @@ USE ieee.numeric_std.ALL; ENTITY frame_sync_detector IS GENERIC ( - SYNC_WORD : std_logic_vector(23 DOWNTO 0) := x"02B8DB"; -- MSB-first sync word (CORRECTED) + -- Sync word: 0x02B8DB (24 bits, MSB-first) + SYNC_WORD : std_logic_vector(23 DOWNTO 0) := x"02B8DB"; PAYLOAD_BYTES : NATURAL := 268; - -- Threshold when hunting for initial sync (conservative) - HUNTING_THRESHOLD : NATURAL := 3; - - -- Threshold when locked (more tolerant to maintain lock) - LOCKED_THRESHOLD : NATURAL := 5; + ------------------------------------------------------------------------ + -- Correlation Threshold Tuning Guide + ------------------------------------------------------------------------ + -- The soft input (s_axis_soft_tdata) comes from msk_demodulator.rx_data_soft + -- which is data_f1_sum - data_f2_sum (16-bit signed). + -- + -- Typical soft values depend on: + -- - ADC input level and scaling + -- - Costas loop gain settings + -- - Integration period + -- + -- CALIBRATION PROCEDURE: + -- 1. Connect debug_correlation to a register or ILA + -- 2. Transmit known sync words and observe peak correlation + -- 3. Set HUNTING_THRESHOLD ? 70-80% of observed peak + -- 4. Set LOCKED_THRESHOLD ? 40-50% of observed peak (flywheel mode) + -- + -- EXAMPLE: If soft values are ±4000 nominal at good SNR: + -- Peak correlation ? 24 × 4000 = 96,000 + -- HUNTING_THRESHOLD ? 72,000 (75%) + -- LOCKED_THRESHOLD ? 48,000 (50%) + -- + -- Conservative starting values (adjust after measurement): + -- Start moderate - observe debug_corr_peak and adjust + HUNTING_THRESHOLD : INTEGER := 10000; -- Moderate for initial testing + LOCKED_THRESHOLD : INTEGER := 5000; -- More tolerant when locked + ------------------------------------------------------------------------ -- How many consecutive missed syncs before declaring lock lost FLYWHEEL_TOLERANCE : NATURAL := 2; @@ -39,9 +72,24 @@ ENTITY frame_sync_detector IS clk : IN std_logic; reset : IN std_logic; - -- BIT Input Interface + -- BIT Input Interface (hard decision, still used for byte assembly) rx_bit : IN std_logic; rx_bit_valid : IN std_logic; + + ------------------------------------------------------------------------ + -- Soft Decision Interface + ------------------------------------------------------------------------ + -- s_axis_soft_tdata must be SYNCHRONOUS with rx_bit_valid! + -- Both signals come from msk_demodulator: + -- rx_bit ? rx_data (hard decision) + -- rx_bit_valid ? rx_dvalid (symbol strobe) + -- s_axis_soft ? rx_data_soft (16-bit soft metric) + -- + -- Polarity: Positive = likely '1', Negative = likely '0' + -- Magnitude = confidence (larger |value| = stronger decision) + ------------------------------------------------------------------------ + s_axis_soft_tdata : IN signed(15 DOWNTO 0); -- Soft decision input + m_axis_soft_tdata : OUT signed(15 DOWNTO 0); -- Soft decision passthrough -- AXIS Master Interface (to FIFO) m_axis_tdata : OUT std_logic_vector(7 DOWNTO 0); @@ -53,22 +101,37 @@ ENTITY frame_sync_detector IS frame_sync_locked : OUT std_logic; frames_received : OUT std_logic_vector(31 DOWNTO 0); frame_sync_errors : OUT std_logic_vector(31 DOWNTO 0); - buffer_overflow : OUT std_logic; + frame_buffer_overflow : OUT std_logic; - -- Debug outputs (optional, helpful for monitoring) + -- Debug outputs debug_state : OUT std_logic_vector(2 DOWNTO 0); debug_missed_syncs : OUT std_logic_vector(3 DOWNTO 0); - debug_consecutive_good: OUT std_logic_vector(3 DOWNTO 0) - + debug_consecutive_good: OUT std_logic_vector(3 DOWNTO 0); + + -- Correlation debug outputs (useful for threshold tuning) + debug_correlation : OUT signed(31 DOWNTO 0); -- Current correlation + debug_corr_peak : OUT signed(31 DOWNTO 0); -- Peak correlation seen (for calibration) + + -- Additional debug for troubleshooting + debug_soft_current : OUT signed(15 DOWNTO 0); -- Current soft input value + debug_bit_count : OUT std_logic_vector(31 DOWNTO 0) -- Total bits received ); END ENTITY frame_sync_detector; ARCHITECTURE rtl OF frame_sync_detector IS - -- Bit-level sync detection (MSB shifts in from left) - SIGNAL sync_shift_bits : std_logic_vector(23 DOWNTO 0) := (OTHERS => '0'); - SIGNAL sync_bit_count : unsigned(4 DOWNTO 0) := (OTHERS => '0'); -- Counts 0-23 + ---------------------------------------------------------------------------- + -- Soft Decision Shift Register for Correlation + ---------------------------------------------------------------------------- + -- We maintain 24 soft samples (one per sync word bit) + -- Each sample is 16-bit signed from the demodulator + TYPE soft_shift_array_t IS ARRAY(0 TO 23) OF signed(15 DOWNTO 0); + SIGNAL soft_shift_reg : soft_shift_array_t; + + -- Bit-level shift for hard decisions (still needed for byte assembly) + SIGNAL sync_shift_bits : std_logic_vector(23 DOWNTO 0); + SIGNAL sync_bit_count : unsigned(4 DOWNTO 0); -- Counts 0-23 -- Byte assembly for output (MSB shifts in from left) SIGNAL byte_shift_reg : std_logic_vector(7 DOWNTO 0); @@ -78,12 +141,11 @@ ARCHITECTURE rtl OF frame_sync_detector IS CONSTANT BUFFER_SIZE : NATURAL := 2**BUFFER_DEPTH; TYPE byte_buffer_t IS ARRAY(0 TO BUFFER_SIZE-1) OF std_logic_vector(7 DOWNTO 0); SIGNAL circ_buffer : byte_buffer_t; - -- Force Block RAM usage for circular buffer ATTRIBUTE ram_style : STRING; ATTRIBUTE ram_style OF circ_buffer : SIGNAL IS "block"; - SIGNAL wr_ptr : unsigned(BUFFER_DEPTH-1 DOWNTO 0) := (OTHERS => '0'); - SIGNAL rd_ptr : unsigned(BUFFER_DEPTH-1 DOWNTO 0) := (OTHERS => '0'); + SIGNAL wr_ptr : unsigned(BUFFER_DEPTH-1 DOWNTO 0); + SIGNAL rd_ptr : unsigned(BUFFER_DEPTH-1 DOWNTO 0); -- Enhanced state machine TYPE state_t IS (HUNTING, LOCKED, VERIFYING_SYNC); @@ -92,36 +154,92 @@ ARCHITECTURE rtl OF frame_sync_detector IS -- Frame tracking SIGNAL frame_start_ptr : unsigned(BUFFER_DEPTH-1 DOWNTO 0); SIGNAL frame_byte_count : natural range 0 to PAYLOAD_BYTES; - SIGNAL frames_count : unsigned(31 DOWNTO 0) := (OTHERS => '0'); - SIGNAL errors_count : unsigned(31 DOWNTO 0) := (OTHERS => '0'); - SIGNAL consecutive_good : natural range 0 to LOCK_FRAMES := 0; - SIGNAL missed_sync_count : natural range 0 to FLYWHEEL_TOLERANCE := 0; + SIGNAL frames_count : unsigned(31 DOWNTO 0); + SIGNAL errors_count : unsigned(31 DOWNTO 0); + SIGNAL consecutive_good : natural range 0 to LOCK_FRAMES; + SIGNAL missed_sync_count : natural range 0 to FLYWHEEL_TOLERANCE; + SIGNAL lock_status : std_logic := '0'; - SIGNAL acquiring_lock : std_logic := '0'; -- True during initial lock acquisition + SIGNAL acquiring_lock : std_logic := '0'; - -- Handshake signals SIGNAL frame_ready : std_logic := '0'; SIGNAL frame_ack : std_logic := '0'; - SIGNAL frame_rd_ptr : unsigned(BUFFER_DEPTH-1 DOWNTO 0) := (OTHERS => '0'); + SIGNAL frame_rd_ptr : unsigned(BUFFER_DEPTH-1 DOWNTO 0); SIGNAL output_active : std_logic := '0'; - SIGNAL output_count : natural range 0 to PAYLOAD_BYTES := 0; + SIGNAL output_count : natural range 0 to PAYLOAD_BYTES; SIGNAL tvalid_int : std_logic := '0'; SIGNAL tlast_int : std_logic := '0'; - -- Hamming distance calculator - FUNCTION calc_hamming_distance( - pattern1 : std_logic_vector; - pattern2 : std_logic_vector - ) RETURN natural IS - VARIABLE distance : natural := 0; + -- Current correlation value (updated each bit) + SIGNAL correlation_value : signed(31 DOWNTO 0); + + -- Peak correlation tracker (for threshold calibration) + -- Readable via debug output, cleared on reset + SIGNAL correlation_peak : signed(31 DOWNTO 0); + + -- Debug: count total bits received (to verify data is flowing) + SIGNAL debug_bits_received : unsigned(31 DOWNTO 0); + + ---------------------------------------------------------------------------- + -- Correlation Calculator + -- Returns: ?(soft_sample[i] × bipolar_coeff[i]) for i = 0..23 + -- + -- IMPORTANT: VHDL signal assignments don't take effect until process ends, + -- so we pass the NEW sample explicitly. The function calculates correlation + -- "as if" the shift had already happened: + -- Position 0 = new_sample (just arrived, corresponds to SYNC_WORD bit 0) + -- Position 1 = soft_samples(0) (corresponds to SYNC_WORD bit 1) + -- Position 2 = soft_samples(1) (corresponds to SYNC_WORD bit 2) + -- ... etc + -- Position 23 = soft_samples(22) (corresponds to SYNC_WORD bit 23) + -- + -- MSB-FIRST TRANSMISSION: + -- SYNC_WORD(23) is transmitted FIRST, shifts to position 23 + -- SYNC_WORD(0) is transmitted LAST, arrives at position 0 + -- So shift register position i corresponds to SYNC_WORD(i) + -- + -- POLARITY (from msk_demodulator): + -- NEGATIVE soft value ? '1' bit + -- POSITIVE soft value ? '0' bit + -- + -- For correlation: + -- When SYNC bit = '1': we WANT negative soft ? SUBTRACT (negative becomes positive) + -- When SYNC bit = '0': we WANT positive soft ? ADD (positive stays positive) + ---------------------------------------------------------------------------- + FUNCTION calc_correlation( + soft_samples : soft_shift_array_t; + new_sample : signed(15 DOWNTO 0) + ) RETURN signed IS + VARIABLE sum : signed(31 DOWNTO 0) := (OTHERS => '0'); + VARIABLE sample : signed(15 DOWNTO 0); BEGIN - FOR i IN pattern1'RANGE LOOP - IF pattern1(i) /= pattern2(i) THEN - distance := distance + 1; + FOR i IN 0 TO 23 LOOP + -- Get the appropriate sample (accounting for pending shift) + IF i = 0 THEN + sample := new_sample; + ELSE + sample := soft_samples(i - 1); + END IF; + + -- Add or subtract based on expected sync word bit + -- Position i in shift register corresponds to SYNC_WORD(i) + -- (MSB transmitted first, shifts to high positions) + -- + -- After differential decoding in demodulator: + -- Positive soft ? decoded hard bit '0' + -- Negative soft ? decoded hard bit '1' + -- + -- For correlation: + -- When SYNC bit = '1': expect negative soft ? SUBTRACT (neg becomes pos contribution) + -- When SYNC bit = '0': expect positive soft ? ADD (pos stays pos contribution) + IF SYNC_WORD(i) = '1' THEN + sum := sum - resize(sample, 32); -- Expect negative soft + ELSE + sum := sum + resize(sample, 32); -- Expect positive soft END IF; END LOOP; - RETURN distance; + RETURN sum; END FUNCTION; BEGIN @@ -132,6 +250,9 @@ BEGIN m_axis_tvalid <= tvalid_int; m_axis_tlast <= tlast_int; + -- Passthrough soft decisions (for downstream use) + m_axis_soft_tdata <= s_axis_soft_tdata; + -- Debug outputs WITH state SELECT debug_state <= "001" WHEN HUNTING, @@ -141,17 +262,26 @@ BEGIN debug_missed_syncs <= std_logic_vector(to_unsigned(missed_sync_count, 4)); debug_consecutive_good <= std_logic_vector(to_unsigned(consecutive_good, 4)); + debug_correlation <= correlation_value; + debug_corr_peak <= correlation_peak; + debug_soft_current <= s_axis_soft_tdata; -- See what soft values look like + debug_bit_count <= std_logic_vector(debug_bits_received); -- Verify bits flowing ------------------------------------------------------------------------------ - -- Main Process: Frame Tracking with Flywheel + -- Main Process: Frame Tracking with Flywheel (Correlator Version) ------------------------------------------------------------------------------ reception_proc: PROCESS(clk) - VARIABLE hamming_dist : natural range 0 to 24; + VARIABLE corr_result : signed(31 DOWNTO 0); VARIABLE assembled_byte : std_logic_vector(7 DOWNTO 0); - VARIABLE threshold_to_use : natural range 0 to 24; + VARIABLE threshold_to_use : integer; BEGIN IF rising_edge(clk) THEN IF reset = '1' THEN + -- Initialize soft shift register + FOR i IN 0 TO 23 LOOP + soft_shift_reg(i) <= (OTHERS => '0'); + END LOOP; + sync_shift_bits <= (OTHERS => '0'); sync_bit_count <= (OTHERS => '0'); byte_shift_reg <= (OTHERS => '0'); @@ -160,25 +290,39 @@ BEGIN state <= HUNTING; frame_start_ptr <= (OTHERS => '0'); frame_byte_count <= 0; + frames_count <= (OTHERS => '0'); + errors_count <= (OTHERS => '0'); consecutive_good <= 0; missed_sync_count <= 0; lock_status <= '0'; acquiring_lock <= '0'; frame_ready <= '0'; frame_rd_ptr <= (OTHERS => '0'); - buffer_overflow <= '0'; + frame_buffer_overflow <= '0'; + correlation_value <= (OTHERS => '0'); + correlation_peak <= (OTHERS => '0'); -- Clear peak on reset + debug_bits_received <= (OTHERS => '0'); -- Clear bit counter ELSE - buffer_overflow <= '0'; + frame_buffer_overflow <= '0'; -- Clear frame_ready when acknowledged IF frame_ack = '1' THEN frame_ready <= '0'; END IF; - -- Always shift in new bits to both registers + -- Always shift in new samples when valid IF rx_bit_valid = '1' THEN - -- MSB-FIRST: Shift LEFT so first bit ends up at position 23 + -- Count bits for debug (verify data is flowing!) + debug_bits_received <= debug_bits_received + 1; + + -- Shift soft samples (newest at position 0, oldest at 23) + FOR i IN 23 DOWNTO 1 LOOP + soft_shift_reg(i) <= soft_shift_reg(i-1); + END LOOP; + soft_shift_reg(0) <= s_axis_soft_tdata; + + -- Also shift hard decision bits (for byte assembly) sync_shift_bits <= sync_shift_bits(22 DOWNTO 0) & rx_bit; byte_shift_reg <= byte_shift_reg(6 DOWNTO 0) & rx_bit; END IF; @@ -186,26 +330,32 @@ BEGIN -- State machine CASE state IS ------------------------------------------------------ - -- HUNTING: Looking for initial sync + -- HUNTING: Looking for initial sync using correlation ------------------------------------------------------ WHEN HUNTING => - acquiring_lock <= '1'; -- We're trying to acquire lock + acquiring_lock <= '1'; IF rx_bit_valid = '1' THEN + -- Calculate correlation including the new sample + -- (signal assignments pending, so we pass new sample explicitly) + corr_result := calc_correlation(soft_shift_reg, s_axis_soft_tdata); + correlation_value <= corr_result; + + -- Track peak correlation for threshold calibration + IF corr_result > correlation_peak THEN + correlation_peak <= corr_result; + END IF; + -- Use conservative threshold when hunting threshold_to_use := HUNTING_THRESHOLD; - hamming_dist := calc_hamming_distance( - sync_shift_bits, - SYNC_WORD - ); - - IF hamming_dist <= threshold_to_use THEN + -- Check if correlation exceeds threshold + IF corr_result >= to_signed(threshold_to_use, 32) THEN -- Found potential sync! frame_byte_count <= 0; bit_count <= (OTHERS => '0'); sync_bit_count <= (OTHERS => '0'); - frame_start_ptr <= wr_ptr; -- AI!!! ADD THIS LINE! + frame_start_ptr <= wr_ptr; state <= LOCKED; -- Track consecutive good detections @@ -226,18 +376,19 @@ BEGIN WHEN LOCKED => IF rx_bit_valid = '1' THEN bit_count <= bit_count + 1; - --sync_bit_count <= sync_bit_count + 1; --AI!!! only increment in VERIFYING_SYNC IF bit_count = 7 THEN -- Byte complete (MSB-first assembly) - assembled_byte := byte_shift_reg; + -- NOTE: byte_shift_reg hasn't been updated yet (signal assignment pending) + -- so we must manually include the current rx_bit + assembled_byte := byte_shift_reg(6 DOWNTO 0) & rx_bit; -- Write to circular buffer circ_buffer(to_integer(wr_ptr)) <= assembled_byte; wr_ptr <= wr_ptr + 1; IF wr_ptr + 1 = rd_ptr THEN - buffer_overflow <= '1'; + frame_buffer_overflow <= '1'; errors_count <= errors_count + 1; END IF; @@ -247,7 +398,6 @@ BEGIN frame_byte_count <= frame_byte_count + 1; ELSE -- Frame payload complete - -- Signal frame is ready for output IF frame_ready = '0' THEN frame_ready <= '1'; frame_rd_ptr <= frame_start_ptr; @@ -258,73 +408,64 @@ BEGIN END IF; frame_byte_count <= 0; - - -- Now expect next sync word state <= VERIFYING_SYNC; sync_bit_count <= (OTHERS => '0'); - --sync_bit_count <= (OTHERS => '0'); --AI!!! run continuously without resets END IF; END IF; END IF; ------------------------------------------------------ - -- VERIFYING_SYNC: Check for next sync at expected position + -- VERIFYING_SYNC: Check for next sync using correlation ------------------------------------------------------ WHEN VERIFYING_SYNC => IF rx_bit_valid = '1' THEN sync_bit_count <= sync_bit_count + 1; - -- After collecting 24 bits, verify it's a sync word + -- After collecting 24 bits, verify via correlation IF sync_bit_count = 23 THEN + -- Calculate correlation (include new sample in calculation) + corr_result := calc_correlation(soft_shift_reg, s_axis_soft_tdata); + correlation_value <= corr_result; + + -- Track peak correlation for threshold calibration + IF corr_result > correlation_peak THEN + correlation_peak <= corr_result; + END IF; + -- Choose threshold based on lock status IF lock_status = '1' THEN - -- Already locked: use relaxed threshold (flywheel) threshold_to_use := LOCKED_THRESHOLD; ELSE - -- Still acquiring lock: use strict threshold threshold_to_use := HUNTING_THRESHOLD; END IF; - hamming_dist := calc_hamming_distance( - sync_shift_bits, - SYNC_WORD - ); - - IF hamming_dist <= threshold_to_use THEN - -- Good! Next sync found where expected + IF corr_result >= to_signed(threshold_to_use, 32) THEN + -- Good! Sync found where expected missed_sync_count <= 0; IF acquiring_lock = '1' THEN - -- Still building confidence IF consecutive_good < LOCK_FRAMES - 1 THEN consecutive_good <= consecutive_good + 1; ELSE - -- Achieved stable lock lock_status <= '1'; acquiring_lock <= '0'; consecutive_good <= LOCK_FRAMES; END IF; ELSE - -- Already locked, maintain it consecutive_good <= LOCK_FRAMES; END IF; - -- Continue with next frame state <= LOCKED; bit_count <= (OTHERS => '0'); - frame_start_ptr <= wr_ptr; -- AI!!! ADD THIS LINE! + frame_start_ptr <= wr_ptr; ELSE -- Missed expected sync! IF lock_status = '1' THEN - -- We're locked: use flywheel tolerance IF missed_sync_count < FLYWHEEL_TOLERANCE THEN - -- Tolerate this miss, keep going missed_sync_count <= missed_sync_count + 1; state <= LOCKED; bit_count <= (OTHERS => '0'); - - -- Note the error but stay locked errors_count <= errors_count + 1; ELSE -- Too many misses, lost lock @@ -335,15 +476,12 @@ BEGIN errors_count <= errors_count + 1; END IF; ELSE - -- Still acquiring lock: any miss sends us back to hunting + -- Still acquiring lock: any miss sends us back consecutive_good <= 0; state <= HUNTING; errors_count <= errors_count + 1; END IF; END IF; - ELSE - -- Still collecting sync bits, stay in this state - NULL; END IF; END IF; @@ -351,12 +489,12 @@ BEGIN state <= HUNTING; END CASE; - END IF; -- End of ELSE for reset - END IF; -- End of rising_edge(clk) + END IF; + END IF; END PROCESS reception_proc; ------------------------------------------------------------------------------ - -- Output Process: Stream bytes to AXIS interface + -- Output Process: Stream bytes to AXIS interface (unchanged) ------------------------------------------------------------------------------ output_proc: PROCESS(clk) BEGIN @@ -371,18 +509,15 @@ BEGIN rd_ptr <= (OTHERS => '0'); ELSE - -- Default: no ack frame_ack <= '0'; - -- Check if new frame is ready IF frame_ready = '1' AND output_active = '0' THEN output_active <= '1'; rd_ptr <= frame_rd_ptr; output_count <= 0; - frame_ack <= '1'; -- Acknowledge we took the frame + frame_ack <= '1'; END IF; - -- Output state machine IF output_active = '1' THEN IF m_axis_tready = '1' OR tvalid_int = '0' THEN m_axis_tdata <= circ_buffer(to_integer(rd_ptr)); diff --git a/src/frame_sync_detector_soft.vhd b/src/frame_sync_detector_soft.vhd new file mode 100644 index 0000000..e365207 --- /dev/null +++ b/src/frame_sync_detector_soft.vhd @@ -0,0 +1,713 @@ +------------------------------------------------------------------------------------------------------ +-- Frame Sync Detector with Soft Decision Support (frame_sync_detector_soft.vhd) +------------------------------------------------------------------------------------------------------ +-- +-- This is a variant of frame_sync_detector.vhd that additionally buffers quantized +-- soft decision values for the downstream soft Viterbi decoder. +-- +------------------------------------------------------------------------------------------------------ +-- SOFT DECISION CORRELATION (from original frame_sync_detector): +-- Instead of counting bit mismatches (hard decision), we compute: +-- correlation = ?(soft_sample[i] × sync_bipolar[i]) +-- Where sync_bipolar[i] = +1 if SYNC_WORD bit is '1', -1 if '0' +-- +-- This preserves confidence information from the demodulator, giving us: +-- - Better detection at low SNR +-- - Full benefit of optimized PSLR sync word +-- - Sharp correlation peak with suppressed sidelobes +------------------------------------------------------------------------------------------------------ +-- SOFT VITERBI INTEGRATION (NEW in this variant): +-- +-- In addition to the byte stream output (m_axis_*), this module outputs a +-- stream of 3-bit quantized soft values (m_axis_soft_bit_*) for use by the +-- soft Viterbi decoder in ov_frame_decoder_soft. +-- +-- Data flow: +-- 1. As each bit arrives during LOCKED state, we: +-- a. Assemble bytes as usual (for m_axis output) +-- b. Quantize the 16-bit soft value to 3 bits and store in soft_frame_buffer +-- +-- 2. When frame is complete (268 bytes = 2144 bits): +-- a. Output 268 bytes via m_axis_* interface +-- b. Then output 2144 3-bit soft values via m_axis_soft_bit_* interface +-- +-- 3. The downstream ov_frame_decoder_soft receives both streams: +-- - Bytes for hard decision path (backwards compatibility) +-- - Soft values for soft Viterbi decoder (~2-3 dB coding gain) +-- +------------------------------------------------------------------------------------------------------ +-- FEATURES: +-- 1. Frame Tracking: Knows exactly where to expect next sync word +-- 2. Flywheel: Tolerates missed syncs during brief interference (stays locked) +-- 3. Adaptive Threshold: Stricter when hunting, more relaxed when locked +-- 4. Better lock management: Distinguishes between acquiring lock vs maintaining lock +-- 5. Correlation-based detection using soft decisions +-- 6. NEW: Soft value buffering and streaming for soft Viterbi decoder +------------------------------------------------------------------------------------------------------ +-- by Open Research Institute +-- Enhanced with soft-decision correlation and soft Viterbi support +------------------------------------------------------------------------------------------------------ +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + + +ENTITY frame_sync_detector_soft IS + GENERIC ( + -- Sync word: 0x02B8DB (24 bits, MSB-first) + SYNC_WORD : std_logic_vector(23 DOWNTO 0) := x"02B8DB"; + PAYLOAD_BYTES : NATURAL := 268; + + ------------------------------------------------------------------------ + -- Correlation Threshold Tuning Guide + ------------------------------------------------------------------------ + -- The soft input (s_axis_soft_tdata) comes from msk_demodulator.rx_data_soft + -- which is data_f1_sum - data_f2_sum (16-bit signed). + -- + -- Typical soft values depend on: + -- - ADC input level and scaling + -- - Costas loop gain settings + -- - Integration period + -- + -- CALIBRATION PROCEDURE: + -- 1. Connect debug_correlation to a register or ILA + -- 2. Transmit known sync words and observe peak correlation + -- 3. Set HUNTING_THRESHOLD ? 70-80% of observed peak + -- 4. Set LOCKED_THRESHOLD ? 40-50% of observed peak (flywheel mode) + -- + -- EXAMPLE: If soft values are ±4000 nominal at good SNR: + -- Peak correlation ? 24 × 4000 = 96,000 + -- HUNTING_THRESHOLD ? 72,000 (75%) + -- LOCKED_THRESHOLD ? 48,000 (50%) + -- + -- Conservative starting values (adjust after measurement): + -- Start moderate - observe debug_corr_peak and adjust + HUNTING_THRESHOLD : INTEGER := 10000; -- Moderate for initial testing + LOCKED_THRESHOLD : INTEGER := 5000; -- More tolerant when locked + ------------------------------------------------------------------------ + + -- How many consecutive missed syncs before declaring lock lost + FLYWHEEL_TOLERANCE : NATURAL := 2; + + -- How many consecutive good frames needed to declare lock acquired + LOCK_FRAMES : NATURAL := 3; + + BUFFER_DEPTH : NATURAL := 11; + + -- Soft value width (3-bit quantization for Viterbi) + SOFT_WIDTH : NATURAL := 3 + ); + PORT ( + clk : IN std_logic; + reset : IN std_logic; + + -- BIT Input Interface (hard decision, still used for byte assembly) + rx_bit : IN std_logic; + rx_bit_valid : IN std_logic; + + ------------------------------------------------------------------------ + -- Soft Decision Interface + ------------------------------------------------------------------------ + -- s_axis_soft_tdata must be SYNCHRONOUS with rx_bit_valid! + -- Both signals come from msk_demodulator: + -- rx_bit ? rx_data (hard decision) + -- rx_bit_valid ? rx_dvalid (symbol strobe) + -- s_axis_soft ? rx_data_soft (16-bit soft metric) + -- + -- Polarity: Positive = likely '1', Negative = likely '0' + -- Magnitude = confidence (larger |value| = stronger decision) + ------------------------------------------------------------------------ + s_axis_soft_tdata : IN signed(15 DOWNTO 0); -- Soft decision input + m_axis_soft_tdata : OUT signed(15 DOWNTO 0); -- Soft decision passthrough + + -- AXIS Master Interface - Bytes (to decoder) + m_axis_tdata : OUT std_logic_vector(7 DOWNTO 0); + m_axis_tvalid : OUT std_logic; + m_axis_tready : IN std_logic; + m_axis_tlast : OUT std_logic; + + -- AXIS Master Interface - Soft bits (to decoder) + -- Outputs 2144 3-bit soft values AFTER the 268 bytes + m_axis_soft_bit_tdata : OUT std_logic_vector(SOFT_WIDTH-1 DOWNTO 0); + m_axis_soft_bit_tvalid : OUT std_logic; + m_axis_soft_bit_tready : IN std_logic; + m_axis_soft_bit_tlast : OUT std_logic; + + -- Status Outputs + frame_sync_locked : OUT std_logic; + frames_received : OUT std_logic_vector(31 DOWNTO 0); + frame_sync_errors : OUT std_logic_vector(31 DOWNTO 0); + frame_buffer_overflow : OUT std_logic; + + -- Debug outputs + debug_state : OUT std_logic_vector(2 DOWNTO 0); + debug_missed_syncs : OUT std_logic_vector(3 DOWNTO 0); + debug_consecutive_good: OUT std_logic_vector(3 DOWNTO 0); + + -- Correlation debug outputs (useful for threshold tuning) + debug_correlation : OUT signed(31 DOWNTO 0); -- Current correlation + debug_corr_peak : OUT signed(31 DOWNTO 0); -- Peak correlation seen (for calibration) + + -- Additional debug for troubleshooting + debug_soft_current : OUT signed(15 DOWNTO 0); -- Current soft input value + debug_bit_count : OUT std_logic_vector(31 DOWNTO 0) -- Total bits received + ); +END ENTITY frame_sync_detector_soft; + + +ARCHITECTURE rtl OF frame_sync_detector_soft IS + + ---------------------------------------------------------------------------- + -- Soft Decision Shift Register for Correlation + ---------------------------------------------------------------------------- + -- We maintain 24 soft samples (one per sync word bit) + -- Each sample is 16-bit signed from the demodulator + TYPE soft_shift_array_t IS ARRAY(0 TO 23) OF signed(15 DOWNTO 0); + SIGNAL soft_shift_reg : soft_shift_array_t; + + -- Bit-level shift for hard decisions (still needed for byte assembly) + SIGNAL sync_shift_bits : std_logic_vector(23 DOWNTO 0); + SIGNAL sync_bit_count : unsigned(4 DOWNTO 0); -- Counts 0-23 + + -- Byte assembly for output (MSB shifts in from left) + SIGNAL byte_shift_reg : std_logic_vector(7 DOWNTO 0); + SIGNAL bit_count : unsigned(2 DOWNTO 0); + + -- Circular buffer for BYTES (after sync found) + CONSTANT BUFFER_SIZE : NATURAL := 2**BUFFER_DEPTH; + TYPE byte_buffer_t IS ARRAY(0 TO BUFFER_SIZE-1) OF std_logic_vector(7 DOWNTO 0); + SIGNAL circ_buffer : byte_buffer_t; + ATTRIBUTE ram_style : STRING; + ATTRIBUTE ram_style OF circ_buffer : SIGNAL IS "block"; + + -- Soft frame buffer (one frame worth of quantized 3-bit soft values) + CONSTANT PAYLOAD_BITS : NATURAL := PAYLOAD_BYTES * 8; -- 2144 + TYPE soft_frame_buffer_t IS ARRAY(0 TO PAYLOAD_BITS-1) OF + std_logic_vector(SOFT_WIDTH-1 DOWNTO 0); + SIGNAL soft_frame_buffer : soft_frame_buffer_t; + SIGNAL frame_soft_idx : natural RANGE 0 TO PAYLOAD_BITS; + ATTRIBUTE ram_style OF soft_frame_buffer : SIGNAL IS "block"; + + SIGNAL wr_ptr : unsigned(BUFFER_DEPTH-1 DOWNTO 0); + SIGNAL rd_ptr : unsigned(BUFFER_DEPTH-1 DOWNTO 0); + + -- Enhanced state machine + TYPE state_t IS (HUNTING, LOCKED, VERIFYING_SYNC); + SIGNAL state : state_t := HUNTING; + + -- Frame tracking + SIGNAL frame_start_ptr : unsigned(BUFFER_DEPTH-1 DOWNTO 0); + SIGNAL frame_byte_count : natural range 0 to PAYLOAD_BYTES; + SIGNAL frames_count : unsigned(31 DOWNTO 0); + SIGNAL errors_count : unsigned(31 DOWNTO 0); + SIGNAL consecutive_good : natural range 0 to LOCK_FRAMES; + SIGNAL missed_sync_count : natural range 0 to FLYWHEEL_TOLERANCE; + + SIGNAL lock_status : std_logic := '0'; + SIGNAL acquiring_lock : std_logic := '0'; + + SIGNAL frame_ready : std_logic := '0'; + SIGNAL frame_ack : std_logic := '0'; + SIGNAL frame_rd_ptr : unsigned(BUFFER_DEPTH-1 DOWNTO 0); + + SIGNAL output_active : std_logic := '0'; + SIGNAL output_count : natural range 0 to PAYLOAD_BYTES; + SIGNAL tvalid_int : std_logic := '0'; + SIGNAL tlast_int : std_logic := '0'; + + -- Soft output signals + SIGNAL soft_output_active : std_logic := '0'; + SIGNAL soft_output_count : natural RANGE 0 TO PAYLOAD_BITS; + SIGNAL soft_tvalid_int : std_logic := '0'; + SIGNAL soft_tlast_int : std_logic := '0'; + + -- Current correlation value (updated each bit) + SIGNAL correlation_value : signed(31 DOWNTO 0); + + -- Peak correlation tracker (for threshold calibration) + -- Readable via debug output, cleared on reset + SIGNAL correlation_peak : signed(31 DOWNTO 0); + + -- Debug: count total bits received (to verify data is flowing) + SIGNAL debug_bits_received : unsigned(31 DOWNTO 0); + + ---------------------------------------------------------------------------- + -- Correlation Calculator + -- Returns: ?(soft_sample[i] × bipolar_coeff[i]) for i = 0..23 + -- + -- IMPORTANT: VHDL signal assignments don't take effect until process ends, + -- so we pass the NEW sample explicitly. The function calculates correlation + -- "as if" the shift had already happened: + -- Position 0 = new_sample (just arrived, corresponds to SYNC_WORD bit 0) + -- Position 1 = soft_samples(0) (corresponds to SYNC_WORD bit 1) + -- Position 2 = soft_samples(1) (corresponds to SYNC_WORD bit 2) + -- ... etc + -- Position 23 = soft_samples(22) (corresponds to SYNC_WORD bit 23) + -- + -- MSB-FIRST TRANSMISSION: + -- SYNC_WORD(23) is transmitted FIRST, shifts to position 23 + -- SYNC_WORD(0) is transmitted LAST, arrives at position 0 + -- So shift register position i corresponds to SYNC_WORD(i) + -- + -- POLARITY (from msk_demodulator): + -- NEGATIVE soft value ? '1' bit + -- POSITIVE soft value ? '0' bit + -- + -- For correlation: + -- When SYNC bit = '1': we WANT negative soft ? SUBTRACT (negative becomes positive) + -- When SYNC bit = '0': we WANT positive soft ? ADD (positive stays positive) + ---------------------------------------------------------------------------- + + ---------------------------------------------------------------------------- + -- Quantize 16-bit signed soft value to 3-bit unsigned for Viterbi decoder + ---------------------------------------------------------------------------- + -- + -- PURPOSE: + -- Convert the 16-bit signed soft decision from msk_demodulator into a + -- 3-bit quantized value suitable for the soft Viterbi decoder. + -- + -- SOFT VALUE SOURCE (msk_demodulator.vhd): + -- rx_data_soft <= data_sum WHEN data_bit_enc_t = '0' ELSE -data_sum + -- where data_sum = data_f1_sum - data_f2_sum (difference of matched filters) + -- + -- The signal path includes: + -- 1. Costas loop integrate-and-dump (shifted right by SINUSOID_W) + -- 2. Additional shift right by 5 in data_out + -- 3. Two-sample addition (data_f1_signed + data_f1_T) + -- 4. F1 - F2 difference + -- 5. Differential decoding (sign flip based on previous bit) + -- + -- OBSERVED VALUES: + -- In simulation loopback (perfect channel): approximately ±360 + -- In hardware with noise: expect a distribution around these values + -- + -- 3-BIT QUANTIZATION CONVENTION: + -- 000 = Strong '0' (highest confidence in '0') + -- 001 = Medium '0' + -- 010 = Weak '0' + -- 011 = Erasure/uncertain (near decision boundary) + -- 100 = Weak '1' + -- 101 = Medium '1' + -- 110 = (unused, mapped to medium '1') + -- 111 = Strong '1' (highest confidence in '1') + -- + -- THRESHOLD CALIBRATION: + -- Thresholds are set based on observed rx_data_soft magnitudes. + -- Current values calibrated for simulation with ±360 nominal: + -- |soft| > 300 ? Strong decision + -- |soft| > 150 ? Medium decision + -- |soft| > 50 ? Weak decision + -- |soft| < 50 ? Uncertain/erasure + -- + -- For hardware deployment, monitor rx_data_soft distribution and + -- adjust thresholds if needed. Could also make configurable via CSR. + -- + -- POLARITY: + -- msk_demodulator convention: NEGATIVE soft ? '1', POSITIVE soft ? '0' + -- Therefore: negative soft ? high quantized value (111 = strong '1') + -- positive soft ? low quantized value (000 = strong '0') + -- + ---------------------------------------------------------------------------- + FUNCTION quantize_soft(soft : signed(15 DOWNTO 0)) RETURN std_logic_vector IS + BEGIN + -- POLARITY: negative soft = '1' bit, positive soft = '0' bit + IF soft < -300 THEN + RETURN "111"; -- Strong '1' (large negative soft) + ELSIF soft < -150 THEN + RETURN "101"; -- Medium '1' + ELSIF soft < -50 THEN + RETURN "100"; -- Weak '1' + ELSIF soft < 50 THEN + RETURN "011"; -- Erasure/uncertain + ELSIF soft < 150 THEN + RETURN "010"; -- Weak '0' + ELSIF soft < 300 THEN + RETURN "001"; -- Medium '0' + ELSE + RETURN "000"; -- Strong '0' (large positive soft) + END IF; + END FUNCTION; + + FUNCTION calc_correlation( + soft_samples : soft_shift_array_t; + new_sample : signed(15 DOWNTO 0) + ) RETURN signed IS + VARIABLE sum : signed(31 DOWNTO 0) := (OTHERS => '0'); + VARIABLE sample : signed(15 DOWNTO 0); + BEGIN + FOR i IN 0 TO 23 LOOP + -- Get the appropriate sample (accounting for pending shift) + IF i = 0 THEN + sample := new_sample; + ELSE + sample := soft_samples(i - 1); + END IF; + + -- Add or subtract based on expected sync word bit + -- Position i in shift register corresponds to SYNC_WORD(i) + -- (MSB transmitted first, shifts to high positions) + -- + -- After differential decoding in demodulator: + -- Positive soft ? decoded hard bit '0' + -- Negative soft ? decoded hard bit '1' + -- + -- For correlation: + -- When SYNC bit = '1': expect negative soft ? SUBTRACT (neg becomes pos contribution) + -- When SYNC bit = '0': expect positive soft ? ADD (pos stays pos contribution) + IF SYNC_WORD(i) = '1' THEN + sum := sum - resize(sample, 32); -- Expect negative soft + ELSE + sum := sum + resize(sample, 32); -- Expect positive soft + END IF; + END LOOP; + RETURN sum; + END FUNCTION; + +BEGIN + + frame_sync_locked <= lock_status; + frames_received <= std_logic_vector(frames_count); + frame_sync_errors <= std_logic_vector(errors_count); + m_axis_tvalid <= tvalid_int; + m_axis_tlast <= tlast_int; + + -- Passthrough soft decisions (for downstream use) + m_axis_soft_tdata <= s_axis_soft_tdata; + + -- Debug outputs + WITH state SELECT debug_state <= + "001" WHEN HUNTING, + "010" WHEN LOCKED, + "011" WHEN VERIFYING_SYNC, + "000" WHEN OTHERS; + + debug_missed_syncs <= std_logic_vector(to_unsigned(missed_sync_count, 4)); + debug_consecutive_good <= std_logic_vector(to_unsigned(consecutive_good, 4)); + debug_correlation <= correlation_value; + debug_corr_peak <= correlation_peak; + debug_soft_current <= s_axis_soft_tdata; -- See what soft values look like + debug_bit_count <= std_logic_vector(debug_bits_received); -- Verify bits flowing + + ------------------------------------------------------------------------------ + -- Main Process: Frame Tracking with Flywheel (Correlator Version) + ------------------------------------------------------------------------------ + reception_proc: PROCESS(clk) + VARIABLE corr_result : signed(31 DOWNTO 0); + VARIABLE assembled_byte : std_logic_vector(7 DOWNTO 0); + VARIABLE threshold_to_use : integer; + BEGIN + IF rising_edge(clk) THEN + IF reset = '1' THEN + -- Initialize soft shift register + FOR i IN 0 TO 23 LOOP + soft_shift_reg(i) <= (OTHERS => '0'); + END LOOP; + + sync_shift_bits <= (OTHERS => '0'); + sync_bit_count <= (OTHERS => '0'); + byte_shift_reg <= (OTHERS => '0'); + bit_count <= (OTHERS => '0'); + wr_ptr <= (OTHERS => '0'); + state <= HUNTING; + frame_start_ptr <= (OTHERS => '0'); + frame_byte_count <= 0; + frame_soft_idx <= 0; + frames_count <= (OTHERS => '0'); + errors_count <= (OTHERS => '0'); + consecutive_good <= 0; + missed_sync_count <= 0; + lock_status <= '0'; + acquiring_lock <= '0'; + frame_ready <= '0'; + frame_rd_ptr <= (OTHERS => '0'); + frame_buffer_overflow <= '0'; + correlation_value <= (OTHERS => '0'); + correlation_peak <= (OTHERS => '0'); -- Clear peak on reset + debug_bits_received <= (OTHERS => '0'); -- Clear bit counter + + ELSE + frame_buffer_overflow <= '0'; + + -- Clear frame_ready when acknowledged + IF frame_ack = '1' THEN + frame_ready <= '0'; + END IF; + + -- Always shift in new samples when valid + IF rx_bit_valid = '1' THEN + -- Count bits for debug (verify data is flowing!) + debug_bits_received <= debug_bits_received + 1; + + -- Shift soft samples (newest at position 0, oldest at 23) + FOR i IN 23 DOWNTO 1 LOOP + soft_shift_reg(i) <= soft_shift_reg(i-1); + END LOOP; + soft_shift_reg(0) <= s_axis_soft_tdata; + + -- Also shift hard decision bits (for byte assembly) + sync_shift_bits <= sync_shift_bits(22 DOWNTO 0) & rx_bit; + byte_shift_reg <= byte_shift_reg(6 DOWNTO 0) & rx_bit; + END IF; + + -- State machine + CASE state IS + ------------------------------------------------------ + -- HUNTING: Looking for initial sync using correlation + ------------------------------------------------------ + WHEN HUNTING => + acquiring_lock <= '1'; + + IF rx_bit_valid = '1' THEN + -- Calculate correlation including the new sample + -- (signal assignments pending, so we pass new sample explicitly) + corr_result := calc_correlation(soft_shift_reg, s_axis_soft_tdata); + correlation_value <= corr_result; + + -- Track peak correlation for threshold calibration + IF corr_result > correlation_peak THEN + correlation_peak <= corr_result; + END IF; + + -- Use conservative threshold when hunting + threshold_to_use := HUNTING_THRESHOLD; + + -- Check if correlation exceeds threshold + IF corr_result >= to_signed(threshold_to_use, 32) THEN + -- Found potential sync! + frame_byte_count <= 0; + bit_count <= (OTHERS => '0'); + sync_bit_count <= (OTHERS => '0'); + frame_start_ptr <= wr_ptr; + state <= LOCKED; + + -- Track consecutive good detections + IF consecutive_good < LOCK_FRAMES THEN + consecutive_good <= consecutive_good + 1; + ELSE + -- Achieved stable lock + lock_status <= '1'; + acquiring_lock <= '0'; + missed_sync_count <= 0; + END IF; + END IF; + END IF; + + ------------------------------------------------------ + -- LOCKED: Collecting frame payload (bytes AND soft values) + ------------------------------------------------------ + WHEN LOCKED => + IF rx_bit_valid = '1' THEN + -- Store quantized soft value in ARRIVAL order. + -- frame_soft_idx counts 0, 1, 2, ... as bits arrive. + -- The decoder will handle deinterleaving and MSB-first correction. + IF frame_soft_idx < PAYLOAD_BITS THEN + soft_frame_buffer(frame_soft_idx) <= + quantize_soft(s_axis_soft_tdata); + frame_soft_idx <= frame_soft_idx + 1; + END IF; + + bit_count <= bit_count + 1; + + IF bit_count = 7 THEN + -- Byte complete (MSB-first assembly) + -- NOTE: byte_shift_reg hasn't been updated yet (signal assignment pending) + -- so we must manually include the current rx_bit + assembled_byte := byte_shift_reg(6 DOWNTO 0) & rx_bit; + + -- Write to circular buffer + circ_buffer(to_integer(wr_ptr)) <= assembled_byte; + wr_ptr <= wr_ptr + 1; + + IF wr_ptr + 1 = rd_ptr THEN + frame_buffer_overflow <= '1'; + errors_count <= errors_count + 1; + END IF; + + bit_count <= (OTHERS => '0'); + + IF frame_byte_count < PAYLOAD_BYTES - 1 THEN + frame_byte_count <= frame_byte_count + 1; + ELSE + -- Frame payload complete + IF frame_ready = '0' THEN + frame_ready <= '1'; + frame_rd_ptr <= frame_start_ptr; + frames_count <= frames_count + 1; + ELSE + -- Output process hasn't taken previous frame yet + errors_count <= errors_count + 1; + END IF; + + frame_byte_count <= 0; + frame_soft_idx <= 0; -- Reset soft index for next frame + state <= VERIFYING_SYNC; + sync_bit_count <= (OTHERS => '0'); + END IF; + END IF; + END IF; + + ------------------------------------------------------ + -- VERIFYING_SYNC: Check for next sync using correlation + ------------------------------------------------------ + WHEN VERIFYING_SYNC => + IF rx_bit_valid = '1' THEN + sync_bit_count <= sync_bit_count + 1; + + -- After collecting 24 bits, verify via correlation + IF sync_bit_count = 23 THEN + -- Calculate correlation (include new sample in calculation) + corr_result := calc_correlation(soft_shift_reg, s_axis_soft_tdata); + correlation_value <= corr_result; + + -- Track peak correlation for threshold calibration + IF corr_result > correlation_peak THEN + correlation_peak <= corr_result; + END IF; + + -- Choose threshold based on lock status + IF lock_status = '1' THEN + threshold_to_use := LOCKED_THRESHOLD; + ELSE + threshold_to_use := HUNTING_THRESHOLD; + END IF; + + IF corr_result >= to_signed(threshold_to_use, 32) THEN + -- Good! Sync found where expected + missed_sync_count <= 0; + + IF acquiring_lock = '1' THEN + IF consecutive_good < LOCK_FRAMES - 1 THEN + consecutive_good <= consecutive_good + 1; + ELSE + lock_status <= '1'; + acquiring_lock <= '0'; + consecutive_good <= LOCK_FRAMES; + END IF; + ELSE + consecutive_good <= LOCK_FRAMES; + END IF; + + state <= LOCKED; + bit_count <= (OTHERS => '0'); + frame_start_ptr <= wr_ptr; + + ELSE + -- Missed expected sync! + IF lock_status = '1' THEN + IF missed_sync_count < FLYWHEEL_TOLERANCE THEN + missed_sync_count <= missed_sync_count + 1; + state <= LOCKED; + bit_count <= (OTHERS => '0'); + errors_count <= errors_count + 1; + ELSE + -- Too many misses, lost lock + lock_status <= '0'; + consecutive_good <= 0; + missed_sync_count <= 0; + state <= HUNTING; + errors_count <= errors_count + 1; + END IF; + ELSE + -- Still acquiring lock: any miss sends us back + consecutive_good <= 0; + state <= HUNTING; + errors_count <= errors_count + 1; + END IF; + END IF; + END IF; + END IF; + + WHEN OTHERS => + state <= HUNTING; + END CASE; + + END IF; + END IF; + END PROCESS reception_proc; + + ------------------------------------------------------------------------------ + -- Output Process: Stream bytes then soft values to AXIS interfaces + ------------------------------------------------------------------------------ + output_proc: PROCESS(clk) + BEGIN + IF rising_edge(clk) THEN + IF reset = '1' THEN + m_axis_tdata <= (OTHERS => '0'); + tvalid_int <= '0'; + tlast_int <= '0'; + output_count <= 0; + output_active <= '0'; + soft_output_active <= '0'; + soft_output_count <= 0; + soft_tvalid_int <= '0'; + soft_tlast_int <= '0'; + frame_ack <= '0'; + rd_ptr <= (OTHERS => '0'); + + ELSE + frame_ack <= '0'; + + -- Start byte output when frame is ready + IF frame_ready = '1' AND output_active = '0' AND soft_output_active = '0' THEN + output_active <= '1'; + rd_ptr <= frame_rd_ptr; + output_count <= 0; + frame_ack <= '1'; + END IF; + + -- Output bytes + IF output_active = '1' THEN + IF m_axis_tready = '1' OR tvalid_int = '0' THEN + m_axis_tdata <= circ_buffer(to_integer(rd_ptr)); + tvalid_int <= '1'; + rd_ptr <= rd_ptr + 1; + + IF output_count = PAYLOAD_BYTES - 1 THEN + tlast_int <= '1'; + output_active <= '0'; + output_count <= 0; + -- Start soft output after bytes complete + soft_output_active <= '1'; + soft_output_count <= 0; + ELSE + tlast_int <= '0'; + output_count <= output_count + 1; + END IF; + END IF; + ELSE + IF m_axis_tready = '1' THEN + tvalid_int <= '0'; + tlast_int <= '0'; + END IF; + END IF; + + -- Output soft values (after bytes are done) + IF soft_output_active = '1' THEN + IF m_axis_soft_bit_tready = '1' OR soft_tvalid_int = '0' THEN + m_axis_soft_bit_tdata <= soft_frame_buffer(soft_output_count); + soft_tvalid_int <= '1'; + + IF soft_output_count = PAYLOAD_BITS - 1 THEN + soft_tlast_int <= '1'; + soft_output_active <= '0'; + soft_output_count <= 0; + ELSE + soft_tlast_int <= '0'; + soft_output_count <= soft_output_count + 1; + END IF; + END IF; + ELSE + IF m_axis_soft_bit_tready = '1' THEN + soft_tvalid_int <= '0'; + soft_tlast_int <= '0'; + END IF; + END IF; + END IF; + END IF; + END PROCESS output_proc; + + -- Connect internal signals to outputs + m_axis_soft_bit_tvalid <= soft_tvalid_int; + m_axis_soft_bit_tlast <= soft_tlast_int; + +END ARCHITECTURE rtl; diff --git a/src/msk_top.vhd b/src/msk_top.vhd index 207546b..5b2e6b5 100644 --- a/src/msk_top.vhd +++ b/src/msk_top.vhd @@ -59,13 +59,25 @@ -- MODIFIED FOR MSB-FIRST: Updated sync word from 0xACFA47/0xE25F35 to 0xE25F35/0xE25F35 -- Both TX and RX now use the same sync word pattern (no bit reversal) ------------------------------------------------------------------------------------------------------ +-- PHASE 1: OV ENCODER/DECODER INTEGRATION (Issue #24) +------------------------------------------------------------------------------------------------------ +-- Integrated OV frame encoder (TX) and decoder (RX) into datapath: +-- TX: FIFO ? Encoder (134?268 bytes) ? Deserializer ? Modulator +-- RX: Demodulator ? Frame Sync ? Decoder (268?134 bytes) ? FIFO +-- +-- KNOWN LIMITATION: Frame size mismatch - PS currently sends/expects 268 bytes +-- - Encoder expects 134-byte input but receives 268 bytes +-- - Decoder outputs 134 bytes but PS expects 268 bytes +-- - This will be resolved in Phase 2 by updating PS frame size to 134 bytes +-- +-- Modified: TX Stage 3 (encoder insertion), TX Stage 4 (deserializer rewire) +-- RX Stage 3 (decoder insertion), RX Stage 4 (FIFO rewire) +------------------------------------------------------------------------------------------------------ LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; -USE work.pkg_msk_top_regs.ALL; - ENTITY msk_top IS GENERIC ( HASH_ID_LO : std_logic_vector := X"AAAA5555"; @@ -85,7 +97,7 @@ ENTITY msk_top IS C_S_AXI_DATA_WIDTH : NATURAL := 32; C_S_AXI_ADDR_WIDTH : NATURAL := 32; SYNC_CNT_W : NATURAL := 24; - FIFO_ADDR_WIDTH : NATURAL := 11 -- 2048 byte FIFO (used in both tx and rx) + FIFO_ADDR_WIDTH : NATURAL := 9 -- 512 byte FIFO (used in both tx and rx) ); PORT ( clk : IN std_logic; @@ -111,9 +123,9 @@ ENTITY msk_top IS s_axi_awready : out std_logic; s_axi_awprot : in std_logic_vector(2 DOWNTO 0); s_axi_arprot : in std_logic_vector(2 DOWNTO 0); - s_axis_aresetn : IN std_logic; s_axis_aclk : IN std_logic; + m_axis_aclk : IN std_logic; -- Clock for RX output to DMA (sys_cpu_clk, 100 MHz) s_axis_tvalid : IN std_logic; s_axis_tready : OUT std_logic; s_axis_tdata : IN std_logic_vector(S_AXIS_DATA_W -1 DOWNTO 0); @@ -136,9 +148,35 @@ ENTITY msk_top IS m_axis_tlast : OUT std_logic; frame_sync_locked : OUT std_logic; - frames_received : OUT std_logic_vector(31 DOWNTO 0); + frames_received : OUT std_logic_vector(31 DOWNTO 0); frame_sync_errors : OUT std_logic_vector(31 DOWNTO 0); - fifo_overflow : OUT std_logic + frame_buffer_overflow : OUT std_logic; + + -- Debug outputs for deserializer probing (TX) + dbg_tx_data_bit : OUT std_logic; + dbg_tx_req : OUT std_logic; + dbg_encoder_tvalid : OUT std_logic; + dbg_encoder_tready : OUT std_logic; + dbg_encoder_tdata : OUT std_logic_vector(7 DOWNTO 0); + dbg_frame_complete : OUT std_logic; + dbg_fifo_tdata : OUT std_logic_vector(7 DOWNTO 0); + dbg_fifo_tvalid : OUT std_logic; + dbg_fifo_tready : OUT std_logic; + dbg_encoder_state : OUT std_logic_vector(2 DOWNTO 0); + + -- Debug outputs for RX path probing + dbg_rx_bit_valid : OUT std_logic; + dbg_rx_bit_corr : OUT std_logic; + dbg_rx_sync_state : OUT std_logic_vector(2 DOWNTO 0); + dbg_rx_sync_correlation : OUT std_logic_vector(31 DOWNTO 0); + dbg_rx_sync_corr_peak : OUT std_logic_vector(31 DOWNTO 0); + dbg_rx_data_soft : OUT std_logic_vector(15 DOWNTO 0); + + -- Randomizer debug outputs (for ILA) + dbg_lfsr_state : OUT std_logic_vector(7 DOWNTO 0); + dbg_input_byte : OUT std_logic_vector(7 DOWNTO 0); + dbg_rand_byte : OUT std_logic_vector(7 DOWNTO 0); + dbg_rand_active : OUT std_logic ); END ENTITY msk_top; @@ -170,8 +208,42 @@ ARCHITECTURE struct OF msk_top IS SIGNAL fifo_tlast : std_logic; SIGNAL frame_complete : std_logic; - SIGNAL fifo_prog_full : std_logic; - SIGNAL fifo_prog_empty : std_logic; + + -- TX Encoder signals (OV Frame Encoder - Phase 1) + SIGNAL encoder_tdata : std_logic_vector(7 DOWNTO 0); + SIGNAL encoder_tvalid : std_logic; + SIGNAL encoder_tready : std_logic; + SIGNAL encoder_tlast : std_logic; + SIGNAL tx_frames_encoded : std_logic_vector(31 DOWNTO 0); + SIGNAL tx_encoder_active : std_logic; + SIGNAL encoder_debug_state : std_logic_vector(2 DOWNTO 0); + + + + -- Encoder randomizer debug signals + SIGNAL encoder_debug_lfsr : std_logic_vector(7 DOWNTO 0); + SIGNAL encoder_debug_input_byte : std_logic_vector(7 DOWNTO 0); + SIGNAL encoder_debug_rand_byte : std_logic_vector(7 DOWNTO 0); + SIGNAL encoder_debug_rand_active : std_logic; + + + SIGNAL tx_async_fifo_prog_full : std_logic; + SIGNAL tx_async_fifo_prog_empty : std_logic; + SIGNAL tx_async_fifo_overflow : std_logic; + SIGNAL tx_async_fifo_underflow : std_logic; + SIGNAL tx_async_fifo_wr_ptr : std_logic_vector(FIFO_ADDR_WIDTH DOWNTO 0); + SIGNAL tx_async_fifo_rd_ptr : std_logic_vector(FIFO_ADDR_WIDTH DOWNTO 0); + SIGNAL tx_async_fifo_status_req : std_logic; + SIGNAL tx_async_fifo_status_ack : std_logic; + + SIGNAL rx_async_fifo_prog_full : std_logic; + SIGNAL rx_async_fifo_prog_empty : std_logic; + SIGNAL rx_async_fifo_overflow : std_logic; + SIGNAL rx_async_fifo_underflow : std_logic; + SIGNAL rx_async_fifo_wr_ptr : std_logic_vector(FIFO_ADDR_WIDTH DOWNTO 0); + SIGNAL rx_async_fifo_rd_ptr : std_logic_vector(FIFO_ADDR_WIDTH DOWNTO 0); + SIGNAL rx_async_fifo_status_req : std_logic; + SIGNAL rx_async_fifo_status_ack : std_logic; -- RX chain signals SIGNAL rx_byte : std_logic_vector(7 DOWNTO 0); @@ -182,15 +254,38 @@ ARCHITECTURE struct OF msk_top IS SIGNAL sync_det_tready : std_logic; SIGNAL sync_det_tlast : std_logic; - SIGNAL rx_fifo_overflow : std_logic; - SIGNAL rx_frame_sync_locked : std_logic; - SIGNAL rx_frames_count : std_logic_vector(31 DOWNTO 0); - SIGNAL rx_frame_sync_errors : std_logic_vector(31 DOWNTO 0); + SIGNAL rx_frame_buffer_overflow : std_logic; + SIGNAL rx_frame_sync_locked : std_logic; + SIGNAL rx_frames_count : std_logic_vector(31 DOWNTO 0); + SIGNAL rx_frame_sync_errors : std_logic_vector(31 DOWNTO 0); -- Flywheel debug signals (internal only, not exposed to top-level ports) SIGNAL rx_debug_state : std_logic_vector(2 DOWNTO 0); SIGNAL rx_debug_missed_syncs : std_logic_vector(3 DOWNTO 0); SIGNAL rx_debug_consecutive_good: std_logic_vector(3 DOWNTO 0); + + -- RX Decoder signals (OV Frame Decoder - Phase 1) + SIGNAL decoder_tdata : std_logic_vector(7 DOWNTO 0); + SIGNAL decoder_tvalid : std_logic; + SIGNAL decoder_tready : std_logic; + SIGNAL decoder_tlast : std_logic; + SIGNAL rx_frames_decoded : std_logic_vector(31 DOWNTO 0); + SIGNAL rx_decoder_active : std_logic; + + -- Debug signals for RX decoder (added for hardware debugging) + SIGNAL decoder_debug_state : std_logic_vector(3 DOWNTO 0); + SIGNAL decoder_debug_viterbi_start : std_logic; + SIGNAL decoder_debug_viterbi_busy : std_logic; + SIGNAL decoder_debug_viterbi_done : std_logic; + + -- Soft Viterbi Decoder Signals + SIGNAL sync_det_soft_tdata : std_logic_vector(2 DOWNTO 0); + SIGNAL sync_det_soft_tvalid : std_logic; + SIGNAL sync_det_soft_tready : std_logic; + SIGNAL sync_det_soft_tlast : std_logic; + -- Debug: soft decoder path metric + SIGNAL decoder_debug_path_metric : std_logic_vector(15 DOWNTO 0); + SIGNAL rx_bit : std_logic; SIGNAL rx_bit_corr : std_logic; @@ -200,6 +295,15 @@ ARCHITECTURE struct OF msk_top IS SIGNAL rx_data_int : std_logic_vector(S_AXIS_DATA_W -1 DOWNTO 0); SIGNAL rx_invert : std_logic; + SIGNAL rx_data_soft : signed(15 downto 0); + SIGNAL rx_data_soft_valid : std_logic; + + -- Frame sync detector correlator debug signals + SIGNAL rx_sync_correlation : signed(31 DOWNTO 0); + SIGNAL rx_sync_corr_peak : signed(31 DOWNTO 0); + SIGNAL rx_sync_soft_current : signed(15 DOWNTO 0); + SIGNAL rx_sync_bit_count : std_logic_vector(31 DOWNTO 0); + SIGNAL rx_sample_clk : std_logic; SIGNAL discard_rxsamples: std_logic_vector(7 DOWNTO 0); SIGNAL discard_rxnco : std_logic_vector(7 DOWNTO 0); @@ -278,8 +382,43 @@ ARCHITECTURE struct OF msk_top IS SIGNAL pd_alpha2 : std_logic_vector(17 DOWNTO 0); SIGNAL pd_power : std_logic_vector(22 DOWNTO 0); + + + ATTRIBUTE dont_touch : STRING; + ATTRIBUTE dont_touch OF u_async_fifo : LABEL IS "true"; + ATTRIBUTE dont_touch OF u_rx_async_fifo : LABEL IS "true"; + ATTRIBUTE dont_touch OF u_ov_encoder : LABEL IS "true"; + ATTRIBUTE dont_touch OF u_deserializer : LABEL IS "true"; + + --ATTRIBUTE dont_touch OF tx_data_bit : SIGNAL IS "true"; + --ATTRIBUTE dont_touch OF fifo_tdata : SIGNAL IS "true"; + --ATTRIBUTE dont_touch OF fifo_tvalid : SIGNAL IS "true"; + --ATTRIBUTE dont_touch OF fifo_tready : SIGNAL IS "true"; + --ATTRIBUTE dont_touch OF fifo_tlast : SIGNAL IS "true"; + --ATTRIBUTE dont_touch OF encoder_tdata : SIGNAL IS "true"; + --ATTRIBUTE dont_touch OF encoder_tvalid : SIGNAL IS "true"; + --ATTRIBUTE dont_touch OF encoder_tready : SIGNAL IS "true"; + --ATTRIBUTE dont_touch OF encoder_tlast : SIGNAL IS "true"; + + -- RX path protection (add after existing TX dont_touch attributes) + ATTRIBUTE dont_touch OF u_ov_decoder : LABEL IS "true"; + ATTRIBUTE dont_touch OF u_rx_frame_sync : LABEL IS "true"; + + --ATTRIBUTE dont_touch OF decoder_tdata : SIGNAL IS "true"; + --ATTRIBUTE dont_touch OF decoder_tvalid : SIGNAL IS "true"; + --ATTRIBUTE dont_touch OF decoder_tready : SIGNAL IS "true"; + --ATTRIBUTE dont_touch OF decoder_tlast : SIGNAL IS "true"; + --ATTRIBUTE dont_touch OF sync_det_tdata : SIGNAL IS "true"; + --ATTRIBUTE dont_touch OF sync_det_tvalid : SIGNAL IS "true"; + --ATTRIBUTE dont_touch OF sync_det_tready : SIGNAL IS "true"; + --ATTRIBUTE dont_touch OF sync_det_tlast : SIGNAL IS "true"; + + + BEGIN + + ------------------------------------------------------------------------------------------------------ -- OPULENT VOICE TX FIFO CHAIN ------------------------------------------------------------------------------------------------------ @@ -310,11 +449,11 @@ BEGIN u_async_fifo : ENTITY work.axis_async_fifo GENERIC MAP ( DATA_WIDTH => 8, - ADDR_WIDTH => FIFO_ADDR_WIDTH + ADDR_WIDTH => FIFO_ADDR_WIDTH --9 which is 512 bytes ) PORT MAP ( wr_aclk => s_axis_aclk, - wr_aresetn => s_axis_aresetn, + wr_aresetn => s_axis_aresetn AND NOT txinit, -- add software control s_axis_tdata => adapter_tdata, s_axis_tvalid => adapter_tvalid, @@ -329,23 +468,93 @@ BEGIN m_axis_tready => fifo_tready, m_axis_tlast => fifo_tlast, - prog_full => fifo_prog_full, - prog_empty => fifo_prog_empty + -- status signals synchronized to AXI control/status bus + status_aclk => s_axi_aclk, + status_aresetn => s_axi_aresetn, + status_req => tx_async_fifo_status_req, + status_ack => tx_async_fifo_status_ack, + prog_full => tx_async_fifo_prog_full, + prog_empty => tx_async_fifo_prog_empty, + fifo_overflow => tx_async_fifo_overflow, + fifo_underflow => tx_async_fifo_underflow, + fifo_wr_ptr => tx_async_fifo_wr_ptr, + fifo_rd_ptr => tx_async_fifo_rd_ptr ); - -- Stage 3: Byte-to-Bit De-serializer (MSB-FIRST VERSION) - u_deserializer : ENTITY work.byte_to_bit_deserializer + ------------------------------------------------------------------------------------------------------ + -- TX Stage 3: OV Frame Encoder (Randomize + FEC + Interleave) - PHASE 1 + ------------------------------------------------------------------------------------------------------ + -- NOTE: Phase 1 limitation - encoder expects 134-byte frames but currently receives 268 bytes + -- This will be corrected in Phase 2 when PS side is updated to send 134-byte frames + ------------------------------------------------------------------------------------------------------ + + u_ov_encoder : ENTITY work.ov_frame_encoder GENERIC MAP ( - BYTE_WIDTH => 8 + PAYLOAD_BYTES => 134, + ENCODED_BYTES => 268, + ENCODED_BITS => 2144, + BYTE_WIDTH => 8, + USE_BIT_INTERLEAVER => TRUE, + BYPASS_RANDOMIZE => FALSE, -- Set TRUE to test without randomization + BYPASS_FEC => TRUE, -- Set TRUE to test without FEC + BYPASS_INTERLEAVE => FALSE -- Set TRUE to test without interleaving ) PORT MAP ( clk => clk, - init => txinit, + aresetn => NOT txinit, + -- Input from FIFO s_axis_tdata => fifo_tdata, s_axis_tvalid => fifo_tvalid, s_axis_tready => fifo_tready, s_axis_tlast => fifo_tlast, + + -- Bypass Encoder here. Comment out above and tie off inputs below + --s_axis_tdata => (others => '0'), + --s_axis_tvalid => '0', + --s_axis_tready => open, -- Leave unconnected! + --s_axis_tlast => '0', + + -- Output to deserializer + m_axis_tdata => encoder_tdata, + m_axis_tvalid => encoder_tvalid, + m_axis_tready => encoder_tready, + m_axis_tlast => encoder_tlast, + + -- Status + frames_encoded => tx_frames_encoded, + encoder_active => tx_encoder_active, + debug_state => encoder_debug_state, + + -- for ILA probing + debug_lfsr => encoder_debug_lfsr, + debug_input_byte => encoder_debug_input_byte, + debug_rand_byte => encoder_debug_rand_byte, + debug_rand_active => encoder_debug_rand_active + + ); + + -- Stage 4: Byte-to-Bit De-serializer (MSB-FIRST VERSION) + u_deserializer : ENTITY work.byte_to_bit_deserializer + GENERIC MAP ( + BYTE_WIDTH => 8 + ) + PORT MAP ( + clk => clk, + init => txinit, + + -- Input from encoder (was: from FIFO) + s_axis_tdata => encoder_tdata, + s_axis_tvalid => encoder_tvalid, + s_axis_tready => encoder_tready, + s_axis_tlast => encoder_tlast, + + -- Bypass Encoder. Comment out encoder above and use below: + --s_axis_tdata => fifo_tdata, + --s_axis_tvalid => fifo_tvalid, + --s_axis_tready => fifo_tready, + --s_axis_tlast => fifo_tlast, + tx_data => tx_data_bit, tx_req => tx_req, @@ -360,6 +569,32 @@ BEGIN tx_samples_I <= tx_samples_I_int; tx_samples_Q <= tx_samples_Q_int; + -- Debug output assignments for ILA probing (TX) + dbg_tx_data_bit <= tx_data_bit; + dbg_tx_req <= tx_req; + dbg_encoder_tvalid <= encoder_tvalid; + dbg_encoder_tready <= encoder_tready; + dbg_encoder_tdata <= encoder_tdata; + dbg_frame_complete <= frame_complete; + dbg_fifo_tdata <= fifo_tdata; + dbg_fifo_tvalid <= fifo_tvalid; + dbg_fifo_tready <= fifo_tready; + dbg_encoder_state <= encoder_debug_state; + + -- Debug output assignments for ILA probing (RX) + dbg_rx_bit_valid <= rx_bit_valid; + dbg_rx_bit_corr <= rx_bit_corr; + dbg_rx_sync_state <= rx_debug_state; + dbg_rx_sync_correlation <= std_logic_vector(rx_sync_correlation); + dbg_rx_sync_corr_peak <= std_logic_vector(rx_sync_corr_peak); + dbg_rx_data_soft <= std_logic_vector(rx_data_soft); + + -- Debug output assignments for ILA probing (Randomizer) + dbg_lfsr_state <= encoder_debug_lfsr; + dbg_input_byte <= encoder_debug_input_byte; + dbg_rand_byte <= encoder_debug_rand_byte; + dbg_rand_active <= encoder_debug_rand_active; + rx_samples_mux <= std_logic_vector(resize(signed(tx_samples_I_int), 16)) WHEN loopback_ena = '1' ELSE rx_samples_I; -- Delay pipeline for tx_data_bit @@ -446,26 +681,22 @@ BEGIN tx_samples_I => tx_samples_I_int, tx_samples_Q => tx_samples_Q_int ); - - - - - - - ------------------------------------------------------------------------------ -- RX Stage 2: Frame Sync Detector (MSB-FIRST VERSION) ------------------------------------------------------------------------------ - u_rx_frame_sync : ENTITY work.frame_sync_detector + u_rx_frame_sync : ENTITY work.frame_sync_detector_soft GENERIC MAP ( SYNC_WORD => x"02B8DB", -- MSB-first sync word (same as TX!) PAYLOAD_BYTES => 268, - HUNTING_THRESHOLD => 3, -- Strict threshold when searching - LOCKED_THRESHOLD => 5, -- Relaxed threshold when locked + HUNTING_THRESHOLD => 6000, -- adjust after observing, soft decisions + -- HUNTING_THRESHOLD => 3, -- Strict threshold when searching, hard decisions + LOCKED_THRESHOLD => 3000, -- adjust after observing, soft decisions + --LOCKED_THRESHOLD => 5, -- Relaxed threshold when locked, hard decisions FLYWHEEL_TOLERANCE => 2, -- Tolerate 2 missed syncs LOCK_FRAMES => 3, -- Need 3 consecutive good frames - BUFFER_DEPTH => 11 -- 2048 bytes + BUFFER_DEPTH => 11, -- 2048 bytes + SOFT_WIDTH => 3 -- 3-bit quantized soft values ) PORT MAP ( clk => clk, @@ -473,54 +704,134 @@ BEGIN rx_bit => rx_bit_corr, rx_bit_valid => rx_bit_valid, - + --s_axis_soft_tdata => (OTHERS => '0'), -- tied to zero for hard decisions + s_axis_soft_tdata => rx_data_soft, -- Connect rx_data_soft for soft decisions + m_axis_soft_tdata => OPEN, -- debug passthrough, unused + + -- byte output m_axis_tdata => sync_det_tdata, m_axis_tvalid => sync_det_tvalid, m_axis_tready => sync_det_tready, m_axis_tlast => sync_det_tlast, + --Soft bit output (2144 x 3-bit values after bytes) + m_axis_soft_bit_tdata => sync_det_soft_tdata, + m_axis_soft_bit_tvalid => sync_det_soft_tvalid, + m_axis_soft_bit_tready => sync_det_soft_tready, + m_axis_soft_bit_tlast => sync_det_soft_tlast, + -- Frame synchronization signals frame_sync_locked => rx_frame_sync_locked, frames_received => rx_frames_count, frame_sync_errors => rx_frame_sync_errors, - buffer_overflow => rx_fifo_overflow, + frame_buffer_overflow => rx_frame_buffer_overflow, - -- Debug signals (internal only) + -- Debug signals for frame detector states debug_state => rx_debug_state, debug_missed_syncs => rx_debug_missed_syncs, - debug_consecutive_good => rx_debug_consecutive_good + debug_consecutive_good => rx_debug_consecutive_good, + + -- Debug outputs for correlation simulation/ILA visibility + debug_correlation => rx_sync_correlation, + debug_corr_peak => rx_sync_corr_peak, + debug_soft_current => rx_sync_soft_current, + debug_bit_count => rx_sync_bit_count + ); ------------------------------------------------------------------------------ - -- RX Stage 3: Async FIFO (Clock Domain Crossing) + -- RX Stage 3: OV Frame Decoder (Deinterleave + FEC Decode + Derandomize) - PHASE 1 + ------------------------------------------------------------------------------ + -- NOTE: Phase 1 limitation - decoder outputs 134 bytes but RX FIFO/DMA expects 268 bytes + -- This will be corrected in Phase 2 when PS side is updated to receive 134-byte frames + ------------------------------------------------------------------------------ + + u_ov_decoder : ENTITY work.ov_frame_decoder_soft + GENERIC MAP ( + PAYLOAD_BYTES => 134, + ENCODED_BYTES => 268, + ENCODED_BITS => 2144, + BYTE_WIDTH => 8, + SOFT_WIDTH => 3, + USE_BIT_INTERLEAVER => TRUE, + BYPASS_RANDOMIZE => FALSE, -- Set TRUE to test without randomization + BYPASS_FEC => TRUE, -- Set TRUE to test without FEC + BYPASS_INTERLEAVE => FALSE -- Set TRUE to test without interleaving + ) + PORT MAP ( + clk => clk, + aresetn => NOT rxinit, + + -- Byte input from frame sync detector + s_axis_tdata => sync_det_tdata, + s_axis_tvalid => sync_det_tvalid, + s_axis_tready => sync_det_tready, + s_axis_tlast => sync_det_tlast, + + --Soft bit input from frame sync detector + s_axis_soft_bit_tdata => sync_det_soft_tdata, + s_axis_soft_bit_tvalid => sync_det_soft_tvalid, + s_axis_soft_bit_tready => sync_det_soft_tready, + s_axis_soft_bit_tlast => sync_det_soft_tlast, + + -- Output to RX FIFO + m_axis_tdata => decoder_tdata, + m_axis_tvalid => decoder_tvalid, + m_axis_tready => decoder_tready, + m_axis_tlast => decoder_tlast, + + -- Status + frames_decoded => rx_frames_decoded, + decoder_active => rx_decoder_active, + + -- Debug outputs + debug_state => decoder_debug_state, + debug_viterbi_start => decoder_debug_viterbi_start, + debug_viterbi_busy => decoder_debug_viterbi_busy, + debug_viterbi_done => decoder_debug_viterbi_done + ); + + ------------------------------------------------------------------------------ + -- RX Stage 4: Async FIFO (Clock Domain Crossing) -- Reuses existing axis_async_fifo component! ------------------------------------------------------------------------------ u_rx_async_fifo : ENTITY work.axis_async_fifo GENERIC MAP ( DATA_WIDTH => 8, - ADDR_WIDTH => FIFO_ADDR_WIDTH -- Reuse generic (11 = 2048 bytes) + ADDR_WIDTH => FIFO_ADDR_WIDTH -- Reuse generic (9 = 512 bytes) ) PORT MAP ( -- Write side (symbol clock domain) wr_aclk => clk, wr_aresetn => NOT rxinit, - s_axis_tdata => sync_det_tdata, - s_axis_tvalid => sync_det_tvalid, - s_axis_tready => sync_det_tready, - s_axis_tlast => sync_det_tlast, + -- Input from decoder (was: from frame sync detector) + s_axis_tdata => decoder_tdata, + s_axis_tvalid => decoder_tvalid, + s_axis_tready => decoder_tready, + s_axis_tlast => decoder_tlast, - -- Read side (AXI clock domain) - rd_aclk => s_axis_aclk, -- Use system AXI clock - rd_aresetn => s_axis_aresetn, + -- Read side (AXI clock domain - 100 MHz sys_cpu_clk) + rd_aclk => m_axis_aclk, -- DMA runs at sys_cpu_clk, not l_clk + -- rd_aclk => s_axis_aclk, -- Use system AXI clock (caused timing violation) + rd_aresetn => s_axis_aresetn AND NOT rxinit, -- add software control m_axis_tdata => m_axis_tdata(7 DOWNTO 0), m_axis_tvalid => m_axis_tvalid, m_axis_tready => m_axis_tready, m_axis_tlast => m_axis_tlast, - prog_full => OPEN, - prog_empty => OPEN + -- status signals synchronized to AXI control/status bus + status_aclk => s_axi_aclk, + status_aresetn => s_axi_aresetn, + status_req => rx_async_fifo_status_req, + status_ack => rx_async_fifo_status_ack, + prog_full => rx_async_fifo_prog_full, + prog_empty => rx_async_fifo_prog_empty, + fifo_overflow => rx_async_fifo_overflow, + fifo_underflow => rx_async_fifo_underflow, + fifo_wr_ptr => rx_async_fifo_wr_ptr, + fifo_rd_ptr => rx_async_fifo_rd_ptr ); -- Zero-pad upper bits of m_axis_tdata if wider than 8 bits @@ -530,7 +841,7 @@ BEGIN frame_sync_locked <= rx_frame_sync_locked; frames_received <= rx_frames_count; frame_sync_errors <= rx_frame_sync_errors; - fifo_overflow <= rx_fifo_overflow; + frame_buffer_overflow <= rx_frame_buffer_overflow; @@ -553,7 +864,6 @@ BEGIN rx_bit_corr <= rx_bit WHEN rx_invert = '0' ELSE NOT rx_bit; - ------------------------------------------------------------------------------------------------------ -- MSK DEMODULATOR ------------------------------------------------------------------------------------------------------ @@ -619,7 +929,8 @@ BEGIN rx_svalid => rx_sample_clk, rx_samples => rx_samples_dec(11 DOWNTO 0), - rx_data => rx_bit, + rx_data => rx_bit, -- hard decision + rx_data_soft => rx_data_soft, -- soft decision rx_dvalid => rx_bit_valid ); @@ -756,6 +1067,19 @@ BEGIN f2_nco_adjust => f2_nco_adjust, f1_error => f1_error, f2_error => f2_error, + pd_power => pd_power, + rx_frame_sync => rx_frame_sync_locked, + rx_frame_buffer_ovf => rx_frame_buffer_overflow, + rx_frame_count => rx_frames_count(23 DOWNTO 0), + rx_frame_sync_err => rx_frame_sync_errors(5 DOWNTO 0), + tx_async_fifo_wr_ptr => tx_async_fifo_wr_ptr, + tx_async_fifo_rd_ptr => tx_async_fifo_rd_ptr, + tx_async_fifo_status_req => tx_async_fifo_status_req, + tx_async_fifo_status_ack => tx_async_fifo_status_ack, + rx_async_fifo_wr_ptr => rx_async_fifo_wr_ptr, + rx_async_fifo_rd_ptr => rx_async_fifo_rd_ptr, + rx_async_fifo_status_req => rx_async_fifo_status_req, + rx_async_fifo_status_ack => rx_async_fifo_status_ack, txinit => txinit, rxinit => rxinit, ptt => ptt, @@ -794,7 +1118,24 @@ BEGIN tx_sync_f2 => tx_sync_f2, pd_alpha1 => pd_alpha1, pd_alpha2 => pd_alpha2, - pd_power => pd_power + + -- Abraxas3d added these experimental signals for transmitter stall investigation + tx_debug_encoder_tvalid => encoder_tvalid, + tx_debug_encoder_tready => encoder_tready, + tx_debug_fifo_tvalid => fifo_tvalid, + tx_debug_fifo_tready => fifo_tready, + tx_debug_tx_req => tx_req, + tx_debug_encoder_tlast => encoder_tlast, + tx_debug_encoder_state => encoder_debug_state, + + -- RX debug signals + rx_debug_decoder_state => decoder_debug_state, + rx_debug_viterbi_start => decoder_debug_viterbi_start, + rx_debug_viterbi_busy => decoder_debug_viterbi_busy, + rx_debug_viterbi_done => decoder_debug_viterbi_done, + rx_debug_decoder_tvalid => decoder_tvalid, + rx_debug_decoder_tready => decoder_tready + ); END ARCHITECTURE struct; diff --git a/src/msk_top_csr.vhd b/src/msk_top_csr.vhd index b19e22e..1e517b2 100644 --- a/src/msk_top_csr.vhd +++ b/src/msk_top_csr.vhd @@ -51,9 +51,9 @@ ------------------------------------------------------------------------------------------------------ --- ╦ ┬┌┐ ┬─┐┌─┐┬─┐┬┌─┐┌─┐ --- ║ │├┴┐├┬┘├─┤├┬┘│├┤ └─┐ --- ╩═╝┴└─┘┴└─┴ ┴┴└─┴└─┘└─┘ +-- ? ??? ???????????????? +-- ? ???????????????? ??? +-- ??????????? ??????????? ------------------------------------------------------------------------------------------------------ -- Libraries @@ -61,12 +61,13 @@ LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; -USE work.pkg_msk_top_regs.ALL; +USE work.axi4lite_intf_pkg.ALL; +USE work.msk_top_regs_pkg.ALL; ------------------------------------------------------------------------------------------------------ --- ╔═╗┌┐┌┌┬┐┬┌┬┐┬ ┬ --- ║╣ │││ │ │ │ └┬┘ --- ╚═╝┘└┘ ┴ ┴ ┴ ┴ +-- ?????????????? ? +-- ?? ??? ? ? ? ??? +-- ?????? ? ? ? ? ------------------------------------------------------------------------------------------------------ -- Entity @@ -83,7 +84,8 @@ ENTITY msk_top_csr IS SYNC_W : NATURAL := 16; C_S_AXI_DATA_WIDTH : NATURAL := 32; C_S_AXI_ADDR_WIDTH : NATURAL := 32; - SYNC_CNT_W : NATURAL := 24 + SYNC_CNT_W : NATURAL := 24; + FIFO_ADDR_WIDTH : NATURAL := 9 ); PORT ( clk : IN std_logic; @@ -126,6 +128,20 @@ ENTITY msk_top_csr IS f2_nco_adjust : IN std_logic_vector(31 DOWNTO 0); f1_error : IN std_logic_vector(31 DOWNTO 0); f2_error : IN std_logic_vector(31 DOWNTO 0); + pd_power : IN std_logic_vector(22 DOWNTO 0); + rx_frame_sync : IN std_logic; + rx_frame_buffer_ovf : IN std_logic; + rx_frame_count : IN std_logic_vector(23 DOWNTO 0); + rx_frame_sync_err : IN std_logic_vector( 5 DOWNTO 0); + + tx_async_fifo_wr_ptr : IN std_logic_vector(FIFO_ADDR_WIDTH DOWNTO 0); + tx_async_fifo_rd_ptr : IN std_logic_vector(FIFO_ADDR_WIDTH DOWNTO 0); + tx_async_fifo_status_req : OUT std_logic; + tx_async_fifo_status_ack : IN std_logic; + rx_async_fifo_wr_ptr : IN std_logic_vector(FIFO_ADDR_WIDTH DOWNTO 0); + rx_async_fifo_rd_ptr : IN std_logic_vector(FIFO_ADDR_WIDTH DOWNTO 0); + rx_async_fifo_status_req : OUT std_logic; + rx_async_fifo_status_ack : IN std_logic; txinit : out std_logic; rxinit : out std_logic; @@ -165,126 +181,310 @@ ENTITY msk_top_csr IS tx_sync_f2 : out std_logic; pd_alpha1 : out std_logic_vector(17 DOWNTO 0); pd_alpha2 : out std_logic_vector(17 DOWNTO 0); - pd_power : in std_logic_vector(22 DOWNTO 0) + + -- Debug signals for TX path + tx_debug_encoder_tvalid : IN std_logic; + tx_debug_encoder_tready : IN std_logic; + tx_debug_fifo_tvalid : IN std_logic; + tx_debug_fifo_tready : IN std_logic; + tx_debug_tx_req : IN std_logic; + tx_debug_encoder_tlast : IN std_logic; + tx_debug_encoder_state : IN std_logic_vector(2 DOWNTO 0); + + -- Debug signals for RX path + rx_debug_decoder_state : IN std_logic_vector(3 DOWNTO 0); + rx_debug_viterbi_start : IN std_logic; + rx_debug_viterbi_busy : IN std_logic; + rx_debug_viterbi_done : IN std_logic; + rx_debug_decoder_tvalid : IN std_logic; + rx_debug_decoder_tready : IN std_logic + ); END ENTITY msk_top_csr; ARCHITECTURE rtl OF msk_top_csr IS - SIGNAL pi_s_top : t_msk_top_regs_m2s; - SIGNAL po_s_top : t_msk_top_regs_s2m; + SIGNAL s_axil_i : axi4lite_slave_in_intf( + AWADDR(7 downto 0), + WDATA(31 downto 0), + WSTRB(3 downto 0), + ARADDR(7 downto 0) + ); + SIGNAL s_axil_o : axi4lite_slave_out_intf( + RDATA(31 downto 0) + ); - SIGNAL pi_addrmap : t_addrmap_msk_top_regs_in; - SIGNAL po_addrmap : t_addrmap_msk_top_regs_out; + SIGNAL hwif_in : msk_top_regs_in_t; + SIGNAL hwif_out : msk_top_regs_out_t; SIGNAL txrxinit : std_logic; + COMPONENT cdc_resync IS + PORT ( + clk : IN std_logic; + sync_reset : IN std_logic; + + di : IN std_logic; + do : OUT std_logic + ); + END COMPONENT cdc_resync; + + COMPONENT pulse_detect IS + PORT ( + clk : IN std_logic; + sync_reset : IN std_logic; + + di : IN std_logic; + do : OUT std_logic + ); + END COMPONENT pulse_detect; + + COMPONENT data_capture IS + GENERIC ( + data_width : natural := 32 + ); + PORT ( + clk : IN std_logic; + sync_reset : IN std_logic; + + capture : IN std_logic; + + di : IN std_logic_vector(data_width -1 DOWNTO 0); + do : OUT std_logic_vector(data_width -1 DOWNTO 0) + ); + END COMPONENT data_capture; + + SIGNAL csr_meta : std_logic; + SIGNAL csr_init : std_logic; + + SIGNAL tx_bit_counter_req : std_logic; + SIGNAL tx_ena_counter_req : std_logic; + SIGNAL f1_error_req : std_logic; + SIGNAL f2_error_req : std_logic; + SIGNAL f1_nco_adjust_req : std_logic; + SIGNAL f2_nco_adjust_req : std_logic; + + SIGNAL prbs_bits_req : std_logic; + SIGNAL prbs_errs_req : std_logic; + SIGNAL lpf_accum_f1_req : std_logic; + SIGNAL lpf_accum_f2_req : std_logic; + SIGNAL pd_power_req : std_logic; + SIGNAL axis_xfer_count_req : std_logic; + + SIGNAL frames_received_req : std_logic; + SIGNAL frame_sync_errors_req: std_logic; + BEGIN - u_msk_regs : ENTITY work.msk_top_regs(arch) + s_axil_i.AWVALID <= s_axi_awvalid; + s_axil_i.AWADDR <= s_axi_awaddr(7 DOWNTO 0); + s_axil_i.AWPROT <= s_axi_awprot; + s_axil_i.WVALID <= s_axi_wvalid; + s_axil_i.WDATA <= s_axi_wdata; + s_axil_i.WSTRB <= s_axi_wstrb; + s_axil_i.BREADY <= s_axi_bready; + s_axil_i.ARVALID <= s_axi_arvalid; + s_axil_i.ARADDR <= s_axi_araddr(7 DOWNTO 0); + s_axil_i.ARPROT <= s_axi_arprot; + s_axil_i.RREADY <= s_axi_rready; + + s_axi_awready <= s_axil_o.AWREADY; + s_axi_wready <= s_axil_o.WREADY; + s_axi_bvalid <= s_axil_o.BVALID; + s_axi_bresp <= s_axil_o.BRESP; + s_axi_arready <= s_axil_o.ARREADY; + s_axi_rvalid <= s_axil_o.RVALID; + s_axi_rdata <= s_axil_o.RDATA; + s_axi_rresp <= s_axil_o.RRESP; + + u_msk_regs : ENTITY work.msk_top_regs(rtl) PORT MAP ( - pi_clock => s_axi_aclk, - pi_reset => NOT s_axi_aresetn, - -- TOP subordinate memory mapped interface - pi_s_reset => NOT s_axi_aresetn, - pi_s_top => pi_s_top, - po_s_top => po_s_top, + clk => s_axi_aclk, + rst => NOT s_axi_aresetn, + s_axil_i => s_axil_i, + s_axil_o => s_axil_o, -- to logic interface - pi_addrmap => pi_addrmap, - po_addrmap => po_addrmap + hwif_in => hwif_in, + hwif_out => hwif_out ); - -- write address channel signals--------------------------------------------- - pi_s_top.awaddr <= s_axi_awaddr; - pi_s_top.awprot <= s_axi_awprot; - pi_s_top.awvalid <= s_axi_awvalid; - -- write data channel signals--------------------------------------------- - pi_s_top.wdata <= s_axi_wdata; - pi_s_top.wstrb <= s_axi_wstrb; - pi_s_top.wvalid <= s_axi_wvalid; - -- write response channel signals - pi_s_top.bready <= s_axi_bready; - -- read address channel signals --------------------------------------------- - pi_s_top.araddr <= s_axi_araddr; - pi_s_top.arprot <= s_axi_arprot; - pi_s_top.arvalid <= s_axi_arvalid; - -- read data channel signals--------------------------------------------- - pi_s_top.rready <= s_axi_rready; - - -- write address channel signals--------------------------------------------- - s_axi_awready <= po_s_top.awready; - -- write data channel signals--------------------------------------------- - s_axi_wready <= po_s_top.wready; - -- write response channel signals --------------------------------------------- - s_axi_bresp <= po_s_top.bresp; - s_axi_bvalid <= po_s_top.bvalid; - -- read address channel signals--------------------------------------------- - s_axi_arready <= po_s_top.arready; - -- read data channel signals--------------------------------------------- - s_axi_rdata <= po_s_top.rdata; - s_axi_rresp <= po_s_top.rresp; - s_axi_rvalid <= po_s_top.rvalid; - - pi_addrmap.MSK_Status.demod_sync_lock.data(0) <= '0'; - pi_addrmap.MSK_Status.tx_enable.data(0) <= tx_enable; - pi_addrmap.MSK_Status.rx_enable.data(0) <= rx_enable; - pi_addrmap.MSK_Status.tx_axis_valid.data(0) <= tx_axis_valid; - pi_addrmap.Tx_Bit_Count.tx_bit_counter.data <= tx_bit_counter; - pi_addrmap.Tx_Enable_Count.tx_ena_counter.data <= tx_ena_counter; - pi_addrmap.axis_xfer_count.xfer_count.data <= xfer_count; - pi_addrmap.PRBS_Bit_Count.status_data.data <= prbs_bits; - pi_addrmap.PRBS_Error_Count.status_data.data <= prbs_errs; - pi_addrmap.LPF_Accum_F1.status_data.data <= lpf_accum_f1; - pi_addrmap.LPF_Accum_F2.status_data.data <= lpf_accum_f2; - pi_addrmap.f1_nco_adjust.data.data <= f1_nco_adjust; - pi_addrmap.f2_nco_adjust.data.data <= f2_nco_adjust; - pi_addrmap.f1_error.data.data <= f1_error; - pi_addrmap.f2_error.data.data <= f2_error; - pi_addrmap.rx_power.rx_power.data <= pd_power; - - - - txrxinit <= po_addrmap.MSK_Init.txrxinit.data(0); - txinit <= po_addrmap.MSK_Init.txinit.data(0) OR txrxinit; - rxinit <= po_addrmap.MSK_Init.rxinit.data(0) OR txrxinit; - ptt <= po_addrmap.MSK_Control.ptt.data(0); - loopback_ena <= po_addrmap.MSK_Control.loopback_ena.data(0); - diff_encdec_lbk_ena <= po_addrmap.MSK_Control.diff_encoder_loopback.data(0); - rx_invert <= po_addrmap.MSK_Control.rx_invert.data(0); - clear_counts <= po_addrmap.MSK_Control.clear_counts.data(0); - freq_word_ft <= po_addrmap.Fb_FreqWord.config_data.data; - freq_word_tx_f1 <= po_addrmap.TX_F1_FreqWord.config_data.data; - freq_word_tx_f2 <= po_addrmap.TX_F2_FreqWord.config_data.data; - freq_word_rx_f1 <= po_addrmap.RX_F1_FreqWord.config_data.data; - freq_word_rx_f2 <= po_addrmap.RX_F2_FreqWord.config_data.data; - lpf_freeze <= po_addrmap.LPF_Config_0.lpf_freeze.data(0); - lpf_zero <= po_addrmap.LPF_Config_0.lpf_zero.data(0); - lpf_alpha <= po_addrmap.LPF_Config_0.lpf_alpha.data; - lpf_i_gain <= po_addrmap.LPF_Config_1.i_gain.data; - lpf_i_shift <= po_addrmap.LPF_Config_1.i_shift.data; - lpf_p_gain <= po_addrmap.LPF_Config_2.p_gain.data; - lpf_p_shift <= po_addrmap.LPF_Config_2.p_shift.data; - tx_data_w <= po_addrmap.Tx_Data_Width.data_width.data; - rx_data_w <= po_addrmap.Rx_Data_Width.data_width.data; - discard_rxsamples <= po_addrmap.Rx_Sample_Discard.rx_sample_discard.data; - discard_rxnco <= po_addrmap.Rx_Sample_Discard.rx_nco_discard.data; - - prbs_initial <= po_addrmap.PRBS_Initial_State.config_data.data; - prbs_poly <= po_addrmap.PRBS_Polynomial.config_data.data; - prbs_err_mask <= po_addrmap.PRBS_Error_Mask.config_data.data; - prbs_err_insert <= po_addrmap.PRBS_Control.prbs_error_insert.data(0); - prbs_sel <= po_addrmap.PRBS_Control.prbs_sel.data(0); - prbs_clear <= po_addrmap.PRBS_Control.prbs_clear.data(0); - prbs_manual_sync <= po_addrmap.PRBS_Control.prbs_manual_sync.data(0); - prbs_sync_threshold <= po_addrmap.PRBS_Control.prbs_sync_threshold.data; - - tx_sync_ena <= po_addrmap.Tx_Sync_Ctrl.tx_sync_ena.data(0); - tx_sync_cnt <= po_addrmap.Tx_Sync_Cnt.tx_sync_cnt.data; - tx_sync_force <= po_addrmap.Tx_Sync_Ctrl.tx_sync_force.data(0); - tx_sync_f1 <= po_addrmap.Tx_Sync_Ctrl.tx_sync_f1.data(0); - tx_sync_f2 <= po_addrmap.Tx_Sync_Ctrl.tx_sync_f2.data(0); - - pd_alpha1 <= po_addrmap.lowpass_ema_alpha1.alpha.data; - pd_alpha2 <= po_addrmap.lowpass_ema_alpha2.alpha.data; + csr_init_proc : PROCESS (clk, s_axi_aresetn) + BEGIN + IF s_axi_aresetn = '0' THEN + csr_meta <= '1'; + csr_init <= '1'; + ELSIF clk'EVENT AND clk = '1' THEN + csr_meta <= '0'; + csr_init <= csr_meta; + END IF; + END PROCESS csr_init_proc; + + ulck_s: cdc_resync PORT MAP (s_axi_aclk, NOT s_axi_aresetn, '0', hwif_in.MSK_Status.demod_sync_lock.next_q); + utxe_s: cdc_resync PORT MAP (s_axi_aclk, NOT s_axi_aresetn, tx_enable, hwif_in.MSK_Status.tx_enable.next_q); + urxe_s: cdc_resync PORT MAP (s_axi_aclk, NOT s_axi_aresetn, rx_enable, hwif_in.MSK_Status.rx_enable.next_q); + urfl_s: cdc_resync PORT MAP (s_axi_aclk, NOT s_axi_aresetn, rx_frame_sync, hwif_in.rx_frame_sync_status.frame_sync_locked.next_q); + + urfo_s: cdc_resync PORT MAP (s_axi_aclk, NOT s_axi_aresetn, rx_frame_buffer_ovf, hwif_in.rx_frame_sync_status.frame_buffer_overflow.we); + + -- hwif_in.MSK_Status.rx_enable.next_q <= '1'; -- Commented out becuase handled by urxe_s CDC, by Abraxas3d + hwif_in.MSK_Status.tx_axis_valid.next_q <= tx_axis_valid; + + -- Status Request from AXI to MDM + utbc_r: pulse_detect PORT MAP (clk, csr_init, hwif_out.Tx_Bit_Count.data.swmod, tx_bit_counter_req ); + utbe_r: pulse_detect PORT MAP (clk, csr_init, hwif_out.Tx_Enable_Count.data.swmod, tx_ena_counter_req ); + utatc_r: pulse_detect PORT MAP (clk, csr_init, hwif_out.axis_xfer_count.data.swmod, axis_xfer_count_req ); + utf1e_r: pulse_detect PORT MAP (clk, csr_init, hwif_out.f1_error.data.swmod, f1_error_req ); + utf2e_r: pulse_detect PORT MAP (clk, csr_init, hwif_out.f2_error.data.swmod, f2_error_req ); + utf1a_r: pulse_detect PORT MAP (clk, csr_init, hwif_out.f1_nco_adjust.data.swmod, f1_nco_adjust_req ); + utf2a_r: pulse_detect PORT MAP (clk, csr_init, hwif_out.f2_nco_adjust.data.swmod, f2_nco_adjust_req ); + utprb_r: pulse_detect PORT MAP (clk, csr_init, hwif_out.PRBS_Bit_Count.data.swmod, prbs_bits_req ); + utpre_r: pulse_detect PORT MAP (clk, csr_init, hwif_out.PRBS_Error_Count.data.swmod, prbs_errs_req ); + utlp1_r: pulse_detect PORT MAP (clk, csr_init, hwif_out.LPF_Accum_F1.data.swmod, lpf_accum_f1_req ); + utlp2_r: pulse_detect PORT MAP (clk, csr_init, hwif_out.LPF_Accum_F2.data.swmod, lpf_accum_f2_req ); + utpwr_r: pulse_detect PORT MAP (clk, csr_init, hwif_out.rx_power.data.swmod, pd_power_req ); + utfss_r: pulse_detect PORT MAP (clk, csr_init, hwif_out.rx_frame_sync_status.frames_received.swmod, frames_received_req ); + utfsr_r: pulse_detect PORT MAP (clk, csr_init, hwif_out.rx_frame_sync_status.frame_sync_errors.swmod, frame_sync_errors_req ); + + -- Status acknowledge from MDM to AXI + utbc_a : pulse_detect PORT MAP (s_axi_aclk, NOT s_axi_aresetn, tx_bit_counter_req, hwif_in.Tx_Bit_Count.data.we ); + utbe_a : pulse_detect PORT MAP (s_axi_aclk, NOT s_axi_aresetn, tx_ena_counter_req, hwif_in.Tx_Enable_Count.data.we ); + utatc_a: pulse_detect PORT MAP (s_axi_aclk, NOT s_axi_aresetn, axis_xfer_count_req, hwif_in.axis_xfer_count.data.we ); + utf1e_a: pulse_detect PORT MAP (s_axi_aclk, NOT s_axi_aresetn, f1_error_req, hwif_in.f1_error.data.we ); + utf2e_a: pulse_detect PORT MAP (s_axi_aclk, NOT s_axi_aresetn, f2_error_req, hwif_in.f2_error.data.we ); + utf1a_a: pulse_detect PORT MAP (s_axi_aclk, NOT s_axi_aresetn, f1_nco_adjust_req, hwif_in.f1_nco_adjust.data.we ); + utf2a_a: pulse_detect PORT MAP (s_axi_aclk, NOT s_axi_aresetn, f2_nco_adjust_req, hwif_in.f2_nco_adjust.data.we ); + utprb_a: pulse_detect PORT MAP (s_axi_aclk, NOT s_axi_aresetn, prbs_bits_req, hwif_in.PRBS_Bit_Count.data.we ); + utpre_a: pulse_detect PORT MAP (s_axi_aclk, NOT s_axi_aresetn, prbs_errs_req, hwif_in.PRBS_Error_Count.data.we ); + utlp1_a: pulse_detect PORT MAP (s_axi_aclk, NOT s_axi_aresetn, lpf_accum_f1_req, hwif_in.LPF_Accum_F1.data.we ); + utlp2_a: pulse_detect PORT MAP (s_axi_aclk, NOT s_axi_aresetn, lpf_accum_f2_req, hwif_in.LPF_Accum_F2.data.we ); + utpwr_a: pulse_detect PORT MAP (s_axi_aclk, NOT s_axi_aresetn, pd_power_req, hwif_in.rx_power.data.we ); + utfss_a: pulse_detect PORT MAP (s_axi_aclk, NOT s_axi_aresetn, frames_received_req, hwif_in.rx_frame_sync_status.frames_received.we ); + utfsr_a: pulse_detect PORT MAP (s_axi_aclk, NOT s_axi_aresetn, frame_sync_errors_req, hwif_in.rx_frame_sync_status.frame_sync_errors.we ); + + -- Status capture from MDM to AXI + utbc_c : data_capture PORT MAP (clk, csr_init, tx_bit_counter_req, tx_bit_counter, hwif_in.Tx_Bit_Count.data.next_q ); + utbe_c : data_capture PORT MAP (clk, csr_init, tx_ena_counter_req, tx_ena_counter, hwif_in.Tx_Enable_Count.data.next_q ); + utatc_c: data_capture PORT MAP (clk, csr_init, axis_xfer_count_req, xfer_count, hwif_in.axis_xfer_count.data.next_q ); + utf1e_c: data_capture PORT MAP (clk, csr_init, f1_error_req, f1_error, hwif_in.f1_error.data.next_q ); + utf2e_c: data_capture PORT MAP (clk, csr_init, f2_error_req, f2_error, hwif_in.f2_error.data.next_q ); + utf1a_c: data_capture PORT MAP (clk, csr_init, f1_nco_adjust_req, f1_nco_adjust, hwif_in.f1_nco_adjust.data.next_q ); + utf2a_c: data_capture PORT MAP (clk, csr_init, f2_nco_adjust_req, f2_nco_adjust, hwif_in.f2_nco_adjust.data.next_q ); + utprb_c: data_capture PORT MAP (clk, csr_init, prbs_bits_req, prbs_bits, hwif_in.PRBS_Bit_Count.data.next_q ); + utpre_c: data_capture PORT MAP (clk, csr_init, prbs_errs_req, prbs_errs, hwif_in.PRBS_Error_Count.data.next_q); + utlp1_c: data_capture PORT MAP (clk, csr_init, lpf_accum_f1_req, lpf_accum_f1, hwif_in.LPF_Accum_F1.data.next_q ); + utlp2_c: data_capture PORT MAP (clk, csr_init, lpf_accum_f2_req, lpf_accum_f2, hwif_in.LPF_Accum_F2.data.next_q ); + utpwr_c: data_capture GENERIC MAP (23) + PORT MAP (clk, csr_init, pd_power_req, pd_power, hwif_in.rx_power.data.next_q ); + utfsc_c: data_capture GENERIC MAP (24) + PORT MAP (clk, csr_init, frames_received_req, rx_frame_count, hwif_in.rx_frame_sync_status.frames_received.next_q ); + utfse_c: data_capture GENERIC MAP (6) + PORT MAP (clk, csr_init, frame_sync_errors_req, rx_frame_sync_err, hwif_in.rx_frame_sync_status.frame_sync_errors.next_q ); + + -- FIFO status reads + rx_async_fifo_status_req <= hwif_out.rx_async_fifo_rd_wr_ptr.data.swmod; + + hwif_in.rx_async_fifo_rd_wr_ptr.data.we <= rx_async_fifo_status_ack; + + + -- commented out by Abraxas3d to add more bits to the register to investigate receive failures + --hwif_in.rx_async_fifo_rd_wr_ptr.data.next_q <= std_logic_vector(resize(unsigned(rx_async_fifo_wr_ptr), 16) & resize(unsigned(rx_async_fifo_rd_ptr), 16)); + +-- Experimental RX debug register setup (matching TX debug pattern) +-- Bit layout: +-- [31:28] decoder state (4 bits - IDLE=0, COLLECT_BYTES=1, COLLECT_SOFT=2, EXTRACT=3, +-- DEDECORRELATE=4, DEINTERLEAVE=5, PREP_FEC_DECODE=6, +-- FEC_DECODE=7, DERANDOMIZE=8, OUTPUT=9) +-- [27] viterbi_start +-- [26] viterbi_busy +-- [25] viterbi_done +-- [24] decoder_tvalid +-- [23] decoder_tready +-- [22:13] rx_fifo_wr_ptr (10 bits) +-- [12:10] spare +-- [9:0] rx_fifo_rd_ptr (10 bits) +hwif_in.rx_async_fifo_rd_wr_ptr.data.next_q <= + rx_debug_decoder_state & -- bits 31:28 (4 bits) + rx_debug_viterbi_start & -- bit 27 + rx_debug_viterbi_busy & -- bit 26 + rx_debug_viterbi_done & -- bit 25 + rx_debug_decoder_tvalid & -- bit 24 + rx_debug_decoder_tready & -- bit 23 + std_logic_vector(resize(unsigned(rx_async_fifo_wr_ptr), 10)) & -- bits 22:13 + "000" & -- bits 12:10 spare + std_logic_vector(resize(unsigned(rx_async_fifo_rd_ptr), 10)); -- bits 9:0 + + + + tx_async_fifo_status_req <= hwif_out.tx_async_fifo_rd_wr_ptr.data.swmod; + + hwif_in.tx_async_fifo_rd_wr_ptr.data.we <= tx_async_fifo_status_ack; + + + + + -- commented out by Abraxas3d to add more bits to the register in order to investigate transmitter stall + --hwif_in.tx_async_fifo_rd_wr_ptr.data.next_q <= std_logic_vector(resize(unsigned(tx_async_fifo_wr_ptr), 16) & resize(unsigned(tx_async_fifo_rd_ptr), 16)); + +-- experimental register setup by Abraxas3d +hwif_in.tx_async_fifo_rd_wr_ptr.data.next_q <= + tx_debug_encoder_tvalid & -- bit 31 + tx_debug_encoder_tready & -- bit 30 + tx_debug_fifo_tvalid & -- bit 29 + tx_debug_fifo_tready & -- bit 28 + tx_debug_tx_req & -- bit 27 + tx_debug_encoder_tlast & -- bit 26 + tx_debug_encoder_state & -- bits 25:23 + std_logic_vector(resize(unsigned(tx_async_fifo_wr_ptr), 10)) & -- bits 22:13 + "000" & -- bits 12:10 spare + std_logic_vector(resize(unsigned(tx_async_fifo_rd_ptr), 10)); -- bits 9:0 + + + -- Control from AXI to MDM + u01s: cdc_resync PORT MAP (clk, csr_init, hwif_out.MSK_Init.txrxinit.value, txrxinit ); + u02s: cdc_resync PORT MAP (clk, csr_init, hwif_out.MSK_Init.txinit.value OR txrxinit, txinit ); + u03s: cdc_resync PORT MAP (clk, csr_init, hwif_out.MSK_Init.rxinit.value OR txrxinit, rxinit ); + u04s: cdc_resync PORT MAP (clk, csr_init, hwif_out.MSK_Control.ptt.value, ptt ); + u05s: cdc_resync PORT MAP (clk, csr_init, hwif_out.MSK_Control.loopback_ena.value, loopback_ena ); + u06s: cdc_resync PORT MAP (clk, csr_init, hwif_out.MSK_Control.diff_encoder_loopback.value, diff_encdec_lbk_ena ); + u07s: cdc_resync PORT MAP (clk, csr_init, hwif_out.MSK_Control.rx_invert.value, rx_invert ); + u08s: cdc_resync PORT MAP (clk, csr_init, hwif_out.MSK_Control.clear_counts.value, clear_counts ); + u09s: cdc_resync PORT MAP (clk, csr_init, hwif_out.LPF_Config_0.lpf_freeze.value, lpf_freeze ); + u10s: cdc_resync PORT MAP (clk, csr_init, hwif_out.LPF_Config_0.lpf_zero.value, lpf_zero ); + u11s: cdc_resync PORT MAP (clk, csr_init, hwif_out.PRBS_Control.prbs_sel.value, prbs_sel ); + u12s: cdc_resync PORT MAP (clk, csr_init, hwif_out.PRBS_Control.prbs_clear.value, prbs_clear ); + u13s: cdc_resync PORT MAP (clk, csr_init, hwif_out.PRBS_Control.prbs_error_insert.value, prbs_err_insert ); + u14s: cdc_resync PORT MAP (clk, csr_init, hwif_out.PRBS_Control.prbs_manual_sync.value, prbs_manual_sync ); + u15s: cdc_resync PORT MAP (clk, csr_init, hwif_out.Tx_Sync_Ctrl.tx_sync_ena.value, tx_sync_ena ); + u16s: cdc_resync PORT MAP (clk, csr_init, hwif_out.Tx_Sync_Ctrl.tx_sync_force.value, tx_sync_force ); + + -- The remaining control signals also cross from the AXI to the local clock domain. These are static signals + -- that are configured while the txrxinit is active. The active txrxinit hold the destination FFs to an + -- initial state preventing meta-stable conditions. + freq_word_ft <= hwif_out.Fb_FreqWord.config_data.value; + freq_word_tx_f1 <= hwif_out.TX_F1_FreqWord.config_data.value; + freq_word_tx_f2 <= hwif_out.TX_F2_FreqWord.config_data.value; + freq_word_rx_f1 <= hwif_out.RX_F1_FreqWord.config_data.value; + freq_word_rx_f2 <= hwif_out.RX_F2_FreqWord.config_data.value; + + lpf_alpha <= hwif_out.LPF_Config_0.lpf_alpha.value; + lpf_i_gain <= hwif_out.LPF_Config_1.i_gain.value; + lpf_i_shift <= hwif_out.LPF_Config_1.i_shift.value; + lpf_p_gain <= hwif_out.LPF_Config_2.p_gain.value; + lpf_p_shift <= hwif_out.LPF_Config_2.p_shift.value; + + tx_data_w <= hwif_out.Tx_Data_Width.data_width.value; + rx_data_w <= hwif_out.Rx_Data_Width.data_width.value; + discard_rxsamples <= hwif_out.Rx_Sample_Discard.rx_sample_discard.value; + discard_rxnco <= hwif_out.Rx_Sample_Discard.rx_nco_discard.value; + + prbs_initial <= hwif_out.PRBS_Initial_State.config_data.value; + prbs_poly <= hwif_out.PRBS_Polynomial.config_data.value; + prbs_err_mask <= hwif_out.PRBS_Error_Mask.config_data.value; + prbs_sync_threshold <= hwif_out.PRBS_Control.prbs_sync_threshold.value; + + tx_sync_cnt <= hwif_out.Tx_Sync_Cnt.tx_sync_cnt.value; + + pd_alpha1 <= hwif_out.lowpass_ema_alpha1.alpha.value; + pd_alpha2 <= hwif_out.lowpass_ema_alpha2.alpha.value; END ARCHITECTURE rtl; diff --git a/src/ov_frame_decoder.vhd b/src/ov_frame_decoder.vhd new file mode 100644 index 0000000..717feb6 --- /dev/null +++ b/src/ov_frame_decoder.vhd @@ -0,0 +1,436 @@ +------------------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------ +-- _______ ________ ______ +-- __ __ \________ _____ _______ ___ __ \_____ _____________ ______ ___________________ /_ +-- _ / / /___ __ \_ _ \__ __ \ __ /_/ /_ _ \__ ___/_ _ \_ __ `/__ ___/_ ___/__ __ \ +-- / /_/ / __ /_/ // __/_ / / / _ _, _/ / __/_(__ ) / __// /_/ / _ / / /__ _ / / / +-- \____/ _ .___/ \___/ /_/ /_/ /_/ |_| \___/ /____/ \___/ \__,_/ /_/ \___/ /_/ /_/ +-- /_/ +-- ________ _____ _____ _____ _____ +-- ____ _/_______ __________ /____(_)__ /_____ ____ /______ +-- __ / __ __ \__ ___/_ __/__ / _ __/_ / / /_ __/_ _ \ +-- __/ / _ / / /_(__ ) / /_ _ / / /_ / /_/ / / /_ / __/ +-- /___/ /_/ /_/ /____/ \__/ /_/ \__/ \__,_/ \__/ \___/ +-- +------------------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------ +-- Copyright +------------------------------------------------------------------------------------------------------ +-- +-- Copyright 2025 by Open Research Institute +-- +------------------------------------------------------------------------------------------------------ +-- License +------------------------------------------------------------------------------------------------------ +-- +-- This source describes Open Hardware and is licensed under the CERN-OHL-W v2. +-- +-- You may redistribute and modify this source and make products using it under +-- the terms of the CERN-OHL-W v2 (https://ohwr.org/cern_ohl_w_v2.txt). +-- +-- This source is distributed WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING +-- OF MERCHANTABILITY, SATISFACTORY QUALITY AND FITNESS FOR A PARTICULAR PURPOSE. +-- Please see the CERN-OHL-W v2 for applicable conditions. +-- +------------------------------------------------------------------------------------------------------ +-- Block name and description +------------------------------------------------------------------------------------------------------ +-- +-- Opulent Voice Protocol Frame Decoder - DUAL MODE (Bit-level or Byte-level Deinterleaver) +-- +-- This module implements the RX path processing for OVP frames (reverse of encoder): +-- 1. Collects 268 bytes of encoded data from AXI-Stream input +-- 2. Deinterleaves using bit-level (67x32) or byte-level (67x4) based on generic +-- 3. Applies FEC decoding via Viterbi decoder +-- 4. Derandomizes (XOR with same fixed sequence) +-- 5. Outputs 134 bytes of payload via AXI-Stream +-- +-- UPDATED (2025-12-16): Re-enabled bit-level deinterleaver support for protocol compliance +-- USE_BIT_INTERLEAVER = TRUE : 67x32 bit-level (correct protocol) +-- USE_BIT_INTERLEAVER = FALSE : 67x4 byte-level (PlutoSDR compatibility) +-- +------------------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------ + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +ENTITY ov_frame_decoder IS + GENERIC ( + PAYLOAD_BYTES : NATURAL := 134; -- Output frame size + ENCODED_BYTES : NATURAL := 268; -- Input frame size + ENCODED_BITS : NATURAL := 2144; -- Encoded bits (268 * 8) + BYTE_WIDTH : NATURAL := 8; + USE_BIT_INTERLEAVER : BOOLEAN := TRUE -- TRUE=bit-level(67x32), FALSE=byte-level(67x4) + ); + PORT ( + clk : IN std_logic; + aresetn : IN std_logic; + + -- Input AXI-Stream (268-byte encoded frames) + s_axis_tdata : IN std_logic_vector(BYTE_WIDTH-1 DOWNTO 0); + s_axis_tvalid : IN std_logic; + s_axis_tready : OUT std_logic; + s_axis_tlast : IN std_logic; + + -- Output AXI-Stream (134-byte payload frames) + m_axis_tdata : OUT std_logic_vector(BYTE_WIDTH-1 DOWNTO 0); + m_axis_tvalid : OUT std_logic; + m_axis_tready : IN std_logic; + m_axis_tlast : OUT std_logic; + + -- Status outputs + frames_decoded : OUT std_logic_vector(31 DOWNTO 0); + decoder_active : OUT std_logic; + + -- Debug outputs for hardware visibility + debug_state : OUT std_logic_vector(2 DOWNTO 0); + debug_viterbi_start : OUT std_logic; + debug_viterbi_busy : OUT std_logic; + debug_viterbi_done : OUT std_logic + ); +END ENTITY ov_frame_decoder; + +ARCHITECTURE rtl OF ov_frame_decoder IS + + -- State machine + TYPE state_t IS (IDLE, COLLECT, EXTRACT, DEINTERLEAVE, PREP_FEC_DECODE, FEC_DECODE, DERANDOMIZE, OUTPUT); + SIGNAL state : state_t := IDLE; + + -- Circular collection buffer - use block RAM style + CONSTANT COLLECT_SIZE : NATURAL := 512; + TYPE collect_buffer_t IS ARRAY(0 TO COLLECT_SIZE-1) OF std_logic_vector(BYTE_WIDTH-1 DOWNTO 0); + SIGNAL collect_buffer : collect_buffer_t; + ATTRIBUTE ram_style : STRING; + ATTRIBUTE ram_style OF collect_buffer : SIGNAL IS "block"; + SIGNAL collect_idx : NATURAL RANGE 0 TO COLLECT_SIZE-1; + + -- Buffer types + TYPE byte_buffer_t IS ARRAY(0 TO PAYLOAD_BYTES-1) OF std_logic_vector(BYTE_WIDTH-1 DOWNTO 0); + TYPE encoded_byte_buffer_t IS ARRAY(0 TO ENCODED_BYTES-1) OF std_logic_vector(BYTE_WIDTH-1 DOWNTO 0); + TYPE bit_buffer_t IS ARRAY(0 TO ENCODED_BITS-1) OF std_logic; + + -- Processing buffers + SIGNAL input_buffer : encoded_byte_buffer_t; -- 268 bytes extracted from circular buffer + SIGNAL input_bits : bit_buffer_t; -- 2144 bits unpacked (for bit-level mode) + SIGNAL deinterleaved_bits : bit_buffer_t; -- 2144 bits after bit-level deinterleaving + SIGNAL deinterleaved_buffer : encoded_byte_buffer_t; -- 268 bytes after byte-level deinterleaving + SIGNAL fec_decoded_buffer : byte_buffer_t; + SIGNAL output_buffer : byte_buffer_t; + + -- Index counters + SIGNAL byte_idx : NATURAL RANGE 0 TO ENCODED_BYTES; + SIGNAL bit_idx : NATURAL RANGE 0 TO ENCODED_BITS; + SIGNAL out_idx : NATURAL RANGE 0 TO PAYLOAD_BYTES; + + -- Frame counter + SIGNAL frame_count : UNSIGNED(31 DOWNTO 0) := (OTHERS => '0'); + + -- Output holding registers + SIGNAL m_tdata_reg : std_logic_vector(BYTE_WIDTH-1 DOWNTO 0); + SIGNAL m_tvalid_reg : std_logic; + SIGNAL m_tlast_reg : std_logic; + + -- OVP Randomizer sequence (same as encoder) + TYPE randomizer_t IS ARRAY(0 TO PAYLOAD_BYTES-1) OF std_logic_vector(7 DOWNTO 0); + CONSTANT RANDOMIZER_SEQUENCE : randomizer_t := ( + x"A3", x"81", x"5C", x"C4", x"C9", x"08", x"0E", x"53", + x"CC", x"A1", x"FB", x"29", x"9E", x"4F", x"16", x"E0", + x"97", x"4E", x"2B", x"57", x"12", x"A7", x"3F", x"C2", + x"4D", x"6B", x"0F", x"08", x"30", x"46", x"11", x"56", + x"0D", x"1A", x"13", x"E7", x"50", x"97", x"61", x"F3", + x"BE", x"E3", x"99", x"B0", x"64", x"39", x"22", x"2C", + x"F0", x"09", x"E1", x"86", x"CF", x"73", x"59", x"C2", + x"5C", x"8E", x"E3", x"D7", x"3F", x"70", x"D4", x"27", + x"C2", x"E0", x"81", x"92", x"DA", x"FC", x"CA", x"5A", + x"80", x"42", x"83", x"15", x"0F", x"A2", x"9E", x"15", + x"9C", x"8B", x"DB", x"A4", x"46", x"1C", x"10", x"9F", + x"B3", x"47", x"6C", x"5E", x"15", x"12", x"1F", x"AD", + x"38", x"3D", x"03", x"BA", x"90", x"8D", x"BE", x"D3", + x"65", x"23", x"32", x"B8", x"AB", x"10", x"62", x"7E", + x"C6", x"26", x"7C", x"13", x"C9", x"65", x"3D", x"15", + x"15", x"ED", x"35", x"F4", x"57", x"F5", x"58", x"11", + x"9D", x"8E", x"E8", x"34", x"C9", x"59" + ); + + -- Viterbi decoder signals + SIGNAL decoder_start : std_logic := '0'; + SIGNAL decoder_busy : std_logic; + SIGNAL decoder_done : std_logic; + SIGNAL decoder_input_g1 : std_logic_vector(2143 DOWNTO 0); + SIGNAL decoder_input_g2 : std_logic_vector(2143 DOWNTO 0); + SIGNAL decoder_output_buf : std_logic_vector(1071 DOWNTO 0); + + -- Prevent optimization + ATTRIBUTE dont_touch : STRING; + ATTRIBUTE dont_touch OF U_DECODER : LABEL IS "true"; + ATTRIBUTE ram_style OF input_bits : SIGNAL IS "block"; + ATTRIBUTE ram_style OF deinterleaved_bits : SIGNAL IS "block"; + + ---------------------------------------------------------------------------- + -- BIT-LEVEL DEINTERLEAVER (67x32) - Reverse of encoder's bit interleave + ---------------------------------------------------------------------------- + -- Encoder: output_pos = (input_pos mod 32) * 67 + (input_pos / 32) + -- Decoder (reverse): given output_pos j, find input_pos i + -- col = j / 67, row = j mod 67 + -- input_pos = row * 32 + col + ---------------------------------------------------------------------------- + FUNCTION reverse_deinterleave_bit(addr : NATURAL) RETURN NATURAL IS + CONSTANT ROWS : NATURAL := 67; + CONSTANT COLS : NATURAL := 32; + VARIABLE row : NATURAL; + VARIABLE col : NATURAL; + BEGIN + col := addr / ROWS; -- 0-31 + row := addr MOD ROWS; -- 0-66 + RETURN row * COLS + col; + END FUNCTION; + ---------------------------------------------------------------------------- + -- FORWARD INTERLEAVE ADDRESS (needed for correct deinterleaving) + -- This is the SAME function the encoder uses - we read from where it wrote + ---------------------------------------------------------------------------- + FUNCTION interleave_address_bit(bit_addr : NATURAL) RETURN NATURAL IS + CONSTANT NUM_ROWS : NATURAL := 67; + CONSTANT NUM_COLS : NATURAL := 32; + VARIABLE row, col : NATURAL; + BEGIN + row := bit_addr / NUM_COLS; + col := bit_addr MOD NUM_COLS; + RETURN col * NUM_ROWS + row; + END FUNCTION; + + + + ---------------------------------------------------------------------------- + -- BYTE-LEVEL DEINTERLEAVER (67x4) - Reverse of encoder's byte interleave + ---------------------------------------------------------------------------- + FUNCTION reverse_deinterleave_byte(addr : NATURAL) RETURN NATURAL IS + CONSTANT ROWS : NATURAL := 67; + CONSTANT COLS : NATURAL := 4; + VARIABLE row : NATURAL; + VARIABLE col : NATURAL; + BEGIN + row := addr / COLS; -- 0-66 (output row) + col := addr MOD COLS; -- 0-3 (output column) + RETURN col * ROWS + row; + END FUNCTION; + +BEGIN + + -- Viterbi Decoder Instantiation + U_DECODER : ENTITY work.viterbi_decoder_k7_simple + GENERIC MAP ( + PAYLOAD_BITS => PAYLOAD_BYTES * 8, + ENCODED_BITS => ENCODED_BYTES * 8, + TRACEBACK_DEPTH => 35 + ) + PORT MAP ( + clk => clk, + aresetn => aresetn, + start => decoder_start, + busy => decoder_busy, + done => decoder_done, + input_bits_g1 => decoder_input_g1, + input_bits_g2 => decoder_input_g2, + output_bits => decoder_output_buf + ); + + -- Output assignments + m_axis_tdata <= m_tdata_reg; + m_axis_tvalid <= m_tvalid_reg; + m_axis_tlast <= m_tlast_reg; + + frames_decoded <= std_logic_vector(frame_count); + + -- Debug output assignments + debug_viterbi_start <= decoder_start; + debug_viterbi_busy <= decoder_busy; + debug_viterbi_done <= decoder_done; + + -- State encoding for debug (3 bits for 8 states) + WITH state SELECT debug_state <= + "000" WHEN IDLE, + "001" WHEN COLLECT, + "010" WHEN EXTRACT, + "011" WHEN DEINTERLEAVE, + "100" WHEN PREP_FEC_DECODE, + "101" WHEN FEC_DECODE, + "110" WHEN DERANDOMIZE, + "111" WHEN OUTPUT; + + -- Main FSM + decoder_fsm : PROCESS(clk) + VARIABLE extract_start : INTEGER; + BEGIN + IF rising_edge(clk) THEN + IF aresetn = '0' THEN + state <= IDLE; + byte_idx <= 0; + bit_idx <= 0; + out_idx <= 0; + collect_idx <= 0; + frame_count <= (OTHERS => '0'); + s_axis_tready <= '0'; + m_tvalid_reg <= '0'; + m_tlast_reg <= '0'; + decoder_active <= '0'; + decoder_start <= '0'; + + ELSE + CASE state IS + + WHEN IDLE => + decoder_active <= '0'; + s_axis_tready <= '0'; + m_tvalid_reg <= '0'; + collect_idx <= 0; + + IF s_axis_tvalid = '1' THEN + state <= COLLECT; + s_axis_tready <= '1'; + END IF; + + WHEN COLLECT => + s_axis_tready <= '1'; + + IF s_axis_tvalid = '1' THEN + collect_buffer(collect_idx) <= s_axis_tdata; + + IF collect_idx < COLLECT_SIZE - 1 THEN + collect_idx <= collect_idx + 1; + ELSE + collect_idx <= 0; + END IF; + + IF s_axis_tlast = '1' THEN + s_axis_tready <= '0'; + byte_idx <= 0; + state <= EXTRACT; + END IF; + END IF; + + WHEN EXTRACT => + IF byte_idx < ENCODED_BYTES THEN + extract_start := (collect_idx - ENCODED_BYTES + COLLECT_SIZE) MOD COLLECT_SIZE; + input_buffer(byte_idx) <= collect_buffer((extract_start + byte_idx) MOD COLLECT_SIZE); + byte_idx <= byte_idx + 1; + ELSE + IF USE_BIT_INTERLEAVER THEN + -- Unpack bytes to bits for bit-level deinterleaving + FOR i IN 0 TO ENCODED_BYTES - 1 LOOP + FOR j IN 0 TO 7 LOOP + input_bits(i*8 + j) <= input_buffer(i)(j); + END LOOP; + END LOOP; + bit_idx <= 0; + ELSE + byte_idx <= 0; + END IF; + state <= DEINTERLEAVE; + decoder_active <= '1'; + END IF; + + -- DEINTERLEAVE: Reverse the interleaving (bit-level or byte-level) + WHEN DEINTERLEAVE => + IF USE_BIT_INTERLEAVER THEN + -- BIT-LEVEL mode: Process 1 bit per clock (2144 clocks) + IF bit_idx < ENCODED_BITS THEN + deinterleaved_bits(bit_idx) <= input_bits(interleave_address_bit(bit_idx)); + bit_idx <= bit_idx + 1; + ELSE + byte_idx <= 0; + state <= PREP_FEC_DECODE; + END IF; + ELSE + -- BYTE-LEVEL mode: Process 1 byte per clock (268 clocks) + IF byte_idx < ENCODED_BYTES THEN + -- Read from reverse-computed address, write sequentially + deinterleaved_buffer(byte_idx) <= input_buffer(reverse_deinterleave_byte(byte_idx)); + byte_idx <= byte_idx + 1; + ELSE + byte_idx <= 0; + state <= PREP_FEC_DECODE; + END IF; + END IF; + + -- PREP_FEC_DECODE: Unpack deinterleaved data to G1/G2 bit streams + WHEN PREP_FEC_DECODE => + IF USE_BIT_INTERLEAVER THEN + -- Bit-level mode: deinterleaved_bits already contains bit stream + -- Extract G1 (even positions) and G2 (odd positions) + FOR i IN 0 TO ENCODED_BITS/2 - 1 LOOP + decoder_input_g1(i) <= deinterleaved_bits(i*2); + decoder_input_g2(i) <= deinterleaved_bits(i*2 + 1); + END LOOP; + ELSE + -- Byte-level mode: unpack bytes to g1/g2 streams + -- Each byte contributes 4 bits to g1 (even bit positions) and 4 bits to g2 (odd bit positions) + FOR i IN 0 TO ENCODED_BYTES - 1 LOOP + decoder_input_g1(i*4 + 0) <= deinterleaved_buffer(i)(0); + decoder_input_g1(i*4 + 1) <= deinterleaved_buffer(i)(2); + decoder_input_g1(i*4 + 2) <= deinterleaved_buffer(i)(4); + decoder_input_g1(i*4 + 3) <= deinterleaved_buffer(i)(6); + decoder_input_g2(i*4 + 0) <= deinterleaved_buffer(i)(1); + decoder_input_g2(i*4 + 1) <= deinterleaved_buffer(i)(3); + decoder_input_g2(i*4 + 2) <= deinterleaved_buffer(i)(5); + decoder_input_g2(i*4 + 3) <= deinterleaved_buffer(i)(7); + END LOOP; + END IF; + + -- Start Viterbi and wait for busy acknowledgment + decoder_start <= '1'; + IF decoder_busy = '1' THEN + state <= FEC_DECODE; + END IF; + + WHEN FEC_DECODE => + decoder_start <= '0'; + IF decoder_done = '1' THEN + -- Unpack decoded bits to bytes (reverse order for encoder compatibility) + FOR i IN 0 TO PAYLOAD_BYTES-1 LOOP + FOR j IN 0 TO 7 LOOP + fec_decoded_buffer(i)(j) <= decoder_output_buf(PAYLOAD_BYTES*8 - 1 - i*8 - j); + END LOOP; + END LOOP; + byte_idx <= 0; + state <= DERANDOMIZE; + END IF; + + WHEN DERANDOMIZE => + IF byte_idx < PAYLOAD_BYTES THEN + output_buffer(byte_idx) <= + fec_decoded_buffer(byte_idx) XOR RANDOMIZER_SEQUENCE(byte_idx); + byte_idx <= byte_idx + 1; + ELSE + out_idx <= 0; + state <= OUTPUT; + END IF; + + WHEN OUTPUT => + IF out_idx < PAYLOAD_BYTES THEN + m_tdata_reg <= output_buffer(out_idx); + m_tvalid_reg <= '1'; + + IF out_idx = PAYLOAD_BYTES - 1 THEN + m_tlast_reg <= '1'; + ELSE + m_tlast_reg <= '0'; + END IF; + + IF m_axis_tready = '1' OR m_tvalid_reg = '0' THEN + out_idx <= out_idx + 1; + END IF; + ELSE + m_tvalid_reg <= '0'; + m_tlast_reg <= '0'; + frame_count <= frame_count + 1; + state <= IDLE; + END IF; + + END CASE; + END IF; + END IF; + END PROCESS decoder_fsm; + +END ARCHITECTURE rtl; diff --git a/src/ov_frame_decoder.vhd.backup b/src/ov_frame_decoder.vhd.backup new file mode 100644 index 0000000..5e2e8eb --- /dev/null +++ b/src/ov_frame_decoder.vhd.backup @@ -0,0 +1,435 @@ +------------------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------ +-- _______ ________ ______ +-- __ __ \________ _____ _______ ___ __ \_____ _____________ ______ ___________________ /_ +-- _ / / /___ __ \_ _ \__ __ \ __ /_/ /_ _ \__ ___/_ _ \_ __ `/__ ___/_ ___/__ __ \ +-- / /_/ / __ /_/ // __/_ / / / _ _, _/ / __/_(__ ) / __// /_/ / _ / / /__ _ / / / +-- \____/ _ .___/ \___/ /_/ /_/ /_/ |_| \___/ /____/ \___/ \__,_/ /_/ \___/ /_/ /_/ +-- /_/ +-- ________ _____ _____ _____ _____ +-- ____ _/_______ __________ /____(_)__ /_____ ____ /______ +-- __ / __ __ \__ ___/_ __/__ / _ __/_ / / /_ __/_ _ \ +-- __/ / _ / / /_(__ ) / /_ _ / / /_ / /_/ / / /_ / __/ +-- /___/ /_/ /_/ /____/ \__/ /_/ \__/ \__,_/ \__/ \___/ +-- +------------------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------ +-- Copyright +------------------------------------------------------------------------------------------------------ +-- +-- Copyright 2025 by Open Research Institute +-- +------------------------------------------------------------------------------------------------------ +-- License +------------------------------------------------------------------------------------------------------ +-- +-- This source describes Open Hardware and is licensed under the CERN-OHL-W v2. +-- +-- You may redistribute and modify this source and make products using it under +-- the terms of the CERN-OHL-W v2 (https://ohwr.org/cern_ohl_w_v2.txt). +-- +-- This source is distributed WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING +-- OF MERCHANTABILITY, SATISFACTORY QUALITY AND FITNESS FOR A PARTICULAR PURPOSE. +-- Please see the CERN-OHL-W v2 for applicable conditions. +-- +------------------------------------------------------------------------------------------------------ +-- Block name and description +------------------------------------------------------------------------------------------------------ +-- +-- Opulent Voice Protocol Frame Decoder +-- +-- This module implements the RX path processing for OVP frames (reverse of encoder): +-- 1. Collects 268 bytes of encoded data from AXI-Stream input +-- 2. Deinterleaves bits (reverse 67x32 row-column interleaver) +-- 3. Applies FEC decoding (majority vote on bit pairs) +-- 4. Derandomizes (XOR with same fixed sequence) +-- 5. Outputs 134 bytes of payload via AXI-Stream +-- +-- CIRCULAR BUFFER FIX (2025-11-20): Matching encoder's proven strategy +-- - Collect ALL incoming bytes into circular buffer +-- - When tlast arrives, count back 268 bytes +-- - This handles FIFO timing issues naturally +-- - Never try to time the "first" byte arrival +-- +-- VITERBI HANDSHAKE FIX (2025-11-26): Fixed race condition in PREP_FEC_DECODE +-- - decoder_start was only HIGH for 1 clock cycle +-- - If Viterbi was still in COMPLETE state, it missed the pulse +-- - Now holds decoder_start HIGH until decoder_busy='1' +-- - This ensures proper handshake regardless of Viterbi state +-- - Bug only appeared with back-to-back frames (no inter-frame gap) +-- +------------------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------ + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +ENTITY ov_frame_decoder IS + GENERIC ( + PAYLOAD_BYTES : NATURAL := 134; -- Output frame size + ENCODED_BYTES : NATURAL := 268; -- Input frame size + ENCODED_BITS : NATURAL := 2144; -- Encoded bits (268 * 8) + BYTE_WIDTH : NATURAL := 8; + USE_BIT_INTERLEAVER : BOOLEAN := TRUE -- Must match encoder setting + ); + PORT ( + clk : IN std_logic; + aresetn : IN std_logic; + + -- Input AXI-Stream (268-byte encoded frames) + s_axis_tdata : IN std_logic_vector(BYTE_WIDTH-1 DOWNTO 0); + s_axis_tvalid : IN std_logic; + s_axis_tready : OUT std_logic; + s_axis_tlast : IN std_logic; + + -- Output AXI-Stream (134-byte payload frames) + m_axis_tdata : OUT std_logic_vector(BYTE_WIDTH-1 DOWNTO 0); + m_axis_tvalid : OUT std_logic; + m_axis_tready : IN std_logic; + m_axis_tlast : OUT std_logic; + + -- Status outputs + frames_decoded : OUT std_logic_vector(31 DOWNTO 0); + decoder_active : OUT std_logic + ); +END ENTITY ov_frame_decoder; + +ARCHITECTURE rtl OF ov_frame_decoder IS + + -- State machine - ADDED EXTRACT STATE + TYPE state_t IS (IDLE, COLLECT, EXTRACT, DEINTERLEAVE, PREP_FEC_DECODE, FEC_DECODE, DERANDOMIZE, OUTPUT); + SIGNAL state : state_t := IDLE; + + -- Circular collection buffer (2x encoded size for safety) + CONSTANT COLLECT_SIZE : NATURAL := 512; + TYPE collect_buffer_t IS ARRAY(0 TO COLLECT_SIZE-1) OF std_logic_vector(BYTE_WIDTH-1 DOWNTO 0); + SIGNAL collect_buffer : collect_buffer_t; + SIGNAL collect_idx : NATURAL RANGE 0 TO COLLECT_SIZE-1; + + -- Buffer types + TYPE byte_buffer_t IS ARRAY(0 TO PAYLOAD_BYTES-1) OF std_logic_vector(BYTE_WIDTH-1 DOWNTO 0); + TYPE encoded_byte_buffer_t IS ARRAY(0 TO ENCODED_BYTES-1) OF std_logic_vector(BYTE_WIDTH-1 DOWNTO 0); + TYPE bit_buffer_t IS ARRAY(0 TO ENCODED_BITS-1) OF std_logic; + + -- Processing buffers + SIGNAL input_buffer : encoded_byte_buffer_t; -- 268 bytes extracted from circular buffer + SIGNAL deinterleaved_buffer : bit_buffer_t := (OTHERS => '0'); + SIGNAL fec_decoded_buffer : byte_buffer_t; + SIGNAL output_buffer : byte_buffer_t; + + -- Index counters + SIGNAL byte_idx : NATURAL RANGE 0 TO ENCODED_BYTES; + SIGNAL bit_idx : NATURAL RANGE 0 TO ENCODED_BITS; + SIGNAL out_idx : NATURAL RANGE 0 TO PAYLOAD_BYTES; + + -- Frame counter + SIGNAL frame_count : UNSIGNED(31 DOWNTO 0) := (OTHERS => '0'); + + -- Output holding registers + SIGNAL m_tdata_reg : std_logic_vector(BYTE_WIDTH-1 DOWNTO 0); + SIGNAL m_tvalid_reg : std_logic; + SIGNAL m_tlast_reg : std_logic; + + -- OVP Randomizer sequence (same as encoder) + TYPE randomizer_t IS ARRAY(0 TO PAYLOAD_BYTES-1) OF std_logic_vector(7 DOWNTO 0); + CONSTANT RANDOMIZER_SEQUENCE : randomizer_t := ( + x"A3", x"81", x"5C", x"C4", x"C9", x"08", x"0E", x"53", + x"CC", x"A1", x"FB", x"29", x"9E", x"4F", x"16", x"E0", + x"97", x"4E", x"2B", x"57", x"12", x"A7", x"3F", x"C2", + x"4D", x"6B", x"0F", x"08", x"30", x"46", x"11", x"56", + x"0D", x"1A", x"13", x"E7", x"50", x"97", x"61", x"F3", + x"BE", x"E3", x"99", x"B0", x"64", x"39", x"22", x"2C", + x"F0", x"09", x"E1", x"86", x"CF", x"73", x"59", x"C2", + x"5C", x"8E", x"E3", x"D7", x"3F", x"70", x"D4", x"27", + x"C2", x"E0", x"81", x"92", x"DA", x"FC", x"CA", x"5A", + x"80", x"42", x"83", x"15", x"0F", x"A2", x"9E", x"15", + x"9C", x"8B", x"DB", x"A4", x"46", x"1C", x"10", x"9F", + x"B3", x"47", x"6C", x"5E", x"15", x"12", x"1F", x"AD", + x"38", x"3D", x"03", x"BA", x"90", x"8D", x"BE", x"D3", + x"65", x"23", x"32", x"B8", x"AB", x"10", x"62", x"7E", + x"C6", x"26", x"7C", x"13", x"C9", x"65", x"3D", x"15", + x"15", x"ED", x"35", x"F4", x"57", x"F5", x"58", x"11", + x"9D", x"8E", x"E8", x"34", x"C9", x"59" + ); + + -- Viterbi decoder signals + SIGNAL decoder_start : std_logic := '0'; + SIGNAL decoder_busy : std_logic; + SIGNAL decoder_done : std_logic; + SIGNAL decoder_input_g1 : std_logic_vector(2143 DOWNTO 0); + SIGNAL decoder_input_g2 : std_logic_vector(2143 DOWNTO 0); + SIGNAL decoder_output_buf : std_logic_vector(1071 DOWNTO 0); + + -- Bit-level deinterleaver address calculation (67x32 - reverse of interleaver) + FUNCTION deinterleave_address(addr : NATURAL) RETURN NATURAL IS + CONSTANT ROWS : NATURAL := 67; + CONSTANT COLS : NATURAL := 32; + VARIABLE row : NATURAL; + VARIABLE col : NATURAL; + BEGIN + row := addr MOD ROWS; + col := addr / ROWS; + RETURN row * COLS + col; + END FUNCTION; + + -- Byte-level deinterleaver address calculation (67x4 - reverse of byte interleaver) + FUNCTION deinterleave_address_byte(addr : NATURAL) RETURN NATURAL IS + CONSTANT ROWS : NATURAL := 67; + CONSTANT COLS : NATURAL := 4; + VARIABLE row : NATURAL; + VARIABLE col : NATURAL; + BEGIN + row := addr MOD ROWS; + col := addr / ROWS; + RETURN row * COLS + col; + END FUNCTION; + +BEGIN + + -- Viterbi Decoder Instantiation (Hard Decision) + U_DECODER : ENTITY work.viterbi_decoder_k7_simple + GENERIC MAP ( + PAYLOAD_BITS => PAYLOAD_BYTES * 8, + ENCODED_BITS => ENCODED_BYTES * 8, + TRACEBACK_DEPTH => 35 + ) + PORT MAP ( + clk => clk, + aresetn => aresetn, + start => decoder_start, + busy => decoder_busy, + done => decoder_done, + input_bits_g1 => decoder_input_g1, + input_bits_g2 => decoder_input_g2, + output_bits => decoder_output_buf + ); + + -- Output assignments + m_axis_tdata <= m_tdata_reg; + m_axis_tvalid <= m_tvalid_reg; + m_axis_tlast <= m_tlast_reg; + + frames_decoded <= std_logic_vector(frame_count); + + -- Main FSM with Circular Buffer Collection + decoder_fsm : PROCESS(clk) + VARIABLE extract_start : INTEGER; + VARIABLE extract_end : INTEGER; + BEGIN + IF rising_edge(clk) THEN + IF aresetn = '0' THEN + state <= IDLE; + byte_idx <= 0; + bit_idx <= 0; + out_idx <= 0; + collect_idx <= 0; + frame_count <= (OTHERS => '0'); + s_axis_tready <= '0'; + m_tvalid_reg <= '0'; + m_tlast_reg <= '0'; + decoder_active <= '0'; + decoder_start <= '0'; + + ELSE + CASE state IS + + -- IDLE: Ready to start collecting + WHEN IDLE => + decoder_active <= '0'; + s_axis_tready <= '0'; -- Keep tready LOW in IDLE + m_tvalid_reg <= '0'; + collect_idx <= 0; + + IF s_axis_tvalid = '1' THEN + state <= COLLECT; + s_axis_tready <= '1'; -- Set tready HIGH when entering COLLECT + END IF; + + -- COLLECT: Continuously store ALL incoming bytes into circular buffer + WHEN COLLECT => + s_axis_tready <= '1'; -- Maintain tready HIGH during collection + + IF s_axis_tvalid = '1' THEN + -- Store byte at current circular buffer position + collect_buffer(collect_idx) <= s_axis_tdata; + + -- Debug: Report first few bytes + IF collect_idx < 5 THEN + REPORT "COLLECT: collect_idx=" & INTEGER'IMAGE(collect_idx) & + " data=0x" & INTEGER'IMAGE(to_integer(unsigned(s_axis_tdata))) & + " tlast=" & STD_LOGIC'IMAGE(s_axis_tlast)(2); + END IF; + + -- Check for tlast + IF s_axis_tlast = '1' THEN + REPORT "COLLECT: tlast at collect_idx=" & INTEGER'IMAGE(collect_idx); + + -- Move to EXTRACT state to count back 268 bytes + s_axis_tready <= '0'; + byte_idx <= 0; + state <= EXTRACT; + ELSE + -- Advance circular buffer pointer (wrap around) + IF collect_idx = COLLECT_SIZE - 1 THEN + collect_idx <= 0; + ELSE + collect_idx <= collect_idx + 1; + END IF; + END IF; + END IF; + + -- EXTRACT: Count back ENCODED_BYTES from where tlast arrived + WHEN EXTRACT => + IF byte_idx < ENCODED_BYTES THEN + -- Calculate which byte in collect_buffer to read + -- If collect_idx = 267, we want bytes [0:267] + -- If collect_idx = 300, we want bytes [33:300] + extract_start := (collect_idx + 1) - ENCODED_BYTES; + extract_end := collect_idx; + + -- Copy byte from circular buffer (with modulo wraparound) + input_buffer(byte_idx) <= collect_buffer((extract_start + byte_idx) MOD COLLECT_SIZE); + + IF byte_idx < 5 THEN + REPORT "EXTRACT[" & INTEGER'IMAGE(byte_idx) & + "] from collect_buffer[" & + INTEGER'IMAGE((extract_start + byte_idx) MOD COLLECT_SIZE) & + "] = 0x" & + INTEGER'IMAGE(to_integer(unsigned(collect_buffer((extract_start + byte_idx) MOD COLLECT_SIZE)))); + END IF; + + byte_idx <= byte_idx + 1; + ELSE + REPORT "EXTRACT complete, " & INTEGER'IMAGE(ENCODED_BYTES) & " bytes copied"; + byte_idx <= 0; + bit_idx <= 0; + state <= DEINTERLEAVE; + decoder_active <= '1'; + END IF; + + -- DEINTERLEAVE: Reverse the row-column shuffle + WHEN DEINTERLEAVE => + IF USE_BIT_INTERLEAVER THEN + -- BIT-LEVEL mode: Process 1 bit per clock (2144 clocks) + IF bit_idx < ENCODED_BITS THEN + -- Unpack input_buffer bytes to bits + deinterleaved_buffer(deinterleave_address(bit_idx)) <= + input_buffer(bit_idx / 8)(bit_idx MOD 8); + bit_idx <= bit_idx + 1; + ELSE + REPORT "DEINTERLEAVE complete (bit-level)"; + byte_idx <= 0; + bit_idx <= 0; + state <= PREP_FEC_DECODE; + END IF; + ELSE + -- BYTE-LEVEL mode: Process 1 byte per clock (268 clocks) + IF byte_idx < ENCODED_BYTES THEN + FOR j IN 0 TO 7 LOOP + deinterleaved_buffer(deinterleave_address_byte(byte_idx)*8 + j) <= + input_buffer(byte_idx)(j); + END LOOP; + byte_idx <= byte_idx + 1; + ELSE + REPORT "DEINTERLEAVE complete (byte-level)"; + byte_idx <= 0; + bit_idx <= 0; + state <= PREP_FEC_DECODE; + END IF; + END IF; + + -- PREP_FEC_DECODE: Separate deinterleaved bits into G1 and G2 streams + -- and start the Viterbi decoder with proper handshaking + WHEN PREP_FEC_DECODE => + -- Setup G1/G2 streams for Viterbi decoder + FOR i IN 0 TO ENCODED_BITS/2 - 1 LOOP + decoder_input_g1(i) <= deinterleaved_buffer(i*2); + decoder_input_g2(i) <= deinterleaved_buffer(i*2 + 1); + END LOOP; + + -- Assert start and WAIT for Viterbi to acknowledge via busy signal + -- FIX: Previously decoder_start was only high for 1 clock cycle. + -- If the Viterbi decoder was still in COMPLETE state (transitioning + -- to IDLE), it would miss the start pulse entirely, causing the + -- frame decoder to wait forever for decoder_done. + -- Now we hold decoder_start high until decoder_busy confirms + -- the Viterbi has accepted the request. + decoder_start <= '1'; + IF decoder_busy = '1' THEN + state <= FEC_DECODE; + END IF; + + WHEN FEC_DECODE => + decoder_start <= '0'; + IF decoder_done = '1' THEN + -- Unpack decoded bits in REVERSE order to match encoder's bit reversal + -- Viterbi traceback produces bits in reverse order, compensating for + -- conv encoder's MSB-first processing, but we need to reverse again + -- to match how encoder packed the input + FOR i IN 0 TO PAYLOAD_BYTES-1 LOOP + FOR j IN 0 TO 7 LOOP + fec_decoded_buffer(i)(j) <= decoder_output_buf(PAYLOAD_BYTES*8 - 1 - i*8 - j); + END LOOP; + END LOOP; + byte_idx <= 0; + state <= DERANDOMIZE; + END IF; + + -- DERANDOMIZE: XOR with same sequence (inverse operation) + WHEN DERANDOMIZE => + IF byte_idx < PAYLOAD_BYTES THEN + output_buffer(byte_idx) <= + fec_decoded_buffer(byte_idx) XOR RANDOMIZER_SEQUENCE(byte_idx); + + IF byte_idx < 5 THEN + REPORT "DERANDOMIZE[" & INTEGER'IMAGE(byte_idx) & + "] fec=" & INTEGER'IMAGE(to_integer(unsigned(fec_decoded_buffer(byte_idx)))) & + " rand=" & INTEGER'IMAGE(to_integer(unsigned(RANDOMIZER_SEQUENCE(byte_idx)))) & + " out=" & INTEGER'IMAGE(to_integer(unsigned(fec_decoded_buffer(byte_idx) XOR RANDOMIZER_SEQUENCE(byte_idx)))); + END IF; + + byte_idx <= byte_idx + 1; + ELSE + REPORT "DERANDOMIZE complete"; + out_idx <= 0; + state <= OUTPUT; + END IF; + + -- OUTPUT: Send bytes to next stage (FIXED AXI-Stream handshaking) + WHEN OUTPUT => + IF out_idx < PAYLOAD_BYTES THEN + -- Present current data + m_tdata_reg <= output_buffer(out_idx); + m_tvalid_reg <= '1'; + + IF out_idx < 5 THEN + REPORT "DECODER OUTPUT byte " & INTEGER'IMAGE(out_idx) & " = " & + INTEGER'IMAGE(to_integer(unsigned(output_buffer(out_idx)))); + END IF; + + -- Set tlast on final byte + IF out_idx = PAYLOAD_BYTES - 1 THEN + m_tlast_reg <= '1'; + ELSE + m_tlast_reg <= '0'; + END IF; + + -- Advance on handshake OR on first presentation (tvalid was 0) + IF m_axis_tready = '1' OR m_tvalid_reg = '0' THEN + out_idx <= out_idx + 1; + END IF; + ELSE + -- Frame complete + m_tvalid_reg <= '0'; + m_tlast_reg <= '0'; + frame_count <= frame_count + 1; + state <= IDLE; + END IF; + + END CASE; + END IF; + END IF; + END PROCESS decoder_fsm; + +END ARCHITECTURE rtl; diff --git a/src/ov_frame_decoder.vhd.backup2 b/src/ov_frame_decoder.vhd.backup2 new file mode 100644 index 0000000..a04647c --- /dev/null +++ b/src/ov_frame_decoder.vhd.backup2 @@ -0,0 +1,373 @@ +------------------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------ +-- _______ ________ ______ +-- __ __ \________ _____ _______ ___ __ \_____ _____________ ______ ___________________ /_ +-- _ / / /___ __ \_ _ \__ __ \ __ /_/ /_ _ \__ ___/_ _ \_ __ `/__ ___/_ ___/__ __ \ +-- / /_/ / __ /_/ // __/_ / / / _ _, _/ / __/_(__ ) / __// /_/ / _ / / /__ _ / / / +-- \____/ _ .___/ \___/ /_/ /_/ /_/ |_| \___/ /____/ \___/ \__,_/ /_/ \___/ /_/ /_/ +-- /_/ +-- ________ _____ _____ _____ _____ +-- ____ _/_______ __________ /____(_)__ /_____ ____ /______ +-- __ / __ __ \__ ___/_ __/__ / _ __/_ / / /_ __/_ _ \ +-- __/ / _ / / /_(__ ) / /_ _ / / /_ / /_/ / / /_ / __/ +-- /___/ /_/ /_/ /____/ \__/ /_/ \__/ \__,_/ \__/ \___/ +-- +------------------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------ +-- Copyright +------------------------------------------------------------------------------------------------------ +-- +-- Copyright 2025 by Open Research Institute +-- +------------------------------------------------------------------------------------------------------ +-- License +------------------------------------------------------------------------------------------------------ +-- +-- This source describes Open Hardware and is licensed under the CERN-OHL-W v2. +-- +-- You may redistribute and modify this source and make products using it under +-- the terms of the CERN-OHL-W v2 (https://ohwr.org/cern_ohl_w_v2.txt). +-- +-- This source is distributed WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING +-- OF MERCHANTABILITY, SATISFACTORY QUALITY AND FITNESS FOR A PARTICULAR PURPOSE. +-- Please see the CERN-OHL-W v2 for applicable conditions. +-- +------------------------------------------------------------------------------------------------------ +-- Block name and description +------------------------------------------------------------------------------------------------------ +-- +-- Opulent Voice Protocol Frame Decoder - OPTIMIZED FOR RESOURCE USAGE +-- +-- This module implements the RX path processing for OVP frames (reverse of encoder): +-- 1. Collects 268 bytes of encoded data from AXI-Stream input +-- 2. Deinterleaves bytes (reverse 67x4 row-column byte interleaver) +-- 3. Applies FEC decoding via Viterbi decoder +-- 4. Derandomizes (XOR with same fixed sequence) +-- 5. Outputs 134 bytes of payload via AXI-Stream +-- +-- OPTIMIZATION (2025-12-01): Eliminated bit-level buffer to reduce LUT usage +-- - Changed deinterleaved_buffer from 2144 bits to 268 bytes +-- - Bit extraction to g1/g2 done with constant indexing in FOR loops +-- - This eliminates the massive mux structures from variable bit indexing +-- - Removed bit-level interleaver option (USE_BIT_INTERLEAVER ignored, always byte-level) +-- - Added ram_style attribute for collect_buffer to encourage BRAM inference +-- +------------------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------ + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +ENTITY ov_frame_decoder IS + GENERIC ( + PAYLOAD_BYTES : NATURAL := 134; -- Output frame size + ENCODED_BYTES : NATURAL := 268; -- Input frame size + ENCODED_BITS : NATURAL := 2144; -- Encoded bits (268 * 8) + BYTE_WIDTH : NATURAL := 8; + USE_BIT_INTERLEAVER : BOOLEAN := TRUE -- IGNORED - always uses byte-level for resource efficiency + ); + PORT ( + clk : IN std_logic; + aresetn : IN std_logic; + + -- Input AXI-Stream (268-byte encoded frames) + s_axis_tdata : IN std_logic_vector(BYTE_WIDTH-1 DOWNTO 0); + s_axis_tvalid : IN std_logic; + s_axis_tready : OUT std_logic; + s_axis_tlast : IN std_logic; + + -- Output AXI-Stream (134-byte payload frames) + m_axis_tdata : OUT std_logic_vector(BYTE_WIDTH-1 DOWNTO 0); + m_axis_tvalid : OUT std_logic; + m_axis_tready : IN std_logic; + m_axis_tlast : OUT std_logic; + + -- Status outputs + frames_decoded : OUT std_logic_vector(31 DOWNTO 0); + decoder_active : OUT std_logic; + + -- Debug outputs for hardware visibility + debug_state : OUT std_logic_vector(2 DOWNTO 0); + debug_viterbi_start : OUT std_logic; + debug_viterbi_busy : OUT std_logic; + debug_viterbi_done : OUT std_logic + ); +END ENTITY ov_frame_decoder; + +ARCHITECTURE rtl OF ov_frame_decoder IS + + -- State machine + TYPE state_t IS (IDLE, COLLECT, EXTRACT, DEINTERLEAVE, PREP_FEC_DECODE, FEC_DECODE, DERANDOMIZE, OUTPUT); + SIGNAL state : state_t := IDLE; + + -- Circular collection buffer - use block RAM style + CONSTANT COLLECT_SIZE : NATURAL := 512; + TYPE collect_buffer_t IS ARRAY(0 TO COLLECT_SIZE-1) OF std_logic_vector(BYTE_WIDTH-1 DOWNTO 0); + SIGNAL collect_buffer : collect_buffer_t; + ATTRIBUTE ram_style : STRING; + ATTRIBUTE ram_style OF collect_buffer : SIGNAL IS "block"; + SIGNAL collect_idx : NATURAL RANGE 0 TO COLLECT_SIZE-1; + + -- Buffer types - ALL BYTE-LEVEL for efficient synthesis + TYPE byte_buffer_t IS ARRAY(0 TO PAYLOAD_BYTES-1) OF std_logic_vector(BYTE_WIDTH-1 DOWNTO 0); + TYPE encoded_byte_buffer_t IS ARRAY(0 TO ENCODED_BYTES-1) OF std_logic_vector(BYTE_WIDTH-1 DOWNTO 0); + + -- Processing buffers - all byte-level + SIGNAL input_buffer : encoded_byte_buffer_t; -- 268 bytes extracted from circular buffer + SIGNAL deinterleaved_buffer : encoded_byte_buffer_t; -- 268 bytes after deinterleaving (WAS bit_buffer_t!) + SIGNAL fec_decoded_buffer : byte_buffer_t; + SIGNAL output_buffer : byte_buffer_t; + + -- Index counters + SIGNAL byte_idx : NATURAL RANGE 0 TO ENCODED_BYTES; + SIGNAL out_idx : NATURAL RANGE 0 TO PAYLOAD_BYTES; + + -- Frame counter + SIGNAL frame_count : UNSIGNED(31 DOWNTO 0) := (OTHERS => '0'); + + -- Output holding registers + SIGNAL m_tdata_reg : std_logic_vector(BYTE_WIDTH-1 DOWNTO 0); + SIGNAL m_tvalid_reg : std_logic; + SIGNAL m_tlast_reg : std_logic; + + -- OVP Randomizer sequence (same as encoder) + TYPE randomizer_t IS ARRAY(0 TO PAYLOAD_BYTES-1) OF std_logic_vector(7 DOWNTO 0); + CONSTANT RANDOMIZER_SEQUENCE : randomizer_t := ( + x"A3", x"81", x"5C", x"C4", x"C9", x"08", x"0E", x"53", + x"CC", x"A1", x"FB", x"29", x"9E", x"4F", x"16", x"E0", + x"97", x"4E", x"2B", x"57", x"12", x"A7", x"3F", x"C2", + x"4D", x"6B", x"0F", x"08", x"30", x"46", x"11", x"56", + x"0D", x"1A", x"13", x"E7", x"50", x"97", x"61", x"F3", + x"BE", x"E3", x"99", x"B0", x"64", x"39", x"22", x"2C", + x"F0", x"09", x"E1", x"86", x"CF", x"73", x"59", x"C2", + x"5C", x"8E", x"E3", x"D7", x"3F", x"70", x"D4", x"27", + x"C2", x"E0", x"81", x"92", x"DA", x"FC", x"CA", x"5A", + x"80", x"42", x"83", x"15", x"0F", x"A2", x"9E", x"15", + x"9C", x"8B", x"DB", x"A4", x"46", x"1C", x"10", x"9F", + x"B3", x"47", x"6C", x"5E", x"15", x"12", x"1F", x"AD", + x"38", x"3D", x"03", x"BA", x"90", x"8D", x"BE", x"D3", + x"65", x"23", x"32", x"B8", x"AB", x"10", x"62", x"7E", + x"C6", x"26", x"7C", x"13", x"C9", x"65", x"3D", x"15", + x"15", x"ED", x"35", x"F4", x"57", x"F5", x"58", x"11", + x"9D", x"8E", x"E8", x"34", x"C9", x"59" + ); + + -- Viterbi decoder signals + SIGNAL decoder_start : std_logic := '0'; + SIGNAL decoder_busy : std_logic; + SIGNAL decoder_done : std_logic; + SIGNAL decoder_input_g1 : std_logic_vector(2143 DOWNTO 0); + SIGNAL decoder_input_g2 : std_logic_vector(2143 DOWNTO 0); + SIGNAL decoder_output_buf : std_logic_vector(1071 DOWNTO 0); + + -- Preserve Viterbi interface signals (allow internal optimization) + ATTRIBUTE KEEP : STRING; + ATTRIBUTE KEEP OF decoder_busy : SIGNAL IS "true"; + ATTRIBUTE KEEP OF decoder_done : SIGNAL IS "true"; + ATTRIBUTE KEEP OF decoder_output_buf : SIGNAL IS "true"; + + -- Byte-level deinterleaver: reverse of 67x4 interleaver + -- Input byte at position addr goes to position: (addr MOD 67) * 4 + (addr / 67) + -- Reverse: output position j needs input from: (j MOD 4) * 67 + (j / 4) + FUNCTION reverse_deinterleave_byte(addr : NATURAL) RETURN NATURAL IS + CONSTANT ROWS : NATURAL := 67; + CONSTANT COLS : NATURAL := 4; + VARIABLE row : NATURAL; + VARIABLE col : NATURAL; + BEGIN + row := addr / COLS; -- 0-66 (output row) + col := addr MOD COLS; -- 0-3 (output column) + RETURN col * ROWS + row; + END FUNCTION; + +BEGIN + + -- Viterbi Decoder Instantiation + U_DECODER : ENTITY work.viterbi_decoder_k7_simple + GENERIC MAP ( + PAYLOAD_BITS => PAYLOAD_BYTES * 8, + ENCODED_BITS => ENCODED_BYTES * 8, + TRACEBACK_DEPTH => 35 + ) + PORT MAP ( + clk => clk, + aresetn => aresetn, + start => decoder_start, + busy => decoder_busy, + done => decoder_done, + input_bits_g1 => decoder_input_g1, + input_bits_g2 => decoder_input_g2, + output_bits => decoder_output_buf + ); + + -- Output assignments + m_axis_tdata <= m_tdata_reg; + m_axis_tvalid <= m_tvalid_reg; + m_axis_tlast <= m_tlast_reg; + + frames_decoded <= std_logic_vector(frame_count); + + -- Debug output assignments + debug_viterbi_start <= decoder_start; + debug_viterbi_busy <= decoder_busy; + debug_viterbi_done <= decoder_done; + + -- State encoding for debug (3 bits for 8 states) + WITH state SELECT debug_state <= + "000" WHEN IDLE, + "001" WHEN COLLECT, + "010" WHEN EXTRACT, + "011" WHEN DEINTERLEAVE, + "100" WHEN PREP_FEC_DECODE, + "101" WHEN FEC_DECODE, + "110" WHEN DERANDOMIZE, + "111" WHEN OUTPUT; + + -- Main FSM + decoder_fsm : PROCESS(clk) + VARIABLE extract_start : INTEGER; + BEGIN + IF rising_edge(clk) THEN + IF aresetn = '0' THEN + state <= IDLE; + byte_idx <= 0; + out_idx <= 0; + collect_idx <= 0; + frame_count <= (OTHERS => '0'); + s_axis_tready <= '0'; + m_tvalid_reg <= '0'; + m_tlast_reg <= '0'; + decoder_active <= '0'; + decoder_start <= '0'; + + ELSE + CASE state IS + + WHEN IDLE => + decoder_active <= '0'; + s_axis_tready <= '0'; + m_tvalid_reg <= '0'; + collect_idx <= 0; + + IF s_axis_tvalid = '1' THEN + state <= COLLECT; + s_axis_tready <= '1'; + END IF; + + WHEN COLLECT => + s_axis_tready <= '1'; + + IF s_axis_tvalid = '1' THEN + collect_buffer(collect_idx) <= s_axis_tdata; + + IF collect_idx < COLLECT_SIZE - 1 THEN + collect_idx <= collect_idx + 1; + ELSE + collect_idx <= 0; + END IF; + + IF s_axis_tlast = '1' THEN + s_axis_tready <= '0'; + byte_idx <= 0; + state <= EXTRACT; + END IF; + END IF; + + WHEN EXTRACT => + IF byte_idx < ENCODED_BYTES THEN + extract_start := (collect_idx - ENCODED_BYTES + COLLECT_SIZE) MOD COLLECT_SIZE; + input_buffer(byte_idx) <= collect_buffer((extract_start + byte_idx) MOD COLLECT_SIZE); + byte_idx <= byte_idx + 1; + ELSE + byte_idx <= 0; + state <= DEINTERLEAVE; + decoder_active <= '1'; + END IF; + + -- DEINTERLEAVE: Reverse the 67x4 byte-level shuffle + -- Read from computed position, write to sequential position + WHEN DEINTERLEAVE => + IF byte_idx < ENCODED_BYTES THEN + -- Read from reverse-computed address, write sequentially + deinterleaved_buffer(byte_idx) <= input_buffer(reverse_deinterleave_byte(byte_idx)); + byte_idx <= byte_idx + 1; + ELSE + byte_idx <= 0; + state <= PREP_FEC_DECODE; + END IF; + + -- PREP_FEC_DECODE: Unpack deinterleaved bytes to G1/G2 bit streams + -- Uses constant indexing in FOR loops for efficient synthesis + WHEN PREP_FEC_DECODE => + -- Unpack bytes to g1/g2 streams + -- Each byte contributes 4 bits to g1 (even bit positions) and 4 bits to g2 (odd bit positions) + -- Byte i, bits 0,2,4,6 -> g1[i*4+0..i*4+3] + -- Byte i, bits 1,3,5,7 -> g2[i*4+0..i*4+3] + FOR i IN 0 TO ENCODED_BYTES - 1 LOOP + decoder_input_g1(i*4 + 0) <= deinterleaved_buffer(i)(0); + decoder_input_g1(i*4 + 1) <= deinterleaved_buffer(i)(2); + decoder_input_g1(i*4 + 2) <= deinterleaved_buffer(i)(4); + decoder_input_g1(i*4 + 3) <= deinterleaved_buffer(i)(6); + decoder_input_g2(i*4 + 0) <= deinterleaved_buffer(i)(1); + decoder_input_g2(i*4 + 1) <= deinterleaved_buffer(i)(3); + decoder_input_g2(i*4 + 2) <= deinterleaved_buffer(i)(5); + decoder_input_g2(i*4 + 3) <= deinterleaved_buffer(i)(7); + END LOOP; + + -- Start Viterbi and wait for busy acknowledgment + decoder_start <= '1'; + IF decoder_busy = '1' THEN + state <= FEC_DECODE; + END IF; + + WHEN FEC_DECODE => + decoder_start <= '0'; + IF decoder_done = '1' THEN + -- Unpack decoded bits to bytes (reverse order for encoder compatibility) + FOR i IN 0 TO PAYLOAD_BYTES-1 LOOP + FOR j IN 0 TO 7 LOOP + fec_decoded_buffer(i)(j) <= decoder_output_buf(PAYLOAD_BYTES*8 - 1 - i*8 - j); + END LOOP; + END LOOP; + byte_idx <= 0; + state <= DERANDOMIZE; + END IF; + + WHEN DERANDOMIZE => + IF byte_idx < PAYLOAD_BYTES THEN + output_buffer(byte_idx) <= + fec_decoded_buffer(byte_idx) XOR RANDOMIZER_SEQUENCE(byte_idx); + byte_idx <= byte_idx + 1; + ELSE + out_idx <= 0; + state <= OUTPUT; + END IF; + + WHEN OUTPUT => + IF out_idx < PAYLOAD_BYTES THEN + m_tdata_reg <= output_buffer(out_idx); + m_tvalid_reg <= '1'; + + IF out_idx = PAYLOAD_BYTES - 1 THEN + m_tlast_reg <= '1'; + ELSE + m_tlast_reg <= '0'; + END IF; + + IF m_axis_tready = '1' OR m_tvalid_reg = '0' THEN + out_idx <= out_idx + 1; + END IF; + ELSE + m_tvalid_reg <= '0'; + m_tlast_reg <= '0'; + frame_count <= frame_count + 1; + state <= IDLE; + END IF; + + END CASE; + END IF; + END IF; + END PROCESS decoder_fsm; + +END ARCHITECTURE rtl; diff --git a/src/ov_frame_decoder_soft.vhd b/src/ov_frame_decoder_soft.vhd new file mode 100644 index 0000000..a23c9d2 --- /dev/null +++ b/src/ov_frame_decoder_soft.vhd @@ -0,0 +1,525 @@ +-------------------------------------------------------------------------------- +-- ov_frame_decoder_soft.vhd +-- +-- Opulent Voice Frame Decoder with Soft-Decision Viterbi Decoding +-- +-- This module decodes OV protocol frames using soft-decision Viterbi decoding +-- for improved performance at low SNR. +-- +-- Processing chain (reverse of encoder): +-- 1. COLLECT_BYTES: Receive 268 bytes from frame_sync_detector +-- 2. COLLECT_SOFT: Receive 2144 3-bit soft values +-- 3. EXTRACT: Unpack bytes to bit array +-- 4. DEINTERLEAVE: Reverse 67x32 bit interleaving (hard + soft) +-- 5. PREP_FEC_DECODE: Pack soft G1/G2 streams +-- 6. FEC_DECODE: Soft-decision Viterbi decoding +-- 7. DERANDOMIZE: XOR with CCSDS LFSR (standard pre-FEC randomization) +-- 8. OUTPUT: Stream decoded bytes +-- +-- Soft Value Convention: +-- 0 = strong '0', 7 = strong '1', 3-4 = uncertain +-------------------------------------------------------------------------------- + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +ENTITY ov_frame_decoder_soft IS + GENERIC ( + PAYLOAD_BYTES : NATURAL := 134; + ENCODED_BYTES : NATURAL := 268; + ENCODED_BITS : NATURAL := 2144; + BYTE_WIDTH : NATURAL := 8; + SOFT_WIDTH : NATURAL := 3; + USE_BIT_INTERLEAVER : BOOLEAN := TRUE; + -- Debug bypass controls (must match encoder settings!) + BYPASS_RANDOMIZE : BOOLEAN := FALSE; -- TRUE=skip pre-FEC LFSR derandomization + BYPASS_FEC : BOOLEAN := FALSE; -- TRUE=skip Viterbi, take first 134 bytes + BYPASS_INTERLEAVE : BOOLEAN := FALSE -- TRUE=skip 67x32 bit deinterleaving + ); + PORT ( + clk : IN std_logic; + aresetn : IN std_logic; + + -- AXI-Stream input (hard bytes from frame_sync_detector) + s_axis_tdata : IN std_logic_vector(BYTE_WIDTH-1 DOWNTO 0); + s_axis_tvalid : IN std_logic; + s_axis_tready : OUT std_logic; + s_axis_tlast : IN std_logic; + + -- Soft decision input (bit-level, from frame_sync_detector) + -- Arrives as a burst of 2144 3-bit values AFTER the 268 bytes + s_axis_soft_bit_tdata : IN std_logic_vector(SOFT_WIDTH-1 DOWNTO 0); + s_axis_soft_bit_tvalid : IN std_logic; + s_axis_soft_bit_tready : OUT std_logic; + s_axis_soft_bit_tlast : IN std_logic; + + -- AXI-Stream output (decoded payload) + m_axis_tdata : OUT std_logic_vector(BYTE_WIDTH-1 DOWNTO 0); + m_axis_tvalid : OUT std_logic; + m_axis_tready : IN std_logic; + m_axis_tlast : OUT std_logic; + + -- Status + frames_decoded : OUT std_logic_vector(31 DOWNTO 0); + decoder_active : OUT std_logic; + + -- Debug + debug_state : OUT std_logic_vector(3 DOWNTO 0); -- 4 bits for future expansion + debug_viterbi_start : OUT std_logic; + debug_viterbi_busy : OUT std_logic; + debug_viterbi_done : OUT std_logic; + debug_path_metric : OUT std_logic_vector(15 DOWNTO 0) + ); +END ENTITY ov_frame_decoder_soft; + +ARCHITECTURE rtl OF ov_frame_decoder_soft IS + + ------------------------------------------------------------------------------ + -- CCSDS LFSR Functions (for DERANDOMIZE - standard pre-FEC randomization) + ------------------------------------------------------------------------------ + -- Polynomial: x^8 + x^7 + x^5 + x^3 + 1 (CCSDS standard randomizer) + -- Period: 255 bits + ------------------------------------------------------------------------------ + + -- Generate 8 output bits from LFSR (for byte-level XOR in DERANDOMIZE) + FUNCTION lfsr_output_byte(seed : std_logic_vector(7 DOWNTO 0)) + RETURN std_logic_vector IS + VARIABLE lfsr : std_logic_vector(7 DOWNTO 0) := seed; + VARIABLE result : std_logic_vector(7 DOWNTO 0); + VARIABLE feedback : std_logic; + BEGIN + FOR i IN 7 DOWNTO 0 LOOP + result(i) := lfsr(7); -- Output bit (MSB) + feedback := lfsr(7) XOR lfsr(6) XOR lfsr(4) XOR lfsr(2); + lfsr := lfsr(6 DOWNTO 0) & feedback; + END LOOP; + RETURN result; + END FUNCTION; + + -- Compute LFSR state after 8 advances + FUNCTION lfsr_advance_8(seed : std_logic_vector(7 DOWNTO 0)) + RETURN std_logic_vector IS + VARIABLE lfsr : std_logic_vector(7 DOWNTO 0) := seed; + VARIABLE feedback : std_logic; + BEGIN + FOR i IN 0 TO 7 LOOP + feedback := lfsr(7) XOR lfsr(6) XOR lfsr(4) XOR lfsr(2); + lfsr := lfsr(6 DOWNTO 0) & feedback; + END LOOP; + RETURN lfsr; + END FUNCTION; + + -- Constants + CONSTANT PAYLOAD_BITS : NATURAL := PAYLOAD_BYTES * 8; -- 1072 + CONSTANT NUM_SYMBOLS : NATURAL := ENCODED_BITS / 2; -- 1072 + + -- State machine (9 states) + TYPE state_t IS (IDLE, COLLECT_BYTES, COLLECT_SOFT, EXTRACT, + DEINTERLEAVE, PREP_FEC_DECODE, FEC_DECODE, DERANDOMIZE, OUTPUT); + SIGNAL state : state_t := IDLE; + + -- Linear buffer for collecting bytes (sized to exactly what we need) + TYPE collect_buffer_t IS ARRAY(0 TO ENCODED_BYTES-1) OF std_logic_vector(BYTE_WIDTH-1 DOWNTO 0); + SIGNAL collect_buffer : collect_buffer_t; + SIGNAL collect_idx : NATURAL RANGE 0 TO ENCODED_BYTES; + + -- Soft value buffer (one 3-bit value per bit, 2144 total) + TYPE soft_bit_buffer_t IS ARRAY(0 TO ENCODED_BITS-1) OF std_logic_vector(SOFT_WIDTH-1 DOWNTO 0); + SIGNAL soft_buffer : soft_bit_buffer_t; + SIGNAL soft_idx : NATURAL RANGE 0 TO ENCODED_BITS-1; + + -- Extracted data buffers + TYPE byte_buffer_t IS ARRAY(0 TO PAYLOAD_BYTES-1) OF std_logic_vector(BYTE_WIDTH-1 DOWNTO 0); + TYPE encoded_byte_buffer_t IS ARRAY(0 TO ENCODED_BYTES-1) OF std_logic_vector(BYTE_WIDTH-1 DOWNTO 0); + TYPE bit_buffer_t IS ARRAY(0 TO ENCODED_BITS-1) OF std_logic; + + SIGNAL input_buffer : encoded_byte_buffer_t; + SIGNAL input_bits : bit_buffer_t; + SIGNAL deinterleaved_bits : bit_buffer_t; + SIGNAL deinterleaved_soft : soft_bit_buffer_t; -- Soft values after deinterleaving + SIGNAL fec_decoded_buffer : byte_buffer_t; + SIGNAL output_buffer : byte_buffer_t; + + -- CCSDS LFSR register (for DERANDOMIZE only) + SIGNAL lfsr_derandomize : std_logic_vector(7 DOWNTO 0) := x"FF"; + + -- Viterbi decoder signals + SIGNAL decoder_start : std_logic := '0'; + SIGNAL decoder_busy : std_logic; + SIGNAL decoder_done : std_logic; + SIGNAL decoder_input_soft_g1 : std_logic_vector(NUM_SYMBOLS * SOFT_WIDTH - 1 DOWNTO 0); + SIGNAL decoder_input_soft_g2 : std_logic_vector(NUM_SYMBOLS * SOFT_WIDTH - 1 DOWNTO 0); + SIGNAL decoder_output_buf : std_logic_vector(PAYLOAD_BITS-1 DOWNTO 0); + SIGNAL decoder_path_metric : std_logic_vector(15 DOWNTO 0); + + -- Processing indices + SIGNAL byte_idx : NATURAL RANGE 0 TO ENCODED_BYTES; + SIGNAL bit_idx : NATURAL RANGE 0 TO ENCODED_BITS; + SIGNAL out_idx : NATURAL RANGE 0 TO PAYLOAD_BYTES; + + -- Frame counter + SIGNAL frame_count : unsigned(31 DOWNTO 0) := (OTHERS => '0'); + + -- Output registers + SIGNAL m_tdata_reg : std_logic_vector(BYTE_WIDTH-1 DOWNTO 0); + SIGNAL m_tvalid_reg : std_logic := '0'; + SIGNAL m_tlast_reg : std_logic := '0'; + + -- Attributes + ATTRIBUTE ram_style : STRING; + ATTRIBUTE ram_style OF collect_buffer : SIGNAL IS "block"; + ATTRIBUTE ram_style OF soft_buffer : SIGNAL IS "block"; + ATTRIBUTE ram_style OF input_bits : SIGNAL IS "block"; + ATTRIBUTE ram_style OF deinterleaved_bits : SIGNAL IS "block"; + ATTRIBUTE ram_style OF deinterleaved_soft : SIGNAL IS "block"; + + ATTRIBUTE dont_touch : STRING; + ATTRIBUTE dont_touch OF U_DECODER : LABEL IS "true"; + + ---------------------------------------------------------------------------- + -- Bit-level interleave address function (67x32 matrix) + ---------------------------------------------------------------------------- + FUNCTION interleave_address_bit(linear_idx : NATURAL) RETURN NATURAL IS + CONSTANT ROWS : NATURAL := 67; + CONSTANT COLS : NATURAL := 32; + VARIABLE row, col : NATURAL; + BEGIN + row := linear_idx / COLS; + col := linear_idx MOD COLS; + RETURN col * ROWS + row; + END FUNCTION; + + ---------------------------------------------------------------------------- + -- Soft buffer deinterleave address function + -- Given deinterleaved bit index, returns the soft_buffer index containing it. + -- soft_buffer is in ARRIVAL order (MSB-first byte transmission). + -- This combines interleave lookup with MSB-first byte correction. + -- + -- Arrival order: bits arrive as bytes transmitted MSB-first + -- arrival[0] = byte 0, bit 7 = interleaved[7] + -- arrival[1] = byte 0, bit 6 = interleaved[6] + -- arrival[7] = byte 0, bit 0 = interleaved[0] + -- arrival[8] = byte 1, bit 7 = interleaved[15] + -- etc. + -- + -- To get deinterleaved bit i: + -- 1. Find interleaved position: interleave_address_bit(i) + -- 2. Convert to arrival position: byte*8 + (7 - bit_in_byte) + ---------------------------------------------------------------------------- + FUNCTION soft_deinterleave_address(deint_idx : NATURAL) RETURN NATURAL IS + VARIABLE interleaved_pos : NATURAL; + VARIABLE byte_num : NATURAL; + VARIABLE bit_in_byte : NATURAL; + BEGIN + -- First find which interleaved position has the deinterleaved bit + interleaved_pos := interleave_address_bit(deint_idx); + -- Convert interleaved position to arrival position (MSB-first correction) + byte_num := interleaved_pos / 8; + bit_in_byte := interleaved_pos MOD 8; + RETURN byte_num * 8 + (7 - bit_in_byte); + END FUNCTION; + +BEGIN + + -- Soft Viterbi Decoder Instantiation + U_DECODER : ENTITY work.viterbi_decoder_k7_soft + GENERIC MAP ( + PAYLOAD_BITS => PAYLOAD_BITS, + ENCODED_BITS => ENCODED_BITS, + TRACEBACK_DEPTH => 35, + SOFT_WIDTH => SOFT_WIDTH + ) + PORT MAP ( + clk => clk, + aresetn => aresetn, + start => decoder_start, + busy => decoder_busy, + done => decoder_done, + input_soft_g1 => decoder_input_soft_g1, + input_soft_g2 => decoder_input_soft_g2, + output_bits => decoder_output_buf, + debug_path_metric => decoder_path_metric + ); + + -- Output assignments + m_axis_tdata <= m_tdata_reg; + m_axis_tvalid <= m_tvalid_reg; + m_axis_tlast <= m_tlast_reg; + + frames_decoded <= std_logic_vector(frame_count); + + -- Debug outputs + debug_viterbi_busy <= decoder_busy; + debug_path_metric <= decoder_path_metric; + + -- Main state machine + PROCESS(clk, aresetn) + BEGIN + IF aresetn = '0' THEN + state <= IDLE; + collect_idx <= 0; + soft_idx <= 0; + byte_idx <= 0; + bit_idx <= 0; + out_idx <= 0; + m_tvalid_reg <= '0'; + m_tlast_reg <= '0'; + frame_count <= (OTHERS => '0'); + decoder_start <= '0'; + debug_viterbi_start <= '0'; + debug_viterbi_done <= '0'; + lfsr_derandomize <= x"FF"; + + ELSIF rising_edge(clk) THEN + decoder_start <= '0'; + debug_viterbi_start <= '0'; + debug_viterbi_done <= '0'; + + CASE state IS + + ---------------------------------------------------------- + -- IDLE: Wait for frame data + ---------------------------------------------------------- + WHEN IDLE => + m_tvalid_reg <= '0'; + m_tlast_reg <= '0'; + + IF s_axis_tvalid = '1' THEN + collect_buffer(0) <= s_axis_tdata; + collect_idx <= 1; + state <= COLLECT_BYTES; + END IF; + + ---------------------------------------------------------- + -- COLLECT_BYTES: Receive 268 bytes into linear buffer + ---------------------------------------------------------- + WHEN COLLECT_BYTES => + IF s_axis_tvalid = '1' THEN + collect_buffer(collect_idx) <= s_axis_tdata; + + IF s_axis_tlast = '1' THEN + soft_idx <= 0; + state <= COLLECT_SOFT; + ELSE + collect_idx <= collect_idx + 1; + END IF; + END IF; + + ---------------------------------------------------------- + -- COLLECT_SOFT: Receive 2144 soft bit values + ---------------------------------------------------------- + WHEN COLLECT_SOFT => + IF s_axis_soft_bit_tvalid = '1' THEN + soft_buffer(soft_idx) <= s_axis_soft_bit_tdata; + + IF s_axis_soft_bit_tlast = '1' OR soft_idx = ENCODED_BITS - 1 THEN + byte_idx <= 0; + state <= EXTRACT; + ELSE + soft_idx <= soft_idx + 1; + END IF; + END IF; + + ---------------------------------------------------------- + -- EXTRACT: Unpack bytes from collect_buffer to bit array + -- Data is stored linearly at indices 0 to ENCODED_BYTES-1 + ---------------------------------------------------------- + WHEN EXTRACT => + IF byte_idx < ENCODED_BYTES THEN + -- Direct linear indexing (data stored at 0 to 267) + input_buffer(byte_idx) <= collect_buffer(byte_idx); + + -- Also unpack to bit array (MSB-first per byte) + FOR j IN 0 TO 7 LOOP + input_bits(byte_idx*8 + j) <= collect_buffer(byte_idx)(7-j); + END LOOP; + + byte_idx <= byte_idx + 1; + ELSE + bit_idx <= 0; + state <= DEINTERLEAVE; + END IF; + + ---------------------------------------------------------- + -- DEINTERLEAVE: Reverse 67x32 bit interleaving + -- Also deinterleave soft values for Viterbi + -- BYPASS_INTERLEAVE=TRUE: Direct copy (must match encoder!) + ---------------------------------------------------------- + WHEN DEINTERLEAVE => + IF USE_BIT_INTERLEAVER THEN + IF bit_idx < ENCODED_BITS THEN + IF BYPASS_INTERLEAVE THEN + -- BYPASS: Direct copy, no deinterleaving + deinterleaved_bits(bit_idx) <= input_bits(bit_idx); + deinterleaved_soft(bit_idx) <= soft_buffer(bit_idx); + ELSE + -- Apply inverse 67x32 deinterleaving + -- For deinterleaved position bit_idx, find the interleaved source + deinterleaved_bits(bit_idx) <= + input_bits(interleave_address_bit(bit_idx)); + deinterleaved_soft(bit_idx) <= + soft_buffer(soft_deinterleave_address(bit_idx)); + END IF; + bit_idx <= bit_idx + 1; + ELSE + byte_idx <= 0; + state <= PREP_FEC_DECODE; + END IF; + ELSE + -- Byte-level interleaver (not using soft deinterleave) + IF bit_idx < ENCODED_BITS THEN + IF BYPASS_INTERLEAVE THEN + deinterleaved_bits(bit_idx) <= input_bits(bit_idx); + deinterleaved_soft(bit_idx) <= soft_buffer(bit_idx); + ELSE + deinterleaved_bits(bit_idx) <= input_bits(bit_idx); + deinterleaved_soft(bit_idx) <= soft_buffer(bit_idx); + END IF; + bit_idx <= bit_idx + 1; + ELSE + byte_idx <= 0; + state <= PREP_FEC_DECODE; + END IF; + END IF; + + ---------------------------------------------------------- + -- PREP_FEC_DECODE: Pack soft G1/G2 and start decoder + -- BYPASS_FEC=TRUE: Skip packing, go straight to extraction + ---------------------------------------------------------- + WHEN PREP_FEC_DECODE => + IF BYPASS_FEC THEN + -- BYPASS: Skip Viterbi, will extract first 134 bytes in FEC_DECODE + state <= FEC_DECODE; + ELSE + -- Real FEC: Pack soft values for Viterbi decoder + -- Deinterleaved stream: G1[0], G2[0], G1[1], G2[1], ... + FOR i IN 0 TO NUM_SYMBOLS - 1 LOOP + decoder_input_soft_g1((i+1)*SOFT_WIDTH-1 DOWNTO i*SOFT_WIDTH) <= + deinterleaved_soft(i*2); + decoder_input_soft_g2((i+1)*SOFT_WIDTH-1 DOWNTO i*SOFT_WIDTH) <= + deinterleaved_soft(i*2 + 1); + END LOOP; + + decoder_start <= '1'; + debug_viterbi_start <= '1'; + IF decoder_busy = '1' THEN + state <= FEC_DECODE; + END IF; + END IF; + + ---------------------------------------------------------- + -- FEC_DECODE: Wait for Viterbi decoder OR extract first copy + -- BYPASS_FEC=TRUE: Take first 1072 bits (134 bytes) from deinterleaved stream + -- BYPASS_FEC=FALSE: Wait for Viterbi decoder to complete + ---------------------------------------------------------- + + + + +WHEN FEC_DECODE => + IF BYPASS_FEC THEN + -- BYPASS: Extract first 134 bytes from deinterleaved stream + -- The encoder duplicated 134 bytes -> 268 bytes + -- First 1072 bits = first copy, second 1072 bits = second copy + -- We just use the first copy + -- + -- EXTRACT packed bits MSB-first: input_bits(i*8 + j) = byte(i)(7-j) + -- So input_bits[0..7] = byte[0] bits 7,6,5,4,3,2,1,0 + -- We must reverse to recover original byte order: + -- fec_decoded_buffer(i)(j) needs original bit j, which is at input_bits(i*8 + (7-j)) + FOR i IN 0 TO PAYLOAD_BYTES - 1 LOOP + FOR j IN 0 TO 7 LOOP + -- Reverse bit order to undo EXTRACT's MSB-first packing + fec_decoded_buffer(i)(j) <= deinterleaved_bits(i*8 + (7-j)); + END LOOP; + END LOOP; + + byte_idx <= 0; + lfsr_derandomize <= x"FF"; -- Reset LFSR for derandomization + state <= DERANDOMIZE; + + ELSIF decoder_done = '1' THEN + -- Real FEC: Use Viterbi decoder output + debug_viterbi_done <= '1'; + + -- Pack decoded bits into bytes + -- NOTE: Bit order must match hard decoder! + -- decoder_output_buf is MSB-first from Viterbi traceback + FOR i IN 0 TO PAYLOAD_BYTES - 1 LOOP + FOR j IN 0 TO 7 LOOP + fec_decoded_buffer(i)(j) <= decoder_output_buf(PAYLOAD_BYTES*8 - 1 - i*8 - j); + END LOOP; + END LOOP; + + byte_idx <= 0; + lfsr_derandomize <= x"FF"; -- Reset LFSR for derandomization + state <= DERANDOMIZE; + END IF; + + ---------------------------------------------------------- + -- DERANDOMIZE: XOR with CCSDS LFSR + -- This is the standard pre-FEC randomization reversal + -- BYPASS_RANDOMIZE=TRUE: Direct copy (must match encoder!) + ---------------------------------------------------------- + WHEN DERANDOMIZE => + IF byte_idx < PAYLOAD_BYTES THEN + IF BYPASS_RANDOMIZE THEN + -- BYPASS: Direct copy, no derandomization + output_buffer(byte_idx) <= fec_decoded_buffer(byte_idx); + ELSE + -- XOR with 8 LFSR output bits + output_buffer(byte_idx) <= + fec_decoded_buffer(byte_idx) XOR lfsr_output_byte(lfsr_derandomize); + -- Advance LFSR by 8 positions + lfsr_derandomize <= lfsr_advance_8(lfsr_derandomize); + END IF; + byte_idx <= byte_idx + 1; + ELSE + out_idx <= 0; + frame_count <= frame_count + 1; + state <= OUTPUT; + END IF; + + ---------------------------------------------------------- + -- OUTPUT: Stream decoded bytes + ---------------------------------------------------------- + WHEN OUTPUT => + IF m_axis_tready = '1' OR m_tvalid_reg = '0' THEN + m_tdata_reg <= output_buffer(out_idx); + m_tvalid_reg <= '1'; + + IF out_idx = PAYLOAD_BYTES - 1 THEN + m_tlast_reg <= '1'; + out_idx <= 0; + state <= IDLE; + ELSE + m_tlast_reg <= '0'; + out_idx <= out_idx + 1; + END IF; + END IF; + + END CASE; + END IF; + END PROCESS; + + -- Ready signals (directly active for these inputs) + s_axis_tready <= '1' WHEN state = IDLE OR state = COLLECT_BYTES ELSE '0'; + s_axis_soft_bit_tready <= '1' WHEN state = COLLECT_SOFT ELSE '0'; + + -- Decoder active when not idle + decoder_active <= '0' WHEN state = IDLE ELSE '1'; + + -- Debug state output + debug_state <= "0000" WHEN state = IDLE ELSE + "0001" WHEN state = COLLECT_BYTES ELSE + "0010" WHEN state = COLLECT_SOFT ELSE + "0011" WHEN state = EXTRACT ELSE + "0100" WHEN state = DEINTERLEAVE ELSE + "0101" WHEN state = PREP_FEC_DECODE ELSE + "0110" WHEN state = FEC_DECODE ELSE + "0111" WHEN state = DERANDOMIZE ELSE + "1000" WHEN state = OUTPUT ELSE + "1111"; + +END ARCHITECTURE rtl; diff --git a/src/ov_frame_encoder.vhd b/src/ov_frame_encoder.vhd new file mode 100644 index 0000000..9e570cf --- /dev/null +++ b/src/ov_frame_encoder.vhd @@ -0,0 +1,597 @@ +------------------------------------------------------------------------------------------------------ +-- Opulent Voice Protocol Frame Encoder - DUAL MODE (Bit-level or Byte-level Interleaver) +------------------------------------------------------------------------------------------------------ +-- Supports both interleaver modes via generic parameter: +-- USE_BIT_INTERLEAVER = TRUE : 67x32 bit-level (correct protocol, requires large FPGA) +-- USE_BIT_INTERLEAVER = FALSE : 67x4 byte-level (fits PlutoSDR, breaks protocol compatibility) +------------------------------------------------------------------------------------------------------ +-- CRITICAL DESIGN PRINCIPLE: TLAST-DRIVEN FRAME COLLECTION +------------------------------------------------------------------------------------------------------ +-- This encoder uses AXI-Stream TLAST signal to detect frame boundaries, NOT fixed byte counting! +-- +-- WHY THIS MATTERS: +-- When data flows continuously (e.g., FIFO buffering multiple frames), counting to a fixed +-- number of bytes and ignoring tlast causes the encoder to "steal" bytes from the next frame. +-- This creates cascading byte loss: +-- Frame 3: Missing byte 0 (stolen during Frame 2 collection) +-- Frame 4: Missing bytes 0-1 (stolen during Frame 3 collection) +-- Frame 5: Missing bytes 0-2 (stolen during Frame 4 collection) +-- ... continues until no more data available +-- +-- CORRECT APPROACH (implemented here): +-- 1. IDLE state: Wait for first byte +-- 2. COLLECT state: Accept bytes until s_axis_tlast = '1' (frame boundary marker) +-- 3. Validate we got exactly PAYLOAD_BYTES (134) +-- 4. Process the complete frame through randomization, FEC, interleaving +-- 5. Pre-set s_axis_tready = '1' before returning to IDLE for next frame +-- +-- This approach: +-- Respects AXI-Stream protocol (tlast marks frame boundaries) +-- Works with continuous data streams (FIFO buffering) +-- Prevents byte stealing across frame boundaries +-- Validates frame size for error detection +-- Works for BOTH bit-level and byte-level interleaving modes +-- +-- NEVER count to a fixed byte number and ignore tlast - this violates AXI-Stream protocol! +------------------------------------------------------------------------------------------------------ + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +ENTITY ov_frame_encoder IS + GENERIC ( + PAYLOAD_BYTES : NATURAL := 134; + ENCODED_BYTES : NATURAL := 268; + COLLECT_SIZE : NATURAL := 4; -- DEPRECATED: No longer used (kept for compatibility) + ENCODED_BITS : NATURAL := 2144; -- Kept for compatibility + BYTE_WIDTH : NATURAL := 8; -- Kept for compatibility + USE_BIT_INTERLEAVER : BOOLEAN := TRUE; -- TRUE=bit-level(67x32), FALSE=byte-level(67x4) + -- Debug bypass controls (must match decoder settings!) + BYPASS_RANDOMIZE : BOOLEAN := FALSE; -- TRUE=skip pre-FEC LFSR randomization + BYPASS_FEC : BOOLEAN := FALSE; -- TRUE=duplicate bytes instead of convolutional encode + BYPASS_INTERLEAVE : BOOLEAN := FALSE -- TRUE=skip 67x32 bit interleaving + ); + PORT ( + clk : IN std_logic; + aresetn : IN std_logic; + + -- AXI-Stream Input (from application) + s_axis_tdata : IN std_logic_vector(BYTE_WIDTH-1 DOWNTO 0); + s_axis_tvalid : IN std_logic; + s_axis_tready : OUT std_logic; + s_axis_tlast : IN std_logic; + + -- AXI-Stream Output (to modulator) + m_axis_tdata : OUT std_logic_vector(BYTE_WIDTH-1 DOWNTO 0); + m_axis_tvalid : OUT std_logic; + m_axis_tready : IN std_logic; + m_axis_tlast : OUT std_logic; + + -- Status outputs + frames_encoded : OUT std_logic_vector(31 DOWNTO 0); + encoder_active : OUT std_logic; + debug_state : OUT std_logic_vector(2 DOWNTO 0); + + -- Randomizer debug outputs + debug_lfsr : OUT std_logic_vector(7 DOWNTO 0); + debug_input_byte : OUT std_logic_vector(7 DOWNTO 0); + debug_rand_byte : OUT std_logic_vector(7 DOWNTO 0); + debug_rand_active : OUT std_logic -- HIGH during RANDOMIZE state + ); +END ENTITY ov_frame_encoder; + +ARCHITECTURE rtl OF ov_frame_encoder IS + + ------------------------------------------------------------------------------ + -- CCSDS LFSR Functions (for RANDOMIZE - standard pre-FEC randomization) + ------------------------------------------------------------------------------ + -- Polynomial: x^8 + x^7 + x^5 + x^3 + 1 (CCSDS standard randomizer) + -- Seed: 0xFF + -- Period: 255 bits + -- This is a well-documented standard from CCSDS (Consultative Committee for + -- Space Data Systems) used in many space communication systems. + ------------------------------------------------------------------------------ + + -- Generate 8 output bits from LFSR (for byte-level XOR) + FUNCTION lfsr_output_byte(seed : std_logic_vector(7 DOWNTO 0)) + RETURN std_logic_vector IS + VARIABLE lfsr : std_logic_vector(7 DOWNTO 0) := seed; + VARIABLE result : std_logic_vector(7 DOWNTO 0); + VARIABLE feedback : std_logic; + BEGIN + FOR i IN 7 DOWNTO 0 LOOP + result(i) := lfsr(7); -- Output bit (MSB) + feedback := lfsr(7) XOR lfsr(6) XOR lfsr(4) XOR lfsr(2); + lfsr := lfsr(6 DOWNTO 0) & feedback; + END LOOP; + RETURN result; + END FUNCTION; + + -- Compute LFSR state after 8 advances + FUNCTION lfsr_advance_8(seed : std_logic_vector(7 DOWNTO 0)) + RETURN std_logic_vector IS + VARIABLE lfsr : std_logic_vector(7 DOWNTO 0) := seed; + VARIABLE feedback : std_logic; + BEGIN + FOR i IN 0 TO 7 LOOP + feedback := lfsr(7) XOR lfsr(6) XOR lfsr(4) XOR lfsr(2); + lfsr := lfsr(6 DOWNTO 0) & feedback; + END LOOP; + RETURN lfsr; + END FUNCTION; + + ------------------------------------------------------------------------------ + -- STATE MACHINE DESIGN PHILOSOPHY + ------------------------------------------------------------------------------ + -- CRITICAL: This encoder uses TLAST-DRIVEN frame detection, NOT fixed byte counting! + -- + -- WHY: AXI-Stream protocol uses tlast to mark frame boundaries. Ignoring tlast + -- causes the encoder to "steal" bytes from the next frame when data is + -- continuously available (e.g., from a buffering FIFO). This causes + -- cascading byte loss errors across multiple frames. + -- + -- COLLECT state strategy: + -- 1. Accept bytes one at a time + -- 2. Store each byte in input_buffer[collect_idx] + -- 3. Watch for s_axis_tlast = '1' (frame boundary) + -- 4. When tlast seen, validate we got PAYLOAD_BYTES (134), then process + -- + -- This works for BOTH byte-level and bit-level interleaving modes because: + -- - Collection only fills input_buffer + -- - Interleaving happens later (INTERLEAVE state) on FEC-encoded bits + -- - Interleaver type doesn't affect how we collect input bytes + -- + -- NEVER count to a fixed number and ignore tlast - this violates AXI protocol! + ------------------------------------------------------------------------------ + TYPE state_t IS ( + IDLE, -- Wait for first byte of frame + COLLECT, -- Gather bytes until tlast (AXI-Stream frame boundary marker) + RANDOMIZE, -- XOR with randomizer sequence + PREP_FEC, -- Prepare for convolutional encoding + FEC_ENCODE, -- Apply K=7 convolutional code + INTERLEAVE, -- Shuffle bits (bit-level) or bytes (byte-level) per generic + OUTPUT -- Stream encoded frame to modulator + ); + SIGNAL state : state_t := IDLE; + + TYPE byte_buffer_t IS ARRAY(0 TO PAYLOAD_BYTES-1) OF std_logic_vector(7 DOWNTO 0); + TYPE bit_buffer_t IS ARRAY(0 TO ENCODED_BITS-1) OF std_logic; + + SIGNAL input_buffer : byte_buffer_t; + SIGNAL randomized_buffer : byte_buffer_t; + SIGNAL fec_buffer : bit_buffer_t := (OTHERS => '0'); + SIGNAL interleaved_buffer : bit_buffer_t := (OTHERS => '0'); + + -- CCSDS LFSR register for randomization + SIGNAL lfsr_randomize : std_logic_vector(7 DOWNTO 0) := x"FF"; + + -- Index counters + SIGNAL collect_idx : NATURAL RANGE 0 TO PAYLOAD_BYTES; -- Now collects all bytes until tlast + SIGNAL byte_idx : NATURAL RANGE 0 TO ENCODED_BYTES; + SIGNAL bit_idx : NATURAL RANGE 0 TO ENCODED_BITS; + SIGNAL out_idx : NATURAL RANGE 0 TO ENCODED_BYTES; + + -- AXI-Stream control + SIGNAL s_axis_tready_reg : std_logic := '0'; + SIGNAL m_axis_tdata_reg : std_logic_vector(BYTE_WIDTH-1 DOWNTO 0) := (OTHERS => '0'); + SIGNAL m_axis_tvalid_reg : std_logic := '0'; + SIGNAL m_axis_tlast_reg : std_logic := '0'; + + -- Status counters + SIGNAL frames_encoded_reg : unsigned(31 DOWNTO 0) := (OTHERS => '0'); + SIGNAL encoder_active_reg : std_logic := '0'; + + -- Convolutional encoder signals + SIGNAL encoder_start : std_logic := '0'; + SIGNAL encoder_busy : std_logic; + SIGNAL encoder_done : std_logic; + SIGNAL encoder_input_buf : std_logic_vector(1071 DOWNTO 0); + SIGNAL encoder_output_buf : std_logic_vector(2143 DOWNTO 0); + + -- preserve the output registers from synthesis optimization + ATTRIBUTE dont_touch : STRING; + ATTRIBUTE dont_touch OF m_axis_tvalid_reg : SIGNAL IS "true"; + ATTRIBUTE dont_touch OF m_axis_tdata_reg : SIGNAL IS "true"; + ATTRIBUTE dont_touch OF m_axis_tlast_reg : SIGNAL IS "true"; + ATTRIBUTE dont_touch OF s_axis_tready_reg : SIGNAL IS "true"; + ATTRIBUTE dont_touch OF input_buffer : SIGNAL IS "true"; + ATTRIBUTE dont_touch OF randomized_buffer : SIGNAL IS "true"; + ATTRIBUTE dont_touch OF fec_buffer : SIGNAL IS "true"; + ATTRIBUTE dont_touch OF interleaved_buffer : SIGNAL IS "true"; + ATTRIBUTE dont_touch OF encoder_input_buf : SIGNAL IS "true"; + ATTRIBUTE dont_touch OF encoder_output_buf : SIGNAL IS "true"; + ATTRIBUTE dont_touch OF state : SIGNAL IS "true"; + -- adding these stalled the FIFO from draining past two frames + --ATTRIBUTE dont_touch OF out_idx : SIGNAL IS "true"; + --ATTRIBUTE dont_touch OF byte_idx : SIGNAL IS "true"; + --ATTRIBUTE dont_touch OF collect_idx : SIGNAL IS "true"; + + -- Protect conv_encoder_k7 interface signals (prevent optimization) + ATTRIBUTE dont_touch OF encoder_start : SIGNAL IS "true"; + ATTRIBUTE dont_touch OF encoder_busy : SIGNAL IS "true"; + ATTRIBUTE dont_touch OF encoder_done : SIGNAL IS "true"; + -- Protect the conv_encoder_k7 instance itself + ATTRIBUTE dont_touch OF U_ENCODER : LABEL IS "true"; + + -- Also force BRAM on the large buffers + ATTRIBUTE ram_style : STRING; + ATTRIBUTE ram_style OF interleaved_buffer : SIGNAL IS "block"; + ATTRIBUTE ram_style OF input_buffer : SIGNAL IS "block"; + ATTRIBUTE ram_style OF randomized_buffer : SIGNAL IS "block"; + ATTRIBUTE ram_style OF fec_buffer : SIGNAL IS "block"; + + + + ---------------------------------------------------------------------------- + -- BIT-LEVEL INTERLEAVER (67x4) - For LibreSDR, etc. + -- Consecutive input bits end up 67 positions apart in output. + ---------------------------------------------------------------------------- + FUNCTION interleave_address_bit(bit_addr : NATURAL) RETURN NATURAL IS + -- 67 rows × 32 columns = 2144 bits + -- Write by rows, read by columns + CONSTANT NUM_ROWS : NATURAL := 67; + CONSTANT NUM_COLS : NATURAL := 32; + VARIABLE row, col : NATURAL; + BEGIN + -- Input bit_addr is linear (row-major order: row 0 bits, then row 1, etc.) + row := bit_addr / NUM_COLS; + col := bit_addr MOD NUM_COLS; + + -- Output in column-major order (column 0 bits, then column 1, etc.) + RETURN col * NUM_ROWS + row; + END FUNCTION; + + ---------------------------------------------------------------------------- + -- BYTE-LEVEL INTERLEAVER (67x4) - For PlutoSDR, fits in xc7z010 + ---------------------------------------------------------------------------- + FUNCTION interleave_address_byte(addr : NATURAL) RETURN NATURAL IS + CONSTANT ROWS : NATURAL := 67; + CONSTANT COLS : NATURAL := 4; + VARIABLE row : NATURAL; + VARIABLE col : NATURAL; + BEGIN + row := addr / COLS; + col := addr MOD COLS; + RETURN col * ROWS + row; + END FUNCTION; + + + + +BEGIN + + -- to find the state of the state machine for debug + debug_state <= "000" WHEN state = IDLE ELSE + "001" WHEN state = COLLECT ELSE + "010" WHEN state = RANDOMIZE ELSE + "011" WHEN state = PREP_FEC ELSE + "100" WHEN state = FEC_ENCODE ELSE + "101" WHEN state = INTERLEAVE ELSE + "110" WHEN state = OUTPUT ELSE + "111"; + + + -- Randomizer debug outputs + debug_lfsr <= lfsr_randomize; + debug_input_byte <= input_buffer(byte_idx) WHEN byte_idx < PAYLOAD_BYTES ELSE x"00"; + debug_rand_byte <= randomized_buffer(byte_idx) WHEN byte_idx < PAYLOAD_BYTES ELSE x"00"; + debug_rand_active <= '1' WHEN state = RANDOMIZE ELSE '0'; + + + -- Convolutional Encoder Instantiation + U_ENCODER : ENTITY work.conv_encoder_k7 + GENERIC MAP ( + PAYLOAD_BYTES => PAYLOAD_BYTES, + ENCODED_BYTES => ENCODED_BYTES + ) + PORT MAP ( + clk => clk, + aresetn => aresetn, + start => encoder_start, + busy => encoder_busy, + done => encoder_done, + input_buffer => encoder_input_buf, + output_buffer => encoder_output_buf + ); + + -- AXI-Stream output assignments + s_axis_tready <= s_axis_tready_reg; + m_axis_tdata <= m_axis_tdata_reg; + m_axis_tvalid <= m_axis_tvalid_reg; + m_axis_tlast <= m_axis_tlast_reg; + + -- Status outputs + frames_encoded <= std_logic_vector(frames_encoded_reg); + encoder_active <= encoder_active_reg; + + -- Main State Machine + PROCESS(clk, aresetn) + VARIABLE out_bit_idx : NATURAL RANGE 0 TO ENCODED_BITS-1; + BEGIN + IF aresetn = '0' THEN + state <= IDLE; + collect_idx <= 0; + byte_idx <= 0; + bit_idx <= 0; + out_idx <= 0; + s_axis_tready_reg <= '0'; + m_axis_tdata_reg <= (OTHERS => '0'); + m_axis_tvalid_reg <= '0'; + m_axis_tlast_reg <= '0'; + encoder_start <= '0'; + frames_encoded_reg <= (OTHERS => '0'); + encoder_active_reg <= '0'; + lfsr_randomize <= x"FF"; -- Reset LFSR to seed + + ELSIF rising_edge(clk) THEN + encoder_start <= '0'; + + CASE state IS + + ---------------------------------------------------------------------- + -- IDLE: Wait for first byte of frame + ---------------------------------------------------------------------- + -- Ready to accept data. When valid data arrives, capture first byte + -- and check for tlast (single-byte frame, unlikely but possible). + ---------------------------------------------------------------------- + WHEN IDLE => + s_axis_tready_reg <= '1'; -- Always ready in IDLE + m_axis_tvalid_reg <= '0'; + m_axis_tlast_reg <= '0'; + encoder_active_reg <= '0'; + + IF s_axis_tvalid = '1' AND s_axis_tready_reg = '1' THEN + -- Capture first byte + input_buffer(0) <= s_axis_tdata; + collect_idx <= 1; + encoder_active_reg <= '1'; + + -- Check for single-byte frame (shouldn't happen for 134-byte frames) + IF s_axis_tlast = '1' THEN + s_axis_tready_reg <= '0'; + REPORT "Single-byte frame detected (unexpected)" SEVERITY WARNING; + byte_idx <= 0; + lfsr_randomize <= x"FF"; -- Reset LFSR BEFORE entering RANDOMIZE + state <= RANDOMIZE; + ELSE + state <= COLLECT; + END IF; + END IF; + + + ---------------------------------------------------------------------- + -- COLLECT: Gather bytes until tlast (AXI-Stream frame boundary) + ---------------------------------------------------------------------- + -- This is the CRITICAL state that prevents byte loss! + -- + -- Strategy: + -- - Keep s_axis_tready = 1 (accept data) + -- - Capture each byte to input_buffer[collect_idx] + -- - Increment collect_idx + -- - WATCH FOR TLAST (frame boundary marker) + -- - When tlast seen, validate frame size and proceed to encoding + -- + -- Why not count to 134 and ignore tlast? + -- Because when FIFO has next frame buffered, we'd keep accepting + -- bytes past the frame boundary, "stealing" from the next frame. + -- This causes cascading byte loss (Frame 3 missing byte 0, + -- Frame 4 missing bytes 0-1, etc.) + -- + -- TLAST is the ONLY reliable frame boundary in AXI-Stream protocol! + ---------------------------------------------------------------------- + WHEN COLLECT => + s_axis_tready_reg <= '1'; -- Keep accepting data + + IF s_axis_tvalid = '1' AND s_axis_tready_reg = '1' THEN + -- Capture byte + input_buffer(collect_idx) <= s_axis_tdata; + + -- Check for frame boundary (tlast = end of frame) + IF s_axis_tlast = '1' THEN + -- Frame complete! Stop accepting data + s_axis_tready_reg <= '0'; + + -- Validate frame size (collect_idx is 0-indexed, so +1 for count) + IF collect_idx + 1 /= PAYLOAD_BYTES THEN + REPORT "Frame size mismatch: expected " & + INTEGER'IMAGE(PAYLOAD_BYTES) & " bytes, got " & + INTEGER'IMAGE(collect_idx + 1) & " bytes" + SEVERITY WARNING; + END IF; + + -- Proceed to randomization (even if size is wrong, try to process) + byte_idx <= 0; + lfsr_randomize <= x"FF"; -- Reset LFSR BEFORE entering RANDOMIZE + state <= RANDOMIZE; + ELSE + -- Not end of frame yet, continue collecting + collect_idx <= collect_idx + 1; + + -- Safety check: prevent buffer overflow + IF collect_idx >= PAYLOAD_BYTES - 1 THEN + REPORT "Collected " & INTEGER'IMAGE(PAYLOAD_BYTES) & + " bytes but tlast not seen yet! Frame too large!" + SEVERITY ERROR; + s_axis_tready_reg <= '0'; + byte_idx <= 0; + lfsr_randomize <= x"FF"; -- Reset LFSR BEFORE entering RANDOMIZE + state <= RANDOMIZE; -- Try to process what we have + END IF; + END IF; + END IF; + + -- RANDOMIZE: XOR with CCSDS LFSR sequence (pre-FEC randomization) + -- This is a standard technique from CCSDS used to whiten data before FEC. + -- LFSR is reset to 0xFF before entering this state (during transition) + -- BYPASS_RANDOMIZE=TRUE: Direct copy (for testing) + WHEN RANDOMIZE => + IF byte_idx < PAYLOAD_BYTES THEN + IF BYPASS_RANDOMIZE THEN + -- BYPASS: Direct copy, no randomization + randomized_buffer(byte_idx) <= input_buffer(byte_idx); + ELSE + -- XOR input byte with 8 LFSR output bits + randomized_buffer(byte_idx) <= + input_buffer(byte_idx) XOR lfsr_output_byte(lfsr_randomize); + -- Advance LFSR by 8 positions for next byte + lfsr_randomize <= lfsr_advance_8(lfsr_randomize); + END IF; + byte_idx <= byte_idx + 1; + ELSE + byte_idx <= 0; + state <= PREP_FEC; + END IF; + + ---------------------------------------------------------------------- + -- PREP_FEC: Pack randomized bytes into encoder input buffer + -- Only start the actual encoder if NOT bypassing FEC + ---------------------------------------------------------------------- + WHEN PREP_FEC => + IF byte_idx < PAYLOAD_BYTES THEN + FOR j IN 0 TO 7 LOOP + encoder_input_buf(byte_idx*8 + j) <= randomized_buffer(byte_idx)(j); + END LOOP; + byte_idx <= byte_idx + 1; + ELSE + IF NOT BYPASS_FEC THEN + encoder_start <= '1'; -- Only start real encoder if not bypassing + END IF; + state <= FEC_ENCODE; + END IF; + + ---------------------------------------------------------------------- + -- FEC_ENCODE: Apply convolutional encoding OR duplicate bytes + -- BYPASS_FEC=TRUE: Duplicate 134 bytes -> 268 bytes (no G1/G2 correlation) + -- BYPASS_FEC=FALSE: Wait for K=7 convolutional encoder to complete + ---------------------------------------------------------------------- + WHEN FEC_ENCODE => + encoder_start <= '0'; + + IF BYPASS_FEC THEN + -- BYPASS: Duplicate input bits without encoding + -- Output format: [copy1(1072 bits)][copy2(1072 bits)] = 2144 bits + -- TRUE PASSTHROUGH: No bit reversal - preserves byte patterns for testing + -- This allows verification that 0x00,0x01,0x02... comes out unchanged + FOR i IN 0 TO 1071 LOOP + fec_buffer(i) <= encoder_input_buf(i); -- First copy, NOT reversed + fec_buffer(i + 1072) <= encoder_input_buf(i); -- Second copy, NOT reversed + END LOOP; + + IF USE_BIT_INTERLEAVER THEN + bit_idx <= 0; + ELSE + byte_idx <= 0; + END IF; + state <= INTERLEAVE; + + ELSIF encoder_done = '1' THEN + -- Real FEC: Copy encoder output to fec_buffer (MSB-first to bit-buffer) + FOR i IN 0 TO ENCODED_BITS-1 LOOP + fec_buffer(i) <= encoder_output_buf(ENCODED_BITS - 1 - i); + END LOOP; + + IF USE_BIT_INTERLEAVER THEN + bit_idx <= 0; + ELSE + byte_idx <= 0; + END IF; + state <= INTERLEAVE; + END IF; + + ------------------------------------------------------------------------ + -- INTERLEAVE: Dual-mode implementation + -- BYPASS_INTERLEAVE=TRUE: Direct copy (for testing) + ------------------------------------------------------------------------ + WHEN INTERLEAVE => + IF USE_BIT_INTERLEAVER THEN + -- BIT-LEVEL mode: Process 1 bit per clock (2144 clocks) + IF bit_idx < ENCODED_BITS THEN + IF BYPASS_INTERLEAVE THEN + -- BYPASS: Direct copy, no interleaving + interleaved_buffer(bit_idx) <= fec_buffer(bit_idx); + ELSE + -- Apply 67x32 bit interleaving + interleaved_buffer(interleave_address_bit(bit_idx)) <= fec_buffer(bit_idx); + END IF; + bit_idx <= bit_idx + 1; + ELSE + out_idx <= 0; + state <= OUTPUT; + m_axis_tvalid_reg <= '0'; + END IF; + ELSE + -- BYTE-LEVEL mode: Process 1 byte per clock (268 clocks) + IF byte_idx < ENCODED_BYTES THEN + IF BYPASS_INTERLEAVE THEN + -- BYPASS: Direct copy, no interleaving + FOR j IN 0 TO 7 LOOP + interleaved_buffer(byte_idx*8 + j) <= fec_buffer(byte_idx*8 + j); + END LOOP; + ELSE + -- Apply 67x4 byte interleaving + FOR j IN 0 TO 7 LOOP + interleaved_buffer(interleave_address_byte(byte_idx)*8 + j) <= + fec_buffer(byte_idx*8 + j); + END LOOP; + END IF; + byte_idx <= byte_idx + 1; + ELSE + out_idx <= 0; + state <= OUTPUT; + m_axis_tvalid_reg <= '0'; + END IF; + END IF; + + + + + ---------------------------------------------------------------------- + -- OUTPUT: Stream interleaved bytes to modulator + ---------------------------------------------------------------------- + -- Send encoded frame one byte at a time via AXI-Stream. + -- Assert tlast on final byte to mark frame boundary. + ---------------------------------------------------------------------- + WHEN OUTPUT => + IF out_idx < ENCODED_BYTES THEN + IF m_axis_tready = '1' OR m_axis_tvalid_reg = '0' THEN + -- Pack 8 bits from interleaved_buffer into output byte + FOR j IN 0 TO 7 LOOP + out_bit_idx := out_idx*8 + j; + m_axis_tdata_reg(j) <= interleaved_buffer(out_bit_idx); + END LOOP; + m_axis_tvalid_reg <= '1'; + + -- Assert tlast on final byte (AXI-Stream frame boundary) + IF out_idx = ENCODED_BYTES - 1 THEN + m_axis_tlast_reg <= '1'; + ELSE + m_axis_tlast_reg <= '0'; + END IF; + + out_idx <= out_idx + 1; + END IF; + ELSE + + -- Frame output complete + IF m_axis_tready = '1' THEN + m_axis_tvalid_reg <= '0'; + m_axis_tlast_reg <= '0'; + + -- Pre-set ready for next frame BEFORE going to IDLE + -- This ensures s_axis_tready is already high when we + -- enter IDLE, preventing one-clock delay in handshake + s_axis_tready_reg <= '1'; + + frames_encoded_reg <= frames_encoded_reg + 1; + collect_idx <= 0; + state <= IDLE; + END IF; + END IF; + + END CASE; + + END IF; + END PROCESS; + +END ARCHITECTURE rtl; diff --git a/src/pulse_detect.vhd b/src/pulse_detect.vhd new file mode 100644 index 0000000..a1060f3 --- /dev/null +++ b/src/pulse_detect.vhd @@ -0,0 +1,109 @@ +------------------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------ +-- _______ ________ ______ +-- __ __ \________ _____ _______ ___ __ \_____ _____________ ______ ___________________ /_ +-- _ / / /___ __ \_ _ \__ __ \ __ /_/ /_ _ \__ ___/_ _ \_ __ `/__ ___/_ ___/__ __ \ +-- / /_/ / __ /_/ // __/_ / / / _ _, _/ / __/_(__ ) / __// /_/ / _ / / /__ _ / / / +-- \____/ _ .___/ \___/ /_/ /_/ /_/ |_| \___/ /____/ \___/ \__,_/ /_/ \___/ /_/ /_/ +-- /_/ +-- ________ _____ _____ _____ _____ +-- ____ _/_______ __________ /____(_)__ /_____ ____ /______ +-- __ / __ __ \__ ___/_ __/__ / _ __/_ / / /_ __/_ _ \ +-- __/ / _ / / /_(__ ) / /_ _ / / /_ / /_/ / / /_ / __/ +-- /___/ /_/ /_/ /____/ \__/ /_/ \__/ \__,_/ \__/ \___/ +-- +------------------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------ +-- Copyright +------------------------------------------------------------------------------------------------------ +-- +-- Copyright 2025 by M. Wishek +-- +------------------------------------------------------------------------------------------------------ +-- License +------------------------------------------------------------------------------------------------------ +-- +-- This source describes Open Hardware and is licensed under the CERN-OHL-W v2. +-- +-- You may redistribute and modify this source and make products using it under +-- the terms of the CERN-OHL-W v2 (https://ohwr.org/cern_ohl_w_v2.txt). +-- +-- This source is distributed WITHOUT ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING +-- OF MERCHANTABILITY, SATISFACTORY QUALITY AND FITNESS FOR A PARTICULAR PURPOSE. +-- Please see the CERN-OHL-W v2 for applicable conditions. +-- +-- Source location: TBD +-- +-- As per CERN-OHL-W v2 section 4.1, should You produce hardware based on this +-- source, You must maintain the Source Location visible on the external case of +-- the products you make using this source. +-- +------------------------------------------------------------------------------------------------------ +-- Block name and description +------------------------------------------------------------------------------------------------------ +-- +-- This is a wrapper block for the register module generated by DesyRDL. +-- +-- Documentation location: TBD +-- +------------------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------ + + +------------------------------------------------------------------------------------------------------ +-- ╦ ┬┌┐ ┬─┐┌─┐┬─┐┬┌─┐┌─┐ +-- ║ │├┴┐├┬┘├─┤├┬┘│├┤ └─┐ +-- ╩═╝┴└─┘┴└─┴ ┴┴└─┴└─┘└─┘ +------------------------------------------------------------------------------------------------------ +-- Libraries + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +------------------------------------------------------------------------------------------------------ +-- ╔═╗┌┐┌┌┬┐┬┌┬┐┬ ┬ +-- ║╣ │││ │ │ │ └┬┘ +-- ╚═╝┘└┘ ┴ ┴ ┴ ┴ +------------------------------------------------------------------------------------------------------ +-- Entity + +ENTITY pulse_detect IS + PORT ( + clk : IN std_logic; + sync_reset : IN std_logic; + + di : IN std_logic; + do : OUT std_logic + ); +END ENTITY pulse_detect; + +ARCHITECTURE rtl OF pulse_detect IS + + SIGNAL detect_q : std_logic; + SIGNAL detect_q1 : std_logic; + SIGNAL detect_q2 : std_logic; + +BEGIN + + do <= detect_q1 AND NOT detect_q2; + + detect : PROCESS (clk, di) + BEGIN + IF di = '1' THEN + detect_q <= '1'; + ELSIF clk'EVENT AND clk = '1' THEN + IF sync_reset = '1' OR detect_q2 = '1' THEN + detect_q <= '0'; + detect_q1 <= '0'; + detect_q2 <= '0'; + ELSE + detect_q1 <= detect_q; + detect_q2 <= detect_q1; + END IF; + END IF; + END PROCESS detect; + +END ARCHITECTURE rtl; + + diff --git a/src/run_extended_tb.tcl b/src/run_extended_tb.tcl new file mode 100644 index 0000000..47fb5d9 --- /dev/null +++ b/src/run_extended_tb.tcl @@ -0,0 +1,6 @@ +create_project -force tb_extended ./tb_extended -part xc7z020clg400-2 +add_files {viterbi_decoder_k7_simple.vhd viterbi_decoder_k7_soft.vhd tb_viterbi_extended.vhd} +set_property top tb_viterbi_extended [get_filesets sim_1] +set_property target_language VHDL [current_project] +launch_simulation +run all diff --git a/src/run_soft_tb.tcl b/src/run_soft_tb.tcl new file mode 100644 index 0000000..f8e42c2 --- /dev/null +++ b/src/run_soft_tb.tcl @@ -0,0 +1,9 @@ +create_project -force tb_soft_viterbi ./tb_soft_viterbi -part xc7z020clg400-2 + +add_files {viterbi_decoder_k7_simple.vhd viterbi_decoder_k7_soft.vhd tb_viterbi_soft.vhd} + +set_property top tb_viterbi_soft [get_filesets sim_1] +set_property target_language VHDL [current_project] + +launch_simulation +run all diff --git a/src/tb_viterbi_extended.vhd b/src/tb_viterbi_extended.vhd new file mode 100644 index 0000000..bc7f511 --- /dev/null +++ b/src/tb_viterbi_extended.vhd @@ -0,0 +1,292 @@ +------------------------------------------------------------------------------------------------------ +-- Testbench: Soft vs Hard Viterbi Decoder - Extended BER Testing +------------------------------------------------------------------------------------------------------ +-- Tests both decoders across a range of BER levels to find breaking points. +-- Tests one full OV frame (134 bytes payload, 268 bytes encoded). +------------------------------------------------------------------------------------------------------ + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; +USE ieee.math_real.ALL; + +ENTITY tb_viterbi_extended IS +END ENTITY tb_viterbi_extended; + +ARCHITECTURE sim OF tb_viterbi_extended IS + + CONSTANT PAYLOAD_BITS : NATURAL := 134 * 8; -- 1072 bits = 1 OV frame + CONSTANT ENCODED_BITS : NATURAL := 268 * 8; -- 2144 bits + CONSTANT NUM_SYMBOLS : NATURAL := ENCODED_BITS / 2; -- 1072 + CONSTANT SOFT_WIDTH : NATURAL := 3; + CONSTANT SOFT_MAX : NATURAL := 2**SOFT_WIDTH - 1; + + CONSTANT CLK_PERIOD : time := 10 ns; + + SIGNAL clk : std_logic := '0'; + SIGNAL aresetn : std_logic := '0'; + + -- Hard decoder signals + SIGNAL hard_start : std_logic := '0'; + SIGNAL hard_busy : std_logic; + SIGNAL hard_done : std_logic; + SIGNAL hard_input_g1 : std_logic_vector(ENCODED_BITS-1 DOWNTO 0); + SIGNAL hard_input_g2 : std_logic_vector(ENCODED_BITS-1 DOWNTO 0); + SIGNAL hard_output : std_logic_vector(PAYLOAD_BITS-1 DOWNTO 0); + + -- Soft decoder signals + SIGNAL soft_start : std_logic := '0'; + SIGNAL soft_busy : std_logic; + SIGNAL soft_done : std_logic; + SIGNAL soft_input_g1 : std_logic_vector(NUM_SYMBOLS * SOFT_WIDTH - 1 DOWNTO 0); + SIGNAL soft_input_g2 : std_logic_vector(NUM_SYMBOLS * SOFT_WIDTH - 1 DOWNTO 0); + SIGNAL soft_output : std_logic_vector(PAYLOAD_BITS-1 DOWNTO 0); + SIGNAL soft_path_metric : std_logic_vector(15 DOWNTO 0); + + -- Test data + SIGNAL original_data : std_logic_vector(PAYLOAD_BITS-1 DOWNTO 0); + SIGNAL encoded_g1 : std_logic_vector(NUM_SYMBOLS-1 DOWNTO 0); + SIGNAL encoded_g2 : std_logic_vector(NUM_SYMBOLS-1 DOWNTO 0); + + ---------------------------------------------------------------------------- + -- Convolutional encoder + ---------------------------------------------------------------------------- + PROCEDURE conv_encode( + data_in : IN std_logic_vector(PAYLOAD_BITS-1 DOWNTO 0); + SIGNAL g1_out : OUT std_logic_vector(NUM_SYMBOLS-1 DOWNTO 0); + SIGNAL g2_out : OUT std_logic_vector(NUM_SYMBOLS-1 DOWNTO 0) + ) IS + VARIABLE sr : std_logic_vector(5 DOWNTO 0) := (OTHERS => '0'); + VARIABLE curr_bit : std_logic; + VARIABLE g1, g2 : std_logic; + VARIABLE out_idx : INTEGER; + BEGIN + sr := (OTHERS => '0'); + out_idx := 0; + + FOR i IN PAYLOAD_BITS-1 DOWNTO 0 LOOP + curr_bit := data_in(i); + g1 := curr_bit XOR sr(3) XOR sr(2) XOR sr(1) XOR sr(0); + g2 := curr_bit XOR sr(5) XOR sr(3) XOR sr(2) XOR sr(0); + g1_out(out_idx) <= g1; + g2_out(out_idx) <= g2; + out_idx := out_idx + 1; + sr := sr(4 DOWNTO 0) & curr_bit; + END LOOP; + END PROCEDURE; + + FUNCTION hard_to_soft(bit : std_logic; confidence : INTEGER) + RETURN std_logic_vector IS + VARIABLE soft_val : INTEGER; + BEGIN + IF bit = '0' THEN + soft_val := (SOFT_MAX - confidence) / 2; + ELSE + soft_val := SOFT_MAX - (SOFT_MAX - confidence) / 2; + END IF; + RETURN std_logic_vector(to_unsigned(soft_val, SOFT_WIDTH)); + END FUNCTION; + +BEGIN + + clk <= NOT clk AFTER CLK_PERIOD / 2; + + U_HARD : ENTITY work.viterbi_decoder_k7_simple + GENERIC MAP ( + PAYLOAD_BITS => PAYLOAD_BITS, + ENCODED_BITS => ENCODED_BITS, + TRACEBACK_DEPTH => 35 + ) + PORT MAP ( + clk => clk, + aresetn => aresetn, + start => hard_start, + busy => hard_busy, + done => hard_done, + input_bits_g1 => hard_input_g1, + input_bits_g2 => hard_input_g2, + output_bits => hard_output + ); + + U_SOFT : ENTITY work.viterbi_decoder_k7_soft + GENERIC MAP ( + PAYLOAD_BITS => PAYLOAD_BITS, + ENCODED_BITS => ENCODED_BITS, + TRACEBACK_DEPTH => 35, + SOFT_WIDTH => SOFT_WIDTH + ) + PORT MAP ( + clk => clk, + aresetn => aresetn, + start => soft_start, + busy => soft_busy, + done => soft_done, + input_soft_g1 => soft_input_g1, + input_soft_g2 => soft_input_g2, + output_bits => soft_output, + debug_path_metric => soft_path_metric + ); + + stim_proc: PROCESS + VARIABLE seed1, seed2 : INTEGER := 42; + VARIABLE rand : REAL; + VARIABLE hard_errors, soft_errors : INTEGER; + VARIABLE num_injected_errors : INTEGER; + + -- BER levels to test (in percent * 100, so 500 = 5.00%) + TYPE ber_array_t IS ARRAY(0 TO 11) OF INTEGER; + CONSTANT BER_LEVELS : ber_array_t := ( + 0, -- 0% (clean) + 500, -- 5% + 1000, -- 10% + 1500, -- 15% + 2000, -- 20% + 2500, -- 25% + 3000, -- 30% + 3500, -- 35% + 4000, -- 40% + 4500, -- 45% + 5000, -- 50% (random) + 0 -- unused + ); + VARIABLE ber_pct : REAL; + VARIABLE test_num : INTEGER; + + BEGIN + aresetn <= '0'; + WAIT FOR CLK_PERIOD * 10; + aresetn <= '1'; + WAIT FOR CLK_PERIOD * 5; + + REPORT "================================================================" SEVERITY NOTE; + REPORT " Soft vs Hard Viterbi Decoder - BER Sweep Test" SEVERITY NOTE; + REPORT " Payload: " & INTEGER'IMAGE(PAYLOAD_BITS) & " bits (1 OV frame)" SEVERITY NOTE; + REPORT " Encoded: " & INTEGER'IMAGE(ENCODED_BITS) & " bits" SEVERITY NOTE; + REPORT " Soft width: " & INTEGER'IMAGE(SOFT_WIDTH) & " bits" SEVERITY NOTE; + REPORT "================================================================" SEVERITY NOTE; + + -- Test each BER level + FOR test_idx IN 0 TO 10 LOOP + test_num := test_idx + 1; + ber_pct := REAL(BER_LEVELS(test_idx)) / 10000.0; + + REPORT "" SEVERITY NOTE; + REPORT "--- Test " & INTEGER'IMAGE(test_num) & ": BER = " & + INTEGER'IMAGE(BER_LEVELS(test_idx)/100) & "." & + INTEGER'IMAGE(BER_LEVELS(test_idx) MOD 100) & "% ---" SEVERITY NOTE; + + -- Initialize + hard_input_g1 <= (OTHERS => '0'); + hard_input_g2 <= (OTHERS => '0'); + + -- Generate random payload + FOR i IN 0 TO PAYLOAD_BITS-1 LOOP + uniform(seed1, seed2, rand); + IF rand > 0.5 THEN + original_data(i) <= '1'; + ELSE + original_data(i) <= '0'; + END IF; + END LOOP; + WAIT FOR CLK_PERIOD; + + -- Encode + conv_encode(original_data, encoded_g1, encoded_g2); + WAIT FOR CLK_PERIOD; + + -- Inject errors based on BER + num_injected_errors := 0; + FOR i IN 0 TO NUM_SYMBOLS-1 LOOP + -- G1 + uniform(seed1, seed2, rand); + IF rand < ber_pct THEN + hard_input_g1(i) <= NOT encoded_g1(i); + IF encoded_g1(i) = '0' THEN + soft_input_g1((i+1)*SOFT_WIDTH-1 DOWNTO i*SOFT_WIDTH) <= + std_logic_vector(to_unsigned(SOFT_MAX/2 + 1, SOFT_WIDTH)); + ELSE + soft_input_g1((i+1)*SOFT_WIDTH-1 DOWNTO i*SOFT_WIDTH) <= + std_logic_vector(to_unsigned(SOFT_MAX/2 - 1, SOFT_WIDTH)); + END IF; + num_injected_errors := num_injected_errors + 1; + ELSE + hard_input_g1(i) <= encoded_g1(i); + soft_input_g1((i+1)*SOFT_WIDTH-1 DOWNTO i*SOFT_WIDTH) <= + hard_to_soft(encoded_g1(i), SOFT_MAX); + END IF; + + -- G2 + uniform(seed1, seed2, rand); + IF rand < ber_pct THEN + hard_input_g2(i) <= NOT encoded_g2(i); + IF encoded_g2(i) = '0' THEN + soft_input_g2((i+1)*SOFT_WIDTH-1 DOWNTO i*SOFT_WIDTH) <= + std_logic_vector(to_unsigned(SOFT_MAX/2 + 1, SOFT_WIDTH)); + ELSE + soft_input_g2((i+1)*SOFT_WIDTH-1 DOWNTO i*SOFT_WIDTH) <= + std_logic_vector(to_unsigned(SOFT_MAX/2 - 1, SOFT_WIDTH)); + END IF; + num_injected_errors := num_injected_errors + 1; + ELSE + hard_input_g2(i) <= encoded_g2(i); + soft_input_g2((i+1)*SOFT_WIDTH-1 DOWNTO i*SOFT_WIDTH) <= + hard_to_soft(encoded_g2(i), SOFT_MAX); + END IF; + END LOOP; + WAIT FOR CLK_PERIOD; + + REPORT " Channel errors injected: " & INTEGER'IMAGE(num_injected_errors) & + " / " & INTEGER'IMAGE(NUM_SYMBOLS*2) & " bits" SEVERITY NOTE; + + -- Run decoders + hard_start <= '1'; + soft_start <= '1'; + WAIT FOR CLK_PERIOD; + hard_start <= '0'; + soft_start <= '0'; + + WAIT UNTIL hard_done = '1' AND soft_done = '1'; + WAIT FOR CLK_PERIOD * 2; + + -- Count errors + hard_errors := 0; + soft_errors := 0; + FOR i IN 0 TO PAYLOAD_BITS-1 LOOP + IF hard_output(i) /= original_data(PAYLOAD_BITS-1-i) THEN + hard_errors := hard_errors + 1; + END IF; + IF soft_output(i) /= original_data(PAYLOAD_BITS-1-i) THEN + soft_errors := soft_errors + 1; + END IF; + END LOOP; + + REPORT " Hard decoder output errors: " & INTEGER'IMAGE(hard_errors) & + " / " & INTEGER'IMAGE(PAYLOAD_BITS) SEVERITY NOTE; + REPORT " Soft decoder output errors: " & INTEGER'IMAGE(soft_errors) & + " / " & INTEGER'IMAGE(PAYLOAD_BITS) SEVERITY NOTE; + REPORT " Soft path metric: " & INTEGER'IMAGE(to_integer(unsigned(soft_path_metric))) SEVERITY NOTE; + + IF soft_errors = 0 AND hard_errors = 0 THEN + REPORT " Result: BOTH PERFECT" SEVERITY NOTE; + ELSIF soft_errors < hard_errors THEN + REPORT " Result: SOFT WINS by " & INTEGER'IMAGE(hard_errors - soft_errors) & " bits" SEVERITY NOTE; + ELSIF soft_errors = hard_errors THEN + REPORT " Result: TIE (both have " & INTEGER'IMAGE(soft_errors) & " errors)" SEVERITY NOTE; + ELSE + REPORT " Result: HARD WINS (unexpected)" SEVERITY WARNING; + END IF; + + WAIT FOR CLK_PERIOD * 10; + + END LOOP; + + REPORT "" SEVERITY NOTE; + REPORT "================================================================" SEVERITY NOTE; + REPORT " All BER tests complete!" SEVERITY NOTE; + REPORT "================================================================" SEVERITY NOTE; + + std.env.stop; + + END PROCESS; + +END ARCHITECTURE sim; diff --git a/src/tb_viterbi_soft.vhd b/src/tb_viterbi_soft.vhd new file mode 100644 index 0000000..4552307 --- /dev/null +++ b/src/tb_viterbi_soft.vhd @@ -0,0 +1,464 @@ +------------------------------------------------------------------------------------------------------ +-- Testbench: Soft vs Hard Viterbi Decoder Comparison +------------------------------------------------------------------------------------------------------ +-- Tests both decoders with the same input and verifies soft decoder handles +-- noisy/uncertain bits better than hard decoder. +------------------------------------------------------------------------------------------------------ + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; +USE ieee.math_real.ALL; + +ENTITY tb_viterbi_soft IS +END ENTITY tb_viterbi_soft; + +ARCHITECTURE sim OF tb_viterbi_soft IS + + CONSTANT PAYLOAD_BITS : NATURAL := 134 * 8; -- 1072 + CONSTANT ENCODED_BITS : NATURAL := 268 * 8; -- 2144 + CONSTANT NUM_SYMBOLS : NATURAL := ENCODED_BITS / 2; -- 1072 + CONSTANT SOFT_WIDTH : NATURAL := 3; + CONSTANT SOFT_MAX : NATURAL := 2**SOFT_WIDTH - 1; + + CONSTANT CLK_PERIOD : time := 10 ns; + + SIGNAL clk : std_logic := '0'; + SIGNAL aresetn : std_logic := '0'; + + -- Hard decoder signals + SIGNAL hard_start : std_logic := '0'; + SIGNAL hard_busy : std_logic; + SIGNAL hard_done : std_logic; + SIGNAL hard_input_g1 : std_logic_vector(ENCODED_BITS-1 DOWNTO 0); -- 2144 bits + SIGNAL hard_input_g2 : std_logic_vector(ENCODED_BITS-1 DOWNTO 0); -- 2144 bits + SIGNAL hard_output : std_logic_vector(PAYLOAD_BITS-1 DOWNTO 0); + + -- Soft decoder signals + SIGNAL soft_start : std_logic := '0'; + SIGNAL soft_busy : std_logic; + SIGNAL soft_done : std_logic; + SIGNAL soft_input_g1 : std_logic_vector(NUM_SYMBOLS * SOFT_WIDTH - 1 DOWNTO 0); + SIGNAL soft_input_g2 : std_logic_vector(NUM_SYMBOLS * SOFT_WIDTH - 1 DOWNTO 0); + SIGNAL soft_output : std_logic_vector(PAYLOAD_BITS-1 DOWNTO 0); + SIGNAL soft_path_metric : std_logic_vector(15 DOWNTO 0); + + -- Test data + SIGNAL original_data : std_logic_vector(PAYLOAD_BITS-1 DOWNTO 0); + SIGNAL encoded_g1 : std_logic_vector(NUM_SYMBOLS-1 DOWNTO 0); -- 1072 symbols + SIGNAL encoded_g2 : std_logic_vector(NUM_SYMBOLS-1 DOWNTO 0); -- 1072 symbols + + -- Error injection + SIGNAL error_mask_g1 : std_logic_vector(NUM_SYMBOLS-1 DOWNTO 0); + SIGNAL error_mask_g2 : std_logic_vector(NUM_SYMBOLS-1 DOWNTO 0); + + ---------------------------------------------------------------------------- + -- Convolutional encoder (same as TX) + -- Outputs SEPARATE G1 and G2 streams (not interleaved) + -- g1_out(i) and g2_out(i) are the outputs for input bit i + ---------------------------------------------------------------------------- + PROCEDURE conv_encode( + data_in : IN std_logic_vector(PAYLOAD_BITS-1 DOWNTO 0); + SIGNAL g1_out : OUT std_logic_vector(NUM_SYMBOLS-1 DOWNTO 0); + SIGNAL g2_out : OUT std_logic_vector(NUM_SYMBOLS-1 DOWNTO 0) + ) IS + VARIABLE sr : std_logic_vector(5 DOWNTO 0) := (OTHERS => '0'); + VARIABLE curr_bit : std_logic; + VARIABLE g1, g2 : std_logic; + VARIABLE out_idx : INTEGER; + BEGIN + sr := (OTHERS => '0'); + out_idx := 0; + + -- Process MSB first (same as actual encoder) + FOR i IN PAYLOAD_BITS-1 DOWNTO 0 LOOP + curr_bit := data_in(i); + + -- G1 = 171 octal: curr_bit XOR sr(3) XOR sr(2) XOR sr(1) XOR sr(0) + g1 := curr_bit XOR sr(3) XOR sr(2) XOR sr(1) XOR sr(0); + + -- G2 = 133 octal: curr_bit XOR sr(5) XOR sr(3) XOR sr(2) XOR sr(0) + g2 := curr_bit XOR sr(5) XOR sr(3) XOR sr(2) XOR sr(0); + + -- Output: g1_out and g2_out are parallel streams + -- Index 0 = first output symbol, index NUM_SYMBOLS-1 = last + g1_out(out_idx) <= g1; + g2_out(out_idx) <= g2; + out_idx := out_idx + 1; + + -- Shift register update + sr := sr(4 DOWNTO 0) & curr_bit; + END LOOP; + END PROCEDURE; + + ---------------------------------------------------------------------------- + -- Convert hard bit to soft value + -- bit='0' -> soft=0 (strong zero) + -- bit='1' -> soft=SOFT_MAX (strong one) + ---------------------------------------------------------------------------- + FUNCTION hard_to_soft(bit : std_logic; confidence : INTEGER) + RETURN std_logic_vector IS + VARIABLE soft_val : INTEGER; + BEGIN + IF bit = '0' THEN + soft_val := (SOFT_MAX - confidence) / 2; -- Low value for '0' + ELSE + soft_val := SOFT_MAX - (SOFT_MAX - confidence) / 2; -- High value for '1' + END IF; + RETURN std_logic_vector(to_unsigned(soft_val, SOFT_WIDTH)); + END FUNCTION; + +BEGIN + + -- Clock generation + clk <= NOT clk AFTER CLK_PERIOD / 2; + + -- Hard decoder (existing) + U_HARD : ENTITY work.viterbi_decoder_k7_simple + GENERIC MAP ( + PAYLOAD_BITS => PAYLOAD_BITS, + ENCODED_BITS => ENCODED_BITS, + TRACEBACK_DEPTH => 35 + ) + PORT MAP ( + clk => clk, + aresetn => aresetn, + start => hard_start, + busy => hard_busy, + done => hard_done, + input_bits_g1 => hard_input_g1, + input_bits_g2 => hard_input_g2, + output_bits => hard_output + ); + + -- Soft decoder (new) + U_SOFT : ENTITY work.viterbi_decoder_k7_soft + GENERIC MAP ( + PAYLOAD_BITS => PAYLOAD_BITS, + ENCODED_BITS => ENCODED_BITS, + TRACEBACK_DEPTH => 35, + SOFT_WIDTH => SOFT_WIDTH + ) + PORT MAP ( + clk => clk, + aresetn => aresetn, + start => soft_start, + busy => soft_busy, + done => soft_done, + input_soft_g1 => soft_input_g1, + input_soft_g2 => soft_input_g2, + output_bits => soft_output, + debug_path_metric => soft_path_metric + ); + + -- Main test process + stim_proc: PROCESS + VARIABLE seed1, seed2 : INTEGER := 42; + VARIABLE rand : REAL; + VARIABLE hard_errors, soft_errors : INTEGER; + VARIABLE num_injected_errors : INTEGER; + VARIABLE error_pos : INTEGER; + VARIABLE confidence : INTEGER; + VARIABLE dbg_i : INTEGER; + BEGIN + -- Reset + aresetn <= '0'; + WAIT FOR CLK_PERIOD * 10; + aresetn <= '1'; + WAIT FOR CLK_PERIOD * 5; + + -------------------------------------------------------------------- + -- Test 1: Clean channel (no errors) + -------------------------------------------------------------------- + REPORT "=== Test 1: Clean channel ===" SEVERITY NOTE; + + -- Generate random payload + FOR i IN 0 TO PAYLOAD_BITS-1 LOOP + uniform(seed1, seed2, rand); + IF rand > 0.5 THEN + original_data(i) <= '1'; + ELSE + original_data(i) <= '0'; + END IF; + END LOOP; + WAIT FOR CLK_PERIOD; + + -- Encode + conv_encode(original_data, encoded_g1, encoded_g2); + WAIT FOR CLK_PERIOD; + + -- Prepare hard decoder input (no errors) + -- Pad upper bits with zeros since hard decoder only uses lower NUM_SYMBOLS bits + hard_input_g1 <= (ENCODED_BITS-1 DOWNTO NUM_SYMBOLS => '0') & encoded_g1; + hard_input_g2 <= (ENCODED_BITS-1 DOWNTO NUM_SYMBOLS => '0') & encoded_g2; + + -- Prepare soft decoder input (high confidence, no errors) + FOR i IN 0 TO NUM_SYMBOLS-1 LOOP + soft_input_g1((i+1)*SOFT_WIDTH-1 DOWNTO i*SOFT_WIDTH) <= + hard_to_soft(encoded_g1(i), SOFT_MAX); + soft_input_g2((i+1)*SOFT_WIDTH-1 DOWNTO i*SOFT_WIDTH) <= + hard_to_soft(encoded_g2(i), SOFT_MAX); + END LOOP; + WAIT FOR CLK_PERIOD; + + -- Run both decoders + hard_start <= '1'; + soft_start <= '1'; + WAIT FOR CLK_PERIOD; + hard_start <= '0'; + soft_start <= '0'; + + -- Wait for completion + WAIT UNTIL hard_done = '1' AND soft_done = '1'; + WAIT FOR CLK_PERIOD * 2; + + -- Check results + hard_errors := 0; + soft_errors := 0; + -- Debug: show first 10 bits + REPORT " First 10 original bits:" SEVERITY NOTE; + FOR dbg_i IN 0 TO 9 LOOP + REPORT " Bit " & INTEGER'IMAGE(dbg_i) & ": " & std_logic'image(original_data(dbg_i)) SEVERITY NOTE; + END LOOP; + REPORT " First 10 hard output bits:" SEVERITY NOTE; + FOR dbg_i IN 0 TO 9 LOOP + REPORT " Bit " & INTEGER'IMAGE(dbg_i) & ": " & std_logic'image(hard_output(dbg_i)) SEVERITY NOTE; + END LOOP; + REPORT " First 5 encoded G1/G2:" SEVERITY NOTE; + FOR dbg_i IN 0 TO 4 LOOP + REPORT " Sym " & INTEGER'IMAGE(dbg_i) & ": G1=" & std_logic'image(encoded_g1(dbg_i)) & " G2=" & std_logic'image(encoded_g2(dbg_i)) SEVERITY NOTE; + END LOOP; + FOR i IN 0 TO PAYLOAD_BITS-1 LOOP + -- Decoder output(i) corresponds to original_data(PAYLOAD_BITS-1-i) + -- because encoder processes MSB first + IF hard_output(i) /= original_data(PAYLOAD_BITS-1-i) THEN + hard_errors := hard_errors + 1; + END IF; + IF soft_output(i) /= original_data(PAYLOAD_BITS-1-i) THEN + soft_errors := soft_errors + 1; + END IF; + END LOOP; + + REPORT " Hard decoder errors: " & INTEGER'IMAGE(hard_errors) SEVERITY NOTE; + REPORT " Soft decoder errors: " & INTEGER'IMAGE(soft_errors) SEVERITY NOTE; + REPORT " Soft path metric: " & INTEGER'IMAGE(to_integer(unsigned(soft_path_metric))) SEVERITY NOTE; + + ASSERT hard_errors = 0 REPORT "Hard decoder failed clean test!" SEVERITY ERROR; + ASSERT soft_errors = 0 REPORT "Soft decoder failed clean test!" SEVERITY ERROR; + + WAIT FOR CLK_PERIOD * 10; + + -------------------------------------------------------------------- + -- Test 2: Channel with errors (hard bits flipped) + -- Soft decoder should outperform by using confidence info + -------------------------------------------------------------------- + REPORT "=== Test 2: Noisy channel (5% BER) ===" SEVERITY NOTE; + + -- Initialize upper bits of hard decoder inputs + hard_input_g1 <= (OTHERS => '0'); + hard_input_g2 <= (OTHERS => '0'); + + -- Generate new random payload + FOR i IN 0 TO PAYLOAD_BITS-1 LOOP + uniform(seed1, seed2, rand); + IF rand > 0.5 THEN + original_data(i) <= '1'; + ELSE + original_data(i) <= '0'; + END IF; + END LOOP; + WAIT FOR CLK_PERIOD; + + -- Encode + conv_encode(original_data, encoded_g1, encoded_g2); + WAIT FOR CLK_PERIOD; + + -- Inject errors and create soft values + num_injected_errors := 0; + FOR i IN 0 TO NUM_SYMBOLS-1 LOOP + -- G1 + uniform(seed1, seed2, rand); + IF rand < 0.05 THEN -- 5% error rate + -- Error: flip hard bit, use LOW confidence soft value + hard_input_g1(i) <= NOT encoded_g1(i); + -- Soft value near middle (uncertain) + IF encoded_g1(i) = '0' THEN + soft_input_g1((i+1)*SOFT_WIDTH-1 DOWNTO i*SOFT_WIDTH) <= + std_logic_vector(to_unsigned(SOFT_MAX/2 + 1, SOFT_WIDTH)); -- Wrong side but low confidence + ELSE + soft_input_g1((i+1)*SOFT_WIDTH-1 DOWNTO i*SOFT_WIDTH) <= + std_logic_vector(to_unsigned(SOFT_MAX/2 - 1, SOFT_WIDTH)); -- Wrong side but low confidence + END IF; + num_injected_errors := num_injected_errors + 1; + ELSE + -- No error: use HIGH confidence + hard_input_g1(i) <= encoded_g1(i); + soft_input_g1((i+1)*SOFT_WIDTH-1 DOWNTO i*SOFT_WIDTH) <= + hard_to_soft(encoded_g1(i), SOFT_MAX); + END IF; + + -- G2 + uniform(seed1, seed2, rand); + IF rand < 0.05 THEN + hard_input_g2(i) <= NOT encoded_g2(i); + IF encoded_g2(i) = '0' THEN + soft_input_g2((i+1)*SOFT_WIDTH-1 DOWNTO i*SOFT_WIDTH) <= + std_logic_vector(to_unsigned(SOFT_MAX/2 + 1, SOFT_WIDTH)); + ELSE + soft_input_g2((i+1)*SOFT_WIDTH-1 DOWNTO i*SOFT_WIDTH) <= + std_logic_vector(to_unsigned(SOFT_MAX/2 - 1, SOFT_WIDTH)); + END IF; + num_injected_errors := num_injected_errors + 1; + ELSE + hard_input_g2(i) <= encoded_g2(i); + soft_input_g2((i+1)*SOFT_WIDTH-1 DOWNTO i*SOFT_WIDTH) <= + hard_to_soft(encoded_g2(i), SOFT_MAX); + END IF; + END LOOP; + WAIT FOR CLK_PERIOD; + + REPORT " Injected " & INTEGER'IMAGE(num_injected_errors) & " channel errors" SEVERITY NOTE; + + -- Run both decoders + hard_start <= '1'; + soft_start <= '1'; + WAIT FOR CLK_PERIOD; + hard_start <= '0'; + soft_start <= '0'; + + -- Wait for completion + WAIT UNTIL hard_done = '1' AND soft_done = '1'; + WAIT FOR CLK_PERIOD * 2; + + -- Check results + hard_errors := 0; + soft_errors := 0; + FOR i IN 0 TO PAYLOAD_BITS-1 LOOP + IF hard_output(i) /= original_data(PAYLOAD_BITS-1-i) THEN + hard_errors := hard_errors + 1; + END IF; + IF soft_output(i) /= original_data(PAYLOAD_BITS-1-i) THEN + soft_errors := soft_errors + 1; + END IF; + END LOOP; + + REPORT " Hard decoder errors: " & INTEGER'IMAGE(hard_errors) SEVERITY NOTE; + REPORT " Soft decoder errors: " & INTEGER'IMAGE(soft_errors) SEVERITY NOTE; + REPORT " Soft path metric: " & INTEGER'IMAGE(to_integer(unsigned(soft_path_metric))) SEVERITY NOTE; + + IF soft_errors < hard_errors THEN + REPORT " SOFT DECODER WINS! (" & INTEGER'IMAGE(hard_errors - soft_errors) & " fewer errors)" SEVERITY NOTE; + ELSIF soft_errors = hard_errors THEN + REPORT " TIE" SEVERITY NOTE; + ELSE + REPORT " Hard decoder wins (unexpected)" SEVERITY WARNING; + END IF; + + WAIT FOR CLK_PERIOD * 10; + + -------------------------------------------------------------------- + -- Test 3: High noise (10% BER) + -------------------------------------------------------------------- + REPORT "=== Test 3: High noise (10% BER) ===" SEVERITY NOTE; + + -- Initialize upper bits of hard decoder inputs + hard_input_g1 <= (OTHERS => '0'); + hard_input_g2 <= (OTHERS => '0'); + + -- Generate new random payload + FOR i IN 0 TO PAYLOAD_BITS-1 LOOP + uniform(seed1, seed2, rand); + IF rand > 0.5 THEN + original_data(i) <= '1'; + ELSE + original_data(i) <= '0'; + END IF; + END LOOP; + WAIT FOR CLK_PERIOD; + + -- Encode + conv_encode(original_data, encoded_g1, encoded_g2); + WAIT FOR CLK_PERIOD; + + -- Inject errors at 10% rate + num_injected_errors := 0; + FOR i IN 0 TO NUM_SYMBOLS-1 LOOP + uniform(seed1, seed2, rand); + IF rand < 0.10 THEN + hard_input_g1(i) <= NOT encoded_g1(i); + IF encoded_g1(i) = '0' THEN + soft_input_g1((i+1)*SOFT_WIDTH-1 DOWNTO i*SOFT_WIDTH) <= + std_logic_vector(to_unsigned(SOFT_MAX/2 + 1, SOFT_WIDTH)); + ELSE + soft_input_g1((i+1)*SOFT_WIDTH-1 DOWNTO i*SOFT_WIDTH) <= + std_logic_vector(to_unsigned(SOFT_MAX/2 - 1, SOFT_WIDTH)); + END IF; + num_injected_errors := num_injected_errors + 1; + ELSE + hard_input_g1(i) <= encoded_g1(i); + soft_input_g1((i+1)*SOFT_WIDTH-1 DOWNTO i*SOFT_WIDTH) <= + hard_to_soft(encoded_g1(i), SOFT_MAX); + END IF; + + uniform(seed1, seed2, rand); + IF rand < 0.10 THEN + hard_input_g2(i) <= NOT encoded_g2(i); + IF encoded_g2(i) = '0' THEN + soft_input_g2((i+1)*SOFT_WIDTH-1 DOWNTO i*SOFT_WIDTH) <= + std_logic_vector(to_unsigned(SOFT_MAX/2 + 1, SOFT_WIDTH)); + ELSE + soft_input_g2((i+1)*SOFT_WIDTH-1 DOWNTO i*SOFT_WIDTH) <= + std_logic_vector(to_unsigned(SOFT_MAX/2 - 1, SOFT_WIDTH)); + END IF; + num_injected_errors := num_injected_errors + 1; + ELSE + hard_input_g2(i) <= encoded_g2(i); + soft_input_g2((i+1)*SOFT_WIDTH-1 DOWNTO i*SOFT_WIDTH) <= + hard_to_soft(encoded_g2(i), SOFT_MAX); + END IF; + END LOOP; + WAIT FOR CLK_PERIOD; + + REPORT " Injected " & INTEGER'IMAGE(num_injected_errors) & " channel errors" SEVERITY NOTE; + + -- Run both decoders + hard_start <= '1'; + soft_start <= '1'; + WAIT FOR CLK_PERIOD; + hard_start <= '0'; + soft_start <= '0'; + + WAIT UNTIL hard_done = '1' AND soft_done = '1'; + WAIT FOR CLK_PERIOD * 2; + + hard_errors := 0; + soft_errors := 0; + FOR i IN 0 TO PAYLOAD_BITS-1 LOOP + IF hard_output(i) /= original_data(PAYLOAD_BITS-1-i) THEN + hard_errors := hard_errors + 1; + END IF; + IF soft_output(i) /= original_data(PAYLOAD_BITS-1-i) THEN + soft_errors := soft_errors + 1; + END IF; + END LOOP; + + REPORT " Hard decoder errors: " & INTEGER'IMAGE(hard_errors) SEVERITY NOTE; + REPORT " Soft decoder errors: " & INTEGER'IMAGE(soft_errors) SEVERITY NOTE; + REPORT " Soft path metric: " & INTEGER'IMAGE(to_integer(unsigned(soft_path_metric))) SEVERITY NOTE; + + IF soft_errors < hard_errors THEN + REPORT " SOFT DECODER WINS! (" & INTEGER'IMAGE(hard_errors - soft_errors) & " fewer errors)" SEVERITY NOTE; + ELSIF soft_errors = hard_errors THEN + REPORT " TIE" SEVERITY NOTE; + ELSE + REPORT " Hard decoder wins (unexpected)" SEVERITY WARNING; + END IF; + + WAIT FOR CLK_PERIOD * 10; + + REPORT "=== All tests complete ===" SEVERITY NOTE; + std.env.stop; + + END PROCESS; + +END ARCHITECTURE sim; diff --git a/src/viterbi_decoder_k7.vhd b/src/viterbi_decoder_k7.vhd new file mode 100644 index 0000000..3539c94 --- /dev/null +++ b/src/viterbi_decoder_k7.vhd @@ -0,0 +1,358 @@ +------------------------------------------------------------------------------------------------------ +-- Soft-Decision Viterbi Decoder for K=7 Convolutional Code +------------------------------------------------------------------------------------------------------ +-- Rate 1/2, constraint length K=7, 64 states +-- Generator polynomials: G1 = 171 octal, G2 = 133 octal (NASA Voyager code) +-- +-- Supports both hard-decision (1-bit) and soft-decision (3-4 bit) inputs +-- Uses register-exchange for survivor path management (simpler than traceback memory) +-- +-- Performance: +-- Hard decisions: ~5 dB coding gain at BER=10^-5 +-- 3-bit soft: ~7 dB coding gain (2 dB improvement over hard) +-- 4-bit soft: ~7.3 dB coding gain (marginal improvement over 3-bit) +-- +-- Think of this like a maze solver that tracks 64 parallel adventurer parties, +-- keeping only the most efficient path to each destination +------------------------------------------------------------------------------------------------------ + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +ENTITY viterbi_decoder_k7 IS + GENERIC ( + PAYLOAD_BYTES : NATURAL := 134; -- Output size in bytes + ENCODED_BYTES : NATURAL := 268; -- Input size in bytes + SOFT_DECISION_WIDTH : NATURAL := 3; -- Bits per soft input (1=hard, 3-4=soft) + TRACEBACK_DEPTH : NATURAL := 35; -- Path memory depth (5*K is typical) + METRIC_WIDTH : NATURAL := 12 -- Path metric width (avoid overflow) + ); + PORT ( + clk : IN std_logic; + aresetn : IN std_logic; + + -- Control + start : IN std_logic; + busy : OUT std_logic; + done : OUT std_logic; + + -- Input buffer (soft decisions, MSB first) + -- For hard decisions: use only MSB of each symbol + -- For soft decisions: full SOFT_DECISION_WIDTH bits represent confidence + -- Most positive value = strong '1', most negative = strong '0' + input_buffer_g1 : IN std_logic_vector(ENCODED_BYTES*4-1 DOWNTO 0); + input_buffer_g2 : IN std_logic_vector(ENCODED_BYTES*4-1 DOWNTO 0); + + -- Output buffer (decoded bits, MSB first) + output_buffer : OUT std_logic_vector(PAYLOAD_BYTES*8-1 DOWNTO 0); + + -- Debug/monitoring + path_metric_min : OUT std_logic_vector(METRIC_WIDTH-1 DOWNTO 0); + path_metric_max : OUT std_logic_vector(METRIC_WIDTH-1 DOWNTO 0) + ); +END ENTITY viterbi_decoder_k7; + +ARCHITECTURE rtl OF viterbi_decoder_k7 IS + + CONSTANT NUM_STATES : NATURAL := 64; -- 2^(K-1) states + CONSTANT TRACEBACK_LENGTH : NATURAL := TRACEBACK_DEPTH; + + -- State machine + TYPE state_t IS (IDLE, INIT_METRICS, DECODE_BITS, TRACEBACK, COMPLETE); + SIGNAL state : state_t := IDLE; + + -- Path metrics: one metric per state (track cumulative "cost" to reach each state) + TYPE metric_array_t IS ARRAY(0 TO NUM_STATES-1) OF signed(METRIC_WIDTH-1 DOWNTO 0); + SIGNAL path_metrics_curr : metric_array_t := (OTHERS => (OTHERS => '0')); + SIGNAL path_metrics_next : metric_array_t := (OTHERS => (OTHERS => '0')); + + -- Survivor path memory: register-exchange method + -- Each state stores its best path history + TYPE path_history_t IS ARRAY(0 TO TRACEBACK_LENGTH-1) OF std_logic; + TYPE survivor_memory_t IS ARRAY(0 TO NUM_STATES-1) OF path_history_t; + SIGNAL survivor_paths_curr : survivor_memory_t; + SIGNAL survivor_paths_next : survivor_memory_t; + + -- Branch metrics: cost to take each transition + SIGNAL branch_metric_00 : signed(METRIC_WIDTH-1 DOWNTO 0); -- Output = 00 + SIGNAL branch_metric_01 : signed(METRIC_WIDTH-1 DOWNTO 0); -- Output = 01 + SIGNAL branch_metric_10 : signed(METRIC_WIDTH-1 DOWNTO 0); -- Output = 10 + SIGNAL branch_metric_11 : signed(METRIC_WIDTH-1 DOWNTO 0); -- Output = 11 + + -- Bit processing + SIGNAL bit_index : NATURAL RANGE 0 TO ENCODED_BYTES*4; + SIGNAL output_bit_index : NATURAL RANGE 0 TO PAYLOAD_BYTES*8; + + -- Current received symbols (soft decisions) + SIGNAL rx_g1 : signed(SOFT_DECISION_WIDTH-1 DOWNTO 0); + SIGNAL rx_g2 : signed(SOFT_DECISION_WIDTH-1 DOWNTO 0); + + -- Trellis butterfly outputs (expected G1, G2 for each input bit) + TYPE output_lut_t IS ARRAY(0 TO NUM_STATES-1, 0 TO 1) OF std_logic_vector(1 DOWNTO 0); + SIGNAL expected_outputs : output_lut_t; + + -- Output buffer working copy + SIGNAL out_buf : std_logic_vector(PAYLOAD_BYTES*8-1 DOWNTO 0); + + -- Best path tracking for traceback + SIGNAL best_state : NATURAL RANGE 0 TO NUM_STATES-1; + SIGNAL traceback_bit : NATURAL RANGE 0 TO TRACEBACK_LENGTH-1; + + -------------------------------------------------------------------------------------------- + -- Precompute expected outputs for each state transition + -- This is the trellis structure for K=7, rate 1/2 code + -------------------------------------------------------------------------------------------- + FUNCTION compute_expected_output( + current_state : NATURAL; + input_bit : std_logic + ) RETURN std_logic_vector IS + VARIABLE full_state : std_logic_vector(6 DOWNTO 0); + VARIABLE g1, g2 : std_logic; + CONSTANT G1_POLY : std_logic_vector(6 DOWNTO 0) := "1111001"; + CONSTANT G2_POLY : std_logic_vector(6 DOWNTO 0) := "1011011"; + BEGIN + -- Construct full state (input bit + 6 state bits) + full_state := input_bit & std_logic_vector(to_unsigned(current_state, 6)); + + -- Compute G1 output + g1 := '0'; + FOR i IN 0 TO 6 LOOP + IF G1_POLY(i) = '1' THEN + g1 := g1 XOR full_state(6-i); + END IF; + END LOOP; + + -- Compute G2 output + g2 := '0'; + FOR i IN 0 TO 6 LOOP + IF G2_POLY(i) = '1' THEN + g2 := g2 XOR full_state(6-i); + END IF; + END LOOP; + + RETURN g1 & g2; + END FUNCTION; + +BEGIN + + -------------------------------------------------------------------------------------------- + -- Initialize expected output LUT (done once at elaboration time) + -------------------------------------------------------------------------------------------- + gen_lut: PROCESS + BEGIN + FOR s IN 0 TO NUM_STATES-1 LOOP + expected_outputs(s, 0) <= compute_expected_output(s, '0'); + expected_outputs(s, 1) <= compute_expected_output(s, '1'); + END LOOP; + WAIT; -- Static initialization + END PROCESS; + + -------------------------------------------------------------------------------------------- + -- Branch Metric Computation + -- For soft decisions: Euclidean distance between received and expected + -- For hard decisions: Hamming distance + -------------------------------------------------------------------------------------------- + PROCESS(rx_g1, rx_g2) + VARIABLE diff_g1, diff_g2 : signed(SOFT_DECISION_WIDTH DOWNTO 0); + VARIABLE metric : signed(METRIC_WIDTH-1 DOWNTO 0); + BEGIN + -- Expected output 00 (both symbols are '0' = most negative value) + diff_g1 := resize(rx_g1, SOFT_DECISION_WIDTH+1) + + to_signed(2**(SOFT_DECISION_WIDTH-1), SOFT_DECISION_WIDTH+1); + diff_g2 := resize(rx_g2, SOFT_DECISION_WIDTH+1) + + to_signed(2**(SOFT_DECISION_WIDTH-1), SOFT_DECISION_WIDTH+1); + branch_metric_00 <= resize(diff_g1*diff_g1 + diff_g2*diff_g2, METRIC_WIDTH); + + -- Expected output 01 (g1='0', g2='1') + diff_g1 := resize(rx_g1, SOFT_DECISION_WIDTH+1) + + to_signed(2**(SOFT_DECISION_WIDTH-1), SOFT_DECISION_WIDTH+1); + diff_g2 := resize(rx_g2, SOFT_DECISION_WIDTH+1) - + to_signed(2**(SOFT_DECISION_WIDTH-1)-1, SOFT_DECISION_WIDTH+1); + branch_metric_01 <= resize(diff_g1*diff_g1 + diff_g2*diff_g2, METRIC_WIDTH); + + -- Expected output 10 + diff_g1 := resize(rx_g1, SOFT_DECISION_WIDTH+1) - + to_signed(2**(SOFT_DECISION_WIDTH-1)-1, SOFT_DECISION_WIDTH+1); + diff_g2 := resize(rx_g2, SOFT_DECISION_WIDTH+1) + + to_signed(2**(SOFT_DECISION_WIDTH-1), SOFT_DECISION_WIDTH+1); + branch_metric_10 <= resize(diff_g1*diff_g1 + diff_g2*diff_g2, METRIC_WIDTH); + + -- Expected output 11 + diff_g1 := resize(rx_g1, SOFT_DECISION_WIDTH+1) - + to_signed(2**(SOFT_DECISION_WIDTH-1)-1, SOFT_DECISION_WIDTH+1); + diff_g2 := resize(rx_g2, SOFT_DECISION_WIDTH+1) - + to_signed(2**(SOFT_DECISION_WIDTH-1)-1, SOFT_DECISION_WIDTH+1); + branch_metric_11 <= resize(diff_g1*diff_g1 + diff_g2*diff_g2, METRIC_WIDTH); + END PROCESS; + + -------------------------------------------------------------------------------------------- + -- Main Viterbi Decoder State Machine + -------------------------------------------------------------------------------------------- + PROCESS(clk, aresetn) + VARIABLE prev_state_0, prev_state_1 : NATURAL RANGE 0 TO NUM_STATES-1; + VARIABLE metric_0, metric_1 : signed(METRIC_WIDTH-1 DOWNTO 0); + VARIABLE input_bit_0, input_bit_1 : std_logic; + VARIABLE expected_out_0, expected_out_1 : std_logic_vector(1 DOWNTO 0); + VARIABLE branch_met_0, branch_met_1 : signed(METRIC_WIDTH-1 DOWNTO 0); + VARIABLE min_metric, max_metric : signed(METRIC_WIDTH-1 DOWNTO 0); + BEGIN + IF aresetn = '0' THEN + state <= IDLE; + busy <= '0'; + done <= '0'; + bit_index <= 0; + output_bit_index <= 0; + path_metrics_curr <= (OTHERS => (OTHERS => '0')); + + ELSIF rising_edge(clk) THEN + done <= '0'; -- Pulse signal + + CASE state IS + + WHEN IDLE => + busy <= '0'; + IF start = '1' THEN + state <= INIT_METRICS; + busy <= '1'; + bit_index <= 0; + output_bit_index <= 0; + END IF; + + WHEN INIT_METRICS => + -- Initialize: state 0 has metric 0, all others have large metric + FOR i IN 0 TO NUM_STATES-1 LOOP + IF i = 0 THEN + path_metrics_curr(i) <= (OTHERS => '0'); + ELSE + path_metrics_curr(i) <= to_signed(2**(METRIC_WIDTH-2), METRIC_WIDTH); + END IF; + -- Clear survivor paths + FOR j IN 0 TO TRACEBACK_LENGTH-1 LOOP + survivor_paths_curr(i)(j) <= '0'; + END LOOP; + END LOOP; + state <= DECODE_BITS; + + WHEN DECODE_BITS => + IF bit_index < (PAYLOAD_BYTES*8 + 6)*2 THEN -- Include 6 flush bits + -- Get received soft symbols + rx_g1 <= signed(input_buffer_g1( + ENCODED_BYTES*4-1 - bit_index*SOFT_DECISION_WIDTH DOWNTO + ENCODED_BYTES*4 - (bit_index+1)*SOFT_DECISION_WIDTH)); + rx_g2 <= signed(input_buffer_g2( + ENCODED_BYTES*4-1 - bit_index*SOFT_DECISION_WIDTH DOWNTO + ENCODED_BYTES*4 - (bit_index+1)*SOFT_DECISION_WIDTH)); + + -- ACS (Add-Compare-Select) for all states + FOR s IN 0 TO NUM_STATES-1 LOOP + -- Each state can be reached from two previous states + -- Previous state that led here with input bit = 0 + prev_state_0 := (s * 2) MOD NUM_STATES; + -- Previous state that led here with input bit = 1 + prev_state_1 := ((s * 2) + 1) MOD NUM_STATES; + + -- Get expected outputs for these transitions + expected_out_0 := expected_outputs(prev_state_0, 0); + expected_out_1 := expected_outputs(prev_state_1, 1); + + -- Branch metrics + CASE expected_out_0 IS + WHEN "00" => branch_met_0 := branch_metric_00; + WHEN "01" => branch_met_0 := branch_metric_01; + WHEN "10" => branch_met_0 := branch_metric_10; + WHEN "11" => branch_met_0 := branch_metric_11; + WHEN OTHERS => branch_met_0 := (OTHERS => '0'); + END CASE; + + CASE expected_out_1 IS + WHEN "00" => branch_met_1 := branch_metric_00; + WHEN "01" => branch_met_1 := branch_metric_01; + WHEN "10" => branch_met_1 := branch_metric_10; + WHEN "11" => branch_met_1 := branch_metric_11; + WHEN OTHERS => branch_met_1 := (OTHERS => '0'); + END CASE; + + -- Add-Compare-Select + metric_0 := path_metrics_curr(prev_state_0) + branch_met_0; + metric_1 := path_metrics_curr(prev_state_1) + branch_met_1; + + IF metric_0 < metric_1 THEN + path_metrics_next(s) <= metric_0; + input_bit_0 := '0'; + -- Shift survivor path and prepend decision + FOR j IN TRACEBACK_LENGTH-1 DOWNTO 1 LOOP + survivor_paths_next(s)(j) <= survivor_paths_curr(prev_state_0)(j-1); + END LOOP; + survivor_paths_next(s)(0) <= input_bit_0; + ELSE + path_metrics_next(s) <= metric_1; + input_bit_1 := '1'; + FOR j IN TRACEBACK_LENGTH-1 DOWNTO 1 LOOP + survivor_paths_next(s)(j) <= survivor_paths_curr(prev_state_1)(j-1); + END LOOP; + survivor_paths_next(s)(0) <= input_bit_1; + END IF; + END LOOP; + + -- Update current metrics + path_metrics_curr <= path_metrics_next; + survivor_paths_curr <= survivor_paths_next; + + bit_index <= bit_index + 2; -- Processed 2 symbols + ELSE + state <= TRACEBACK; + traceback_bit <= 0; + + -- Find best ending state (should be state 0 due to flush bits) + min_metric := path_metrics_curr(0); + best_state <= 0; + FOR i IN 1 TO NUM_STATES-1 LOOP + IF path_metrics_curr(i) < min_metric THEN + min_metric := path_metrics_curr(i); + best_state <= i; + END IF; + END LOOP; + END IF; + + WHEN TRACEBACK => + -- Extract decoded bits from survivor path of best state + IF traceback_bit < PAYLOAD_BYTES*8 THEN + out_buf(PAYLOAD_BYTES*8 - 1 - traceback_bit) <= + survivor_paths_curr(best_state)(TRACEBACK_LENGTH - 1 - traceback_bit); + traceback_bit <= traceback_bit + 1; + ELSE + state <= COMPLETE; + END IF; + + WHEN COMPLETE => + done <= '1'; + busy <= '0'; + state <= IDLE; + + END CASE; + END IF; + END PROCESS; + + -- Output assignment + output_buffer <= out_buf; + + -- Debug outputs + PROCESS(path_metrics_curr) + VARIABLE min_val, max_val : signed(METRIC_WIDTH-1 DOWNTO 0); + BEGIN + min_val := path_metrics_curr(0); + max_val := path_metrics_curr(0); + FOR i IN 1 TO NUM_STATES-1 LOOP + IF path_metrics_curr(i) < min_val THEN + min_val := path_metrics_curr(i); + END IF; + IF path_metrics_curr(i) > max_val THEN + max_val := path_metrics_curr(i); + END IF; + END LOOP; + path_metric_min <= std_logic_vector(min_val); + path_metric_max <= std_logic_vector(max_val); + END PROCESS; + +END ARCHITECTURE rtl; diff --git a/src/viterbi_decoder_k7_simple.vhd b/src/viterbi_decoder_k7_simple.vhd new file mode 100644 index 0000000..1bf39be --- /dev/null +++ b/src/viterbi_decoder_k7_simple.vhd @@ -0,0 +1,318 @@ +------------------------------------------------------------------------------------------------------ +-- BRAM-Optimized Viterbi Decoder - SHIFT REGISTER INPUTS +------------------------------------------------------------------------------------------------------ +-- This version uses shift registers for the input data to avoid massive muxes. +-- Instead of input_bits_g1(time_step) creating a 1072:1 mux, we: +-- 1. Load the parallel input into a shift register +-- 2. Shift out one bit per time step +-- +-- This saves ~2000 LUTs (2 x 1072:1 mux elimination) +-- +-- Interface is IDENTICAL to original - parallel load happens internally. +------------------------------------------------------------------------------------------------------ + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +ENTITY viterbi_decoder_k7_simple IS + GENERIC ( + PAYLOAD_BITS : NATURAL := 134*8; + ENCODED_BITS : NATURAL := 268*8; + TRACEBACK_DEPTH : NATURAL := 35 + ); + PORT ( + clk : IN std_logic; + aresetn : IN std_logic; + start : IN std_logic; + busy : OUT std_logic; + done : OUT std_logic; + input_bits_g1 : IN std_logic_vector(ENCODED_BITS-1 DOWNTO 0); + input_bits_g2 : IN std_logic_vector(ENCODED_BITS-1 DOWNTO 0); + output_bits : OUT std_logic_vector(PAYLOAD_BITS-1 DOWNTO 0) + ); +END ENTITY viterbi_decoder_k7_simple; + +ARCHITECTURE rtl OF viterbi_decoder_k7_simple IS + + ATTRIBUTE KEEP_HIERARCHY : STRING; + ATTRIBUTE KEEP_HIERARCHY OF rtl : ARCHITECTURE IS "yes"; + + CONSTANT NUM_STATES : INTEGER := 64; + CONSTANT METRIC_WIDTH : INTEGER := 12; + CONSTANT INF_METRIC : INTEGER := 4095; + CONSTANT NUM_SYMBOLS : INTEGER := ENCODED_BITS/2; -- 1072 + + TYPE state_t IS (IDLE, INITIALIZE, ACS_COMPUTE, FIND_BEST, + TB_FETCH, TB_USE, COMPLETE); + SIGNAL state : state_t := IDLE; + + TYPE metric_array_t IS ARRAY(0 TO NUM_STATES-1) OF unsigned(METRIC_WIDTH-1 DOWNTO 0); + SIGNAL metrics_current : metric_array_t := (OTHERS => (OTHERS => '0')); + SIGNAL metrics_next : metric_array_t := (OTHERS => (OTHERS => '0')); + + -- Decision memory in BRAM + CONSTANT DECISION_DEPTH : INTEGER := NUM_SYMBOLS * NUM_STATES; + TYPE decision_mem_t IS ARRAY(0 TO DECISION_DEPTH-1) OF std_logic; + SIGNAL decision_mem : decision_mem_t; + + SIGNAL dec_wr_en : std_logic; + SIGNAL dec_wr_addr : INTEGER RANGE 0 TO DECISION_DEPTH-1; + SIGNAL dec_wr_data : std_logic; + SIGNAL dec_rd_addr : INTEGER RANGE 0 TO DECISION_DEPTH-1; + SIGNAL dec_rd_data : std_logic; + + SIGNAL time_step : INTEGER RANGE 0 TO NUM_SYMBOLS; + SIGNAL state_idx : INTEGER RANGE 0 TO NUM_STATES-1; + SIGNAL tb_time : INTEGER RANGE -1 TO NUM_SYMBOLS; + SIGNAL tb_state : INTEGER RANGE 0 TO NUM_STATES-1; + + SIGNAL out_buf : std_logic_vector(PAYLOAD_BITS-1 DOWNTO 0); + SIGNAL rx_symbol : std_logic_vector(1 DOWNTO 0); + + -- SHIFT REGISTERS for input data (replaces massive mux) + -- These shift left, MSB contains current symbol + SIGNAL g1_sr : std_logic_vector(NUM_SYMBOLS-1 DOWNTO 0); + SIGNAL g2_sr : std_logic_vector(NUM_SYMBOLS-1 DOWNTO 0); + + ATTRIBUTE ram_style : STRING; + ATTRIBUTE ram_style OF decision_mem : SIGNAL IS "block"; + + ATTRIBUTE dont_touch : STRING; + ATTRIBUTE dont_touch OF state : SIGNAL IS "true"; + ATTRIBUTE dont_touch OF metrics_current : SIGNAL IS "true"; + ATTRIBUTE dont_touch OF metrics_next : SIGNAL IS "true"; + ATTRIBUTE dont_touch OF decision_mem : SIGNAL IS "true"; + ATTRIBUTE dont_touch OF g1_sr : SIGNAL IS "true"; + ATTRIBUTE dont_touch OF g2_sr : SIGNAL IS "true"; + ATTRIBUTE dont_touch OF out_buf : SIGNAL IS "true"; + ATTRIBUTE dont_touch OF time_step : SIGNAL IS "true"; + ATTRIBUTE dont_touch OF tb_time : SIGNAL IS "true"; + ATTRIBUTE dont_touch OF tb_state : SIGNAL IS "true"; + + ATTRIBUTE ram_style OF g1_sr : SIGNAL IS "block"; + ATTRIBUTE ram_style OF g2_sr : SIGNAL IS "block"; + ATTRIBUTE ram_style OF out_buf : SIGNAL IS "block"; + + + + FUNCTION compute_output(curr_state : INTEGER; input_bit : std_logic) + RETURN std_logic_vector IS + CONSTANT G1_POLY : std_logic_vector(6 DOWNTO 0) := "1111001"; + CONSTANT G2_POLY : std_logic_vector(6 DOWNTO 0) := "1011011"; + VARIABLE full_state : std_logic_vector(6 DOWNTO 0); + VARIABLE g1, g2 : std_logic; + BEGIN + full_state := input_bit & std_logic_vector(to_unsigned(curr_state, 6)); + + g1 := '0'; + FOR i IN 0 TO 6 LOOP + IF G1_POLY(i) = '1' THEN + g1 := g1 XOR full_state(6-i); + END IF; + END LOOP; + + g2 := '0'; + FOR i IN 0 TO 6 LOOP + IF G2_POLY(i) = '1' THEN + g2 := g2 XOR full_state(6-i); + END IF; + END LOOP; + + RETURN g1 & g2; + END FUNCTION; + + FUNCTION hamming_distance(a, b : std_logic_vector) RETURN INTEGER IS + VARIABLE dist : INTEGER := 0; + BEGIN + FOR i IN a'RANGE LOOP + IF a(i) /= b(i) THEN + dist := dist + 1; + END IF; + END LOOP; + RETURN dist; + END FUNCTION; + +BEGIN + + -- BRAM write process + PROCESS(clk) + BEGIN + IF rising_edge(clk) THEN + IF dec_wr_en = '1' THEN + decision_mem(dec_wr_addr) <= dec_wr_data; + END IF; + END IF; + END PROCESS; + + -- BRAM read process + PROCESS(clk) + BEGIN + IF rising_edge(clk) THEN + dec_rd_data <= decision_mem(dec_rd_addr); + END IF; + END PROCESS; + + -- Main FSM + PROCESS(clk, aresetn) + VARIABLE prev_state_0, prev_state_1 : INTEGER RANGE 0 TO NUM_STATES-1; + VARIABLE input_bit : std_logic; + VARIABLE expected_0, expected_1 : std_logic_vector(1 DOWNTO 0); + VARIABLE metric_0, metric_1 : unsigned(METRIC_WIDTH-1 DOWNTO 0); + VARIABLE min_metric : unsigned(METRIC_WIDTH-1 DOWNTO 0); + VARIABLE best_state_var : INTEGER RANGE 0 TO NUM_STATES-1; + BEGIN + IF aresetn = '0' THEN + state <= IDLE; + busy <= '0'; + done <= '0'; + dec_wr_en <= '0'; + time_step <= 0; + state_idx <= 0; + metrics_next <= (OTHERS => (OTHERS => '0')); + g1_sr <= (OTHERS => '0'); + g2_sr <= (OTHERS => '0'); + + ELSIF rising_edge(clk) THEN + done <= '0'; + dec_wr_en <= '0'; + + CASE state IS + + WHEN IDLE => + busy <= '0'; + IF start = '1' THEN + state <= INITIALIZE; + busy <= '1'; + state_idx <= 0; + -- PARALLEL LOAD shift registers from input vectors + -- Load bits 0..1071 directly - simple slice, no mux needed + -- We'll read from bit 0 and shift right each time step + g1_sr <= input_bits_g1(NUM_SYMBOLS-1 DOWNTO 0); + g2_sr <= input_bits_g2(NUM_SYMBOLS-1 DOWNTO 0); + END IF; + + WHEN INITIALIZE => + IF state_idx < NUM_STATES THEN + IF state_idx = 0 THEN + metrics_current(state_idx) <= (OTHERS => '0'); + ELSE + metrics_current(state_idx) <= to_unsigned(INF_METRIC, METRIC_WIDTH); + END IF; + state_idx <= state_idx + 1; + ELSE + state <= ACS_COMPUTE; + state_idx <= 0; + time_step <= 0; + END IF; + + WHEN ACS_COMPUTE => + IF time_step < NUM_SYMBOLS THEN + IF state_idx = 0 THEN + -- Get current symbol from LSB of shift registers + rx_symbol <= g1_sr(0) & g2_sr(0); + END IF; + + IF state_idx < NUM_STATES THEN + prev_state_0 := state_idx / 2; + prev_state_1 := (state_idx / 2) + 32; + input_bit := std_logic(to_unsigned(state_idx MOD 2, 1)(0)); + + expected_0 := compute_output(prev_state_0, input_bit); + metric_0 := metrics_current(prev_state_0) + + to_unsigned(hamming_distance(rx_symbol, expected_0), METRIC_WIDTH); + + expected_1 := compute_output(prev_state_1, input_bit); + metric_1 := metrics_current(prev_state_1) + + to_unsigned(hamming_distance(rx_symbol, expected_1), METRIC_WIDTH); + + IF metric_0 <= metric_1 THEN + metrics_next(state_idx) <= metric_0; + dec_wr_data <= '0'; + ELSE + metrics_next(state_idx) <= metric_1; + dec_wr_data <= '1'; + END IF; + + dec_wr_addr <= time_step * NUM_STATES + state_idx; + dec_wr_en <= '1'; + state_idx <= state_idx + 1; + ELSE + -- Done with all states for this time step + metrics_current <= metrics_next; + state_idx <= 0; + time_step <= time_step + 1; + -- SHIFT RIGHT: next symbol moves to bit 0 + g1_sr <= '0' & g1_sr(NUM_SYMBOLS-1 DOWNTO 1); + g2_sr <= '0' & g2_sr(NUM_SYMBOLS-1 DOWNTO 1); + END IF; + ELSE + state <= FIND_BEST; + state_idx <= 0; + END IF; + + WHEN FIND_BEST => + IF state_idx = 0 THEN + min_metric := metrics_current(0); + best_state_var := 0; + state_idx <= 1; + ELSIF state_idx < NUM_STATES THEN + IF metrics_current(state_idx) < min_metric THEN + min_metric := metrics_current(state_idx); + best_state_var := state_idx; + END IF; + state_idx <= state_idx + 1; + ELSE + tb_state <= best_state_var; + tb_time <= NUM_SYMBOLS - 1; + dec_rd_addr <= (NUM_SYMBOLS-1) * NUM_STATES + best_state_var; + state <= TB_FETCH; + END IF; + + -- SIMPLIFIED 2-CYCLE TRACEBACK + WHEN TB_FETCH => + -- Cycle 1: Issue BRAM read for current (tb_time, tb_state) + state <= TB_USE; + + WHEN TB_USE => + -- Cycle 2: Use the decision that was fetched + IF tb_time >= 0 THEN + -- Output decoded bit + out_buf(tb_time) <= std_logic(to_unsigned(tb_state MOD 2, 1)(0)); + + -- Move to previous state based on decision + IF dec_rd_data = '0' THEN + tb_state <= tb_state / 2; + ELSE + tb_state <= (tb_state / 2) + 32; + END IF; + + tb_time <= tb_time - 1; + + -- Fetch next decision (if not done) + IF tb_time > 0 THEN + IF dec_rd_data = '0' THEN + dec_rd_addr <= (tb_time-1) * NUM_STATES + (tb_state / 2); + ELSE + dec_rd_addr <= (tb_time-1) * NUM_STATES + ((tb_state / 2) + 32); + END IF; + state <= TB_FETCH; + ELSE + state <= COMPLETE; + END IF; + ELSE + state <= COMPLETE; + END IF; + + WHEN COMPLETE => + done <= '1'; + busy <= '0'; + state <= IDLE; + + END CASE; + END IF; + END PROCESS; + + output_bits <= out_buf; + +END ARCHITECTURE rtl; diff --git a/src/viterbi_decoder_k7_simple.vhd.backup b/src/viterbi_decoder_k7_simple.vhd.backup new file mode 100644 index 0000000..7800283 --- /dev/null +++ b/src/viterbi_decoder_k7_simple.vhd.backup @@ -0,0 +1,288 @@ +------------------------------------------------------------------------------------------------------ +-- BRAM-Optimized Viterbi Decoder - SIMPLIFIED TRACEBACK (2 cycles per step) +------------------------------------------------------------------------------------------------------ +-- This version uses 2 clock cycles per traceback step for clarity and correctness: +-- Cycle 1: Fetch decision from BRAM +-- Cycle 2: Use decision, output bit, move to previous state +-- +-- This is slower but eliminates pipeline complexity bugs. +------------------------------------------------------------------------------------------------------ + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +ENTITY viterbi_decoder_k7_simple IS + GENERIC ( + PAYLOAD_BITS : NATURAL := 134*8; + ENCODED_BITS : NATURAL := 268*8; + TRACEBACK_DEPTH : NATURAL := 35 + ); + PORT ( + clk : IN std_logic; + aresetn : IN std_logic; + start : IN std_logic; + busy : OUT std_logic; + done : OUT std_logic; + input_bits_g1 : IN std_logic_vector(ENCODED_BITS-1 DOWNTO 0); + input_bits_g2 : IN std_logic_vector(ENCODED_BITS-1 DOWNTO 0); + output_bits : OUT std_logic_vector(PAYLOAD_BITS-1 DOWNTO 0) + ); +END ENTITY viterbi_decoder_k7_simple; + +ARCHITECTURE rtl OF viterbi_decoder_k7_simple IS + + + CONSTANT NUM_STATES : INTEGER := 64; + CONSTANT METRIC_WIDTH : INTEGER := 12; + CONSTANT INF_METRIC : INTEGER := 4095; + CONSTANT NUM_SYMBOLS : INTEGER := ENCODED_BITS/2; + + TYPE state_t IS (IDLE, INITIALIZE, ACS_COMPUTE, FIND_BEST, + TB_FETCH, TB_USE, COMPLETE); + SIGNAL state : state_t := IDLE; + + TYPE metric_array_t IS ARRAY(0 TO NUM_STATES-1) OF unsigned(METRIC_WIDTH-1 DOWNTO 0); + -- added initialization to try to get simulation to stop stalling on second frame + SIGNAL metrics_current : metric_array_t := (OTHERS => (OTHERS => '0')); + SIGNAL metrics_next : metric_array_t := (OTHERS => (OTHERS => '0')); + + ATTRIBUTE dont_touch : STRING; + --ATTRIBUTE dont_touch OF metrics_current : SIGNAL IS "true"; + --ATTRIBUTE dont_touch OF metrics_next : SIGNAL IS "true"; + + CONSTANT DECISION_DEPTH : INTEGER := NUM_SYMBOLS * NUM_STATES; + TYPE decision_mem_t IS ARRAY(0 TO DECISION_DEPTH-1) OF std_logic; + SIGNAL decision_mem : decision_mem_t; + + ATTRIBUTE dont_touch OF decision_mem : SIGNAL IS "true"; + + ATTRIBUTE ram_style : STRING; + ATTRIBUTE ram_style OF decision_mem : SIGNAL IS "block"; + + SIGNAL dec_wr_en : std_logic; + SIGNAL dec_wr_addr : INTEGER RANGE 0 TO DECISION_DEPTH-1; + SIGNAL dec_wr_data : std_logic; + SIGNAL dec_rd_addr : INTEGER RANGE 0 TO DECISION_DEPTH-1; + SIGNAL dec_rd_data : std_logic; + + SIGNAL time_step : INTEGER RANGE 0 TO NUM_SYMBOLS; + SIGNAL state_idx : INTEGER RANGE 0 TO NUM_STATES-1; + SIGNAL tb_time : INTEGER RANGE -1 TO NUM_SYMBOLS; + SIGNAL tb_state : INTEGER RANGE 0 TO NUM_STATES-1; + + SIGNAL out_buf : std_logic_vector(PAYLOAD_BITS-1 DOWNTO 0); + SIGNAL rx_symbol : std_logic_vector(1 DOWNTO 0); + + ATTRIBUTE dont_touch OF out_buf : SIGNAL IS "true"; + + FUNCTION compute_output(curr_state : INTEGER; input_bit : std_logic) + RETURN std_logic_vector IS + CONSTANT G1_POLY : std_logic_vector(6 DOWNTO 0) := "1111001"; + CONSTANT G2_POLY : std_logic_vector(6 DOWNTO 0) := "1011011"; + VARIABLE full_state : std_logic_vector(6 DOWNTO 0); + VARIABLE g1, g2 : std_logic; + BEGIN + full_state := input_bit & std_logic_vector(to_unsigned(curr_state, 6)); + + g1 := '0'; + FOR i IN 0 TO 6 LOOP + IF G1_POLY(i) = '1' THEN + g1 := g1 XOR full_state(6-i); + END IF; + END LOOP; + + g2 := '0'; + FOR i IN 0 TO 6 LOOP + IF G2_POLY(i) = '1' THEN + g2 := g2 XOR full_state(6-i); + END IF; + END LOOP; + + RETURN g1 & g2; + END FUNCTION; + + FUNCTION hamming_distance(a, b : std_logic_vector) RETURN INTEGER IS + VARIABLE dist : INTEGER := 0; + BEGIN + FOR i IN a'RANGE LOOP + IF a(i) /= b(i) THEN + dist := dist + 1; + END IF; + END LOOP; + RETURN dist; + END FUNCTION; + +BEGIN + + PROCESS(clk) + BEGIN + IF rising_edge(clk) THEN + IF dec_wr_en = '1' THEN + decision_mem(dec_wr_addr) <= dec_wr_data; + --decision_mem(dec_wr_addr / CHUNK_SIZE)(dec_wr_addr MOD CHUNK_SIZE) <= dec_wr_data; + END IF; + END IF; + END PROCESS; + + PROCESS(clk) + BEGIN + IF rising_edge(clk) THEN + dec_rd_data <= decision_mem(dec_rd_addr); + --dec_rd_data <= decision_mem(dec_rd_addr / CHUNK_SIZE)(dec_rd_addr MOD CHUNK_SIZE); + END IF; + END PROCESS; + + PROCESS(clk, aresetn) + VARIABLE prev_state_0, prev_state_1 : INTEGER RANGE 0 TO NUM_STATES-1; + VARIABLE input_bit : std_logic; + VARIABLE expected_0, expected_1 : std_logic_vector(1 DOWNTO 0); + VARIABLE metric_0, metric_1 : unsigned(METRIC_WIDTH-1 DOWNTO 0); + VARIABLE min_metric : unsigned(METRIC_WIDTH-1 DOWNTO 0); + VARIABLE best_state_var : INTEGER RANGE 0 TO NUM_STATES-1; + BEGIN + IF aresetn = '0' THEN + state <= IDLE; + busy <= '0'; + done <= '0'; + dec_wr_en <= '0'; + time_step <= 0; + state_idx <= 0; + metrics_next <= (OTHERS => (OTHERS => '0')); + + ELSIF rising_edge(clk) THEN + done <= '0'; + dec_wr_en <= '0'; + + CASE state IS + + WHEN IDLE => + busy <= '0'; + IF start = '1' THEN + state <= INITIALIZE; + busy <= '1'; + state_idx <= 0; + END IF; + + WHEN INITIALIZE => + IF state_idx < NUM_STATES THEN + IF state_idx = 0 THEN + metrics_current(state_idx) <= (OTHERS => '0'); + ELSE + metrics_current(state_idx) <= to_unsigned(INF_METRIC, METRIC_WIDTH); + END IF; + state_idx <= state_idx + 1; + ELSE + state <= ACS_COMPUTE; + state_idx <= 0; + time_step <= 0; + END IF; + + WHEN ACS_COMPUTE => + IF time_step < NUM_SYMBOLS THEN + IF state_idx = 0 THEN + rx_symbol <= input_bits_g1(time_step) & input_bits_g2(time_step); + END IF; + + IF state_idx < NUM_STATES THEN + prev_state_0 := state_idx / 2; + prev_state_1 := (state_idx / 2) + 32; + input_bit := std_logic(to_unsigned(state_idx MOD 2, 1)(0)); + + expected_0 := compute_output(prev_state_0, input_bit); + metric_0 := metrics_current(prev_state_0) + + to_unsigned(hamming_distance(rx_symbol, expected_0), METRIC_WIDTH); + + expected_1 := compute_output(prev_state_1, input_bit); + metric_1 := metrics_current(prev_state_1) + + to_unsigned(hamming_distance(rx_symbol, expected_1), METRIC_WIDTH); + + IF metric_0 <= metric_1 THEN + metrics_next(state_idx) <= metric_0; + dec_wr_data <= '0'; + ELSE + metrics_next(state_idx) <= metric_1; + dec_wr_data <= '1'; + END IF; + + dec_wr_addr <= time_step * NUM_STATES + state_idx; + dec_wr_en <= '1'; + state_idx <= state_idx + 1; + ELSE + metrics_current <= metrics_next; + state_idx <= 0; + time_step <= time_step + 1; + END IF; + ELSE + state <= FIND_BEST; + state_idx <= 0; + END IF; + + WHEN FIND_BEST => + IF state_idx = 0 THEN + min_metric := metrics_current(0); + best_state_var := 0; + state_idx <= 1; + ELSIF state_idx < NUM_STATES THEN + IF metrics_current(state_idx) < min_metric THEN + min_metric := metrics_current(state_idx); + best_state_var := state_idx; + END IF; + state_idx <= state_idx + 1; + ELSE + tb_state <= best_state_var; + tb_time <= NUM_SYMBOLS - 1; + dec_rd_addr <= (NUM_SYMBOLS-1) * NUM_STATES + best_state_var; + state <= TB_FETCH; + END IF; + + ------------------------------------------------------------------------------------ + -- SIMPLIFIED 2-CYCLE TRACEBACK + ------------------------------------------------------------------------------------ + WHEN TB_FETCH => + -- Cycle 1: Issue BRAM read for current (tb_time, tb_state) + -- Next cycle, dec_rd_data will be valid + state <= TB_USE; + + WHEN TB_USE => + -- Cycle 2: Use the decision that was fetched + IF tb_time >= 0 THEN + -- Output decoded bit + out_buf(tb_time) <= std_logic(to_unsigned(tb_state MOD 2, 1)(0)); + + -- Move to previous state based on decision + IF dec_rd_data = '0' THEN + tb_state <= tb_state / 2; + ELSE + tb_state <= (tb_state / 2) + 32; + END IF; + + tb_time <= tb_time - 1; + + -- Fetch next decision (if not done) + IF tb_time > 0 THEN + IF dec_rd_data = '0' THEN + dec_rd_addr <= (tb_time-1) * NUM_STATES + (tb_state / 2); + ELSE + dec_rd_addr <= (tb_time-1) * NUM_STATES + ((tb_state / 2) + 32); + END IF; + state <= TB_FETCH; + ELSE + state <= COMPLETE; + END IF; + ELSE + state <= COMPLETE; + END IF; + + WHEN COMPLETE => + done <= '1'; + busy <= '0'; + state <= IDLE; + + END CASE; + END IF; + END PROCESS; + + output_bits <= out_buf; + +END ARCHITECTURE rtl; diff --git a/src/viterbi_decoder_k7_simple.vhd.shift_register b/src/viterbi_decoder_k7_simple.vhd.shift_register new file mode 100644 index 0000000..d70da79 --- /dev/null +++ b/src/viterbi_decoder_k7_simple.vhd.shift_register @@ -0,0 +1,297 @@ +------------------------------------------------------------------------------------------------------ +-- BRAM-Optimized Viterbi Decoder - SHIFT REGISTER INPUTS +------------------------------------------------------------------------------------------------------ +-- This version uses shift registers for the input data to avoid massive muxes. +-- Instead of input_bits_g1(time_step) creating a 1072:1 mux, we: +-- 1. Load the parallel input into a shift register +-- 2. Shift out one bit per time step +-- +-- This saves ~2000 LUTs (2 x 1072:1 mux elimination) +-- +-- Interface is IDENTICAL to original - parallel load happens internally. +------------------------------------------------------------------------------------------------------ + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +ENTITY viterbi_decoder_k7_simple IS + GENERIC ( + PAYLOAD_BITS : NATURAL := 134*8; + ENCODED_BITS : NATURAL := 268*8; + TRACEBACK_DEPTH : NATURAL := 35 + ); + PORT ( + clk : IN std_logic; + aresetn : IN std_logic; + start : IN std_logic; + busy : OUT std_logic; + done : OUT std_logic; + input_bits_g1 : IN std_logic_vector(ENCODED_BITS-1 DOWNTO 0); + input_bits_g2 : IN std_logic_vector(ENCODED_BITS-1 DOWNTO 0); + output_bits : OUT std_logic_vector(PAYLOAD_BITS-1 DOWNTO 0) + ); +END ENTITY viterbi_decoder_k7_simple; + +ARCHITECTURE rtl OF viterbi_decoder_k7_simple IS + + CONSTANT NUM_STATES : INTEGER := 64; + CONSTANT METRIC_WIDTH : INTEGER := 12; + CONSTANT INF_METRIC : INTEGER := 4095; + CONSTANT NUM_SYMBOLS : INTEGER := ENCODED_BITS/2; -- 1072 + + TYPE state_t IS (IDLE, INITIALIZE, ACS_COMPUTE, FIND_BEST, + TB_FETCH, TB_USE, COMPLETE); + SIGNAL state : state_t := IDLE; + + TYPE metric_array_t IS ARRAY(0 TO NUM_STATES-1) OF unsigned(METRIC_WIDTH-1 DOWNTO 0); + SIGNAL metrics_current : metric_array_t := (OTHERS => (OTHERS => '0')); + SIGNAL metrics_next : metric_array_t := (OTHERS => (OTHERS => '0')); + + -- Decision memory in BRAM + CONSTANT DECISION_DEPTH : INTEGER := NUM_SYMBOLS * NUM_STATES; + TYPE decision_mem_t IS ARRAY(0 TO DECISION_DEPTH-1) OF std_logic; + SIGNAL decision_mem : decision_mem_t; + + ATTRIBUTE ram_style : STRING; + ATTRIBUTE ram_style OF decision_mem : SIGNAL IS "block"; + + SIGNAL dec_wr_en : std_logic; + SIGNAL dec_wr_addr : INTEGER RANGE 0 TO DECISION_DEPTH-1; + SIGNAL dec_wr_data : std_logic; + SIGNAL dec_rd_addr : INTEGER RANGE 0 TO DECISION_DEPTH-1; + SIGNAL dec_rd_data : std_logic; + + SIGNAL time_step : INTEGER RANGE 0 TO NUM_SYMBOLS; + SIGNAL state_idx : INTEGER RANGE 0 TO NUM_STATES-1; + SIGNAL tb_time : INTEGER RANGE -1 TO NUM_SYMBOLS; + SIGNAL tb_state : INTEGER RANGE 0 TO NUM_STATES-1; + + SIGNAL out_buf : std_logic_vector(PAYLOAD_BITS-1 DOWNTO 0); + SIGNAL rx_symbol : std_logic_vector(1 DOWNTO 0); + + -- SHIFT REGISTERS for input data (replaces massive mux) + -- These shift left, MSB contains current symbol + SIGNAL g1_sr : std_logic_vector(NUM_SYMBOLS-1 DOWNTO 0); + SIGNAL g2_sr : std_logic_vector(NUM_SYMBOLS-1 DOWNTO 0); + + FUNCTION compute_output(curr_state : INTEGER; input_bit : std_logic) + RETURN std_logic_vector IS + CONSTANT G1_POLY : std_logic_vector(6 DOWNTO 0) := "1111001"; + CONSTANT G2_POLY : std_logic_vector(6 DOWNTO 0) := "1011011"; + VARIABLE full_state : std_logic_vector(6 DOWNTO 0); + VARIABLE g1, g2 : std_logic; + BEGIN + full_state := input_bit & std_logic_vector(to_unsigned(curr_state, 6)); + + g1 := '0'; + FOR i IN 0 TO 6 LOOP + IF G1_POLY(i) = '1' THEN + g1 := g1 XOR full_state(6-i); + END IF; + END LOOP; + + g2 := '0'; + FOR i IN 0 TO 6 LOOP + IF G2_POLY(i) = '1' THEN + g2 := g2 XOR full_state(6-i); + END IF; + END LOOP; + + RETURN g1 & g2; + END FUNCTION; + + FUNCTION hamming_distance(a, b : std_logic_vector) RETURN INTEGER IS + VARIABLE dist : INTEGER := 0; + BEGIN + FOR i IN a'RANGE LOOP + IF a(i) /= b(i) THEN + dist := dist + 1; + END IF; + END LOOP; + RETURN dist; + END FUNCTION; + +BEGIN + + -- BRAM write process + PROCESS(clk) + BEGIN + IF rising_edge(clk) THEN + IF dec_wr_en = '1' THEN + decision_mem(dec_wr_addr) <= dec_wr_data; + END IF; + END IF; + END PROCESS; + + -- BRAM read process + PROCESS(clk) + BEGIN + IF rising_edge(clk) THEN + dec_rd_data <= decision_mem(dec_rd_addr); + END IF; + END PROCESS; + + -- Main FSM + PROCESS(clk, aresetn) + VARIABLE prev_state_0, prev_state_1 : INTEGER RANGE 0 TO NUM_STATES-1; + VARIABLE input_bit : std_logic; + VARIABLE expected_0, expected_1 : std_logic_vector(1 DOWNTO 0); + VARIABLE metric_0, metric_1 : unsigned(METRIC_WIDTH-1 DOWNTO 0); + VARIABLE min_metric : unsigned(METRIC_WIDTH-1 DOWNTO 0); + VARIABLE best_state_var : INTEGER RANGE 0 TO NUM_STATES-1; + BEGIN + IF aresetn = '0' THEN + state <= IDLE; + busy <= '0'; + done <= '0'; + dec_wr_en <= '0'; + time_step <= 0; + state_idx <= 0; + metrics_next <= (OTHERS => (OTHERS => '0')); + g1_sr <= (OTHERS => '0'); + g2_sr <= (OTHERS => '0'); + + ELSIF rising_edge(clk) THEN + done <= '0'; + dec_wr_en <= '0'; + + CASE state IS + + WHEN IDLE => + busy <= '0'; + IF start = '1' THEN + state <= INITIALIZE; + busy <= '1'; + state_idx <= 0; + -- PARALLEL LOAD shift registers from input vectors + -- Load bits 0..1071 directly - simple slice, no mux needed + -- We'll read from bit 0 and shift right each time step + g1_sr <= input_bits_g1(NUM_SYMBOLS-1 DOWNTO 0); + g2_sr <= input_bits_g2(NUM_SYMBOLS-1 DOWNTO 0); + END IF; + + WHEN INITIALIZE => + IF state_idx < NUM_STATES THEN + IF state_idx = 0 THEN + metrics_current(state_idx) <= (OTHERS => '0'); + ELSE + metrics_current(state_idx) <= to_unsigned(INF_METRIC, METRIC_WIDTH); + END IF; + state_idx <= state_idx + 1; + ELSE + state <= ACS_COMPUTE; + state_idx <= 0; + time_step <= 0; + END IF; + + WHEN ACS_COMPUTE => + IF time_step < NUM_SYMBOLS THEN + IF state_idx = 0 THEN + -- Get current symbol from LSB of shift registers + rx_symbol <= g1_sr(0) & g2_sr(0); + END IF; + + IF state_idx < NUM_STATES THEN + prev_state_0 := state_idx / 2; + prev_state_1 := (state_idx / 2) + 32; + input_bit := std_logic(to_unsigned(state_idx MOD 2, 1)(0)); + + expected_0 := compute_output(prev_state_0, input_bit); + metric_0 := metrics_current(prev_state_0) + + to_unsigned(hamming_distance(rx_symbol, expected_0), METRIC_WIDTH); + + expected_1 := compute_output(prev_state_1, input_bit); + metric_1 := metrics_current(prev_state_1) + + to_unsigned(hamming_distance(rx_symbol, expected_1), METRIC_WIDTH); + + IF metric_0 <= metric_1 THEN + metrics_next(state_idx) <= metric_0; + dec_wr_data <= '0'; + ELSE + metrics_next(state_idx) <= metric_1; + dec_wr_data <= '1'; + END IF; + + dec_wr_addr <= time_step * NUM_STATES + state_idx; + dec_wr_en <= '1'; + state_idx <= state_idx + 1; + ELSE + -- Done with all states for this time step + metrics_current <= metrics_next; + state_idx <= 0; + time_step <= time_step + 1; + -- SHIFT RIGHT: next symbol moves to bit 0 + g1_sr <= '0' & g1_sr(NUM_SYMBOLS-1 DOWNTO 1); + g2_sr <= '0' & g2_sr(NUM_SYMBOLS-1 DOWNTO 1); + END IF; + ELSE + state <= FIND_BEST; + state_idx <= 0; + END IF; + + WHEN FIND_BEST => + IF state_idx = 0 THEN + min_metric := metrics_current(0); + best_state_var := 0; + state_idx <= 1; + ELSIF state_idx < NUM_STATES THEN + IF metrics_current(state_idx) < min_metric THEN + min_metric := metrics_current(state_idx); + best_state_var := state_idx; + END IF; + state_idx <= state_idx + 1; + ELSE + tb_state <= best_state_var; + tb_time <= NUM_SYMBOLS - 1; + dec_rd_addr <= (NUM_SYMBOLS-1) * NUM_STATES + best_state_var; + state <= TB_FETCH; + END IF; + + -- SIMPLIFIED 2-CYCLE TRACEBACK + WHEN TB_FETCH => + -- Cycle 1: Issue BRAM read for current (tb_time, tb_state) + state <= TB_USE; + + WHEN TB_USE => + -- Cycle 2: Use the decision that was fetched + IF tb_time >= 0 THEN + -- Output decoded bit + out_buf(tb_time) <= std_logic(to_unsigned(tb_state MOD 2, 1)(0)); + + -- Move to previous state based on decision + IF dec_rd_data = '0' THEN + tb_state <= tb_state / 2; + ELSE + tb_state <= (tb_state / 2) + 32; + END IF; + + tb_time <= tb_time - 1; + + -- Fetch next decision (if not done) + IF tb_time > 0 THEN + IF dec_rd_data = '0' THEN + dec_rd_addr <= (tb_time-1) * NUM_STATES + (tb_state / 2); + ELSE + dec_rd_addr <= (tb_time-1) * NUM_STATES + ((tb_state / 2) + 32); + END IF; + state <= TB_FETCH; + ELSE + state <= COMPLETE; + END IF; + ELSE + state <= COMPLETE; + END IF; + + WHEN COMPLETE => + done <= '1'; + busy <= '0'; + state <= IDLE; + + END CASE; + END IF; + END PROCESS; + + output_bits <= out_buf; + +END ARCHITECTURE rtl; diff --git a/src/viterbi_decoder_k7_soft.vhd b/src/viterbi_decoder_k7_soft.vhd new file mode 100644 index 0000000..234d016 --- /dev/null +++ b/src/viterbi_decoder_k7_soft.vhd @@ -0,0 +1,378 @@ +------------------------------------------------------------------------------------------------------ +-- Soft Decision Viterbi Decoder - K=7, Rate 1/2 +------------------------------------------------------------------------------------------------------ +-- Accepts quantized soft decisions instead of hard bits for ~2 dB coding gain. +-- +-- SOFT_WIDTH generic controls quantization: +-- 3-bit: 8 levels, ~1.5-2 dB gain, minimal resources +-- 4-bit: 16 levels, ~2 dB gain +-- 8-bit: 256 levels, ~2.5 dB gain (full soft) +-- +-- Soft value convention (signed, two's complement interpretation): +-- Most negative = highest confidence '0' +-- Most positive = highest confidence '1' +-- Zero = erasure/no information +-- +-- For 3-bit unsigned (current default): +-- 0 = strong '0', 7 = strong '1', 3-4 = uncertain +------------------------------------------------------------------------------------------------------ + +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; + +ENTITY viterbi_decoder_k7_soft IS + GENERIC ( + PAYLOAD_BITS : NATURAL := 134*8; -- 1072 decoded bits + ENCODED_BITS : NATURAL := 268*8; -- 2144 encoded bits + TRACEBACK_DEPTH : NATURAL := 35; + SOFT_WIDTH : NATURAL := 3 -- Bits per soft symbol (3, 4, or 8) + ); + PORT ( + clk : IN std_logic; + aresetn : IN std_logic; + start : IN std_logic; + busy : OUT std_logic; + done : OUT std_logic; + + -- Soft decision inputs (SOFT_WIDTH bits per encoded bit) + -- G1 and G2 streams, each NUM_SYMBOLS deep + input_soft_g1 : IN std_logic_vector(ENCODED_BITS/2 * SOFT_WIDTH - 1 DOWNTO 0); + input_soft_g2 : IN std_logic_vector(ENCODED_BITS/2 * SOFT_WIDTH - 1 DOWNTO 0); + + -- Decoded output + output_bits : OUT std_logic_vector(PAYLOAD_BITS-1 DOWNTO 0); + + -- Debug: final path metric (lower = more confident decode) + debug_path_metric : OUT std_logic_vector(15 DOWNTO 0) + ); +END ENTITY viterbi_decoder_k7_soft; + +ARCHITECTURE rtl OF viterbi_decoder_k7_soft IS + + CONSTANT NUM_STATES : INTEGER := 64; -- 2^(K-1) for K=7 + CONSTANT NUM_SYMBOLS : INTEGER := ENCODED_BITS/2; -- 1072 symbol pairs + + -- Metric width needs to accommodate accumulated soft metrics + -- Worst case per symbol: 2 * (2^SOFT_WIDTH - 1) = max branch metric + -- Over 1072 symbols, need enough bits to not overflow + -- For SOFT_WIDTH=3: max branch = 14, total max = 14*1072 = 15008, needs 14 bits + -- For SOFT_WIDTH=8: max branch = 510, total max = 546720, needs 20 bits + CONSTANT METRIC_WIDTH : INTEGER := SOFT_WIDTH + 12; -- Scales with soft width + CONSTANT INF_METRIC : INTEGER := 2**(METRIC_WIDTH-1) - 1; + + -- Max soft value for this width + CONSTANT SOFT_MAX : INTEGER := 2**SOFT_WIDTH - 1; + + TYPE state_t IS (IDLE, INITIALIZE, ACS_COMPUTE, FIND_BEST, + TB_FETCH, TB_USE, COMPLETE); + SIGNAL state : state_t := IDLE; + + TYPE metric_array_t IS ARRAY(0 TO NUM_STATES-1) OF unsigned(METRIC_WIDTH-1 DOWNTO 0); + SIGNAL metrics_current : metric_array_t := (OTHERS => (OTHERS => '0')); + SIGNAL metrics_next : metric_array_t := (OTHERS => (OTHERS => '0')); + + -- Decision memory in BRAM + CONSTANT DECISION_DEPTH : INTEGER := NUM_SYMBOLS * NUM_STATES; + TYPE decision_mem_t IS ARRAY(0 TO DECISION_DEPTH-1) OF std_logic; + SIGNAL decision_mem : decision_mem_t; + + SIGNAL dec_wr_en : std_logic; + SIGNAL dec_wr_addr : INTEGER RANGE 0 TO DECISION_DEPTH-1; + SIGNAL dec_wr_data : std_logic; + SIGNAL dec_rd_addr : INTEGER RANGE 0 TO DECISION_DEPTH-1; + SIGNAL dec_rd_data : std_logic; + + SIGNAL time_step : INTEGER RANGE 0 TO NUM_SYMBOLS; + SIGNAL state_idx : INTEGER RANGE 0 TO NUM_STATES-1; + SIGNAL tb_time : INTEGER RANGE -1 TO NUM_SYMBOLS; + SIGNAL tb_state : INTEGER RANGE 0 TO NUM_STATES-1; + SIGNAL best_metric : unsigned(METRIC_WIDTH-1 DOWNTO 0); + + SIGNAL out_buf : std_logic_vector(PAYLOAD_BITS-1 DOWNTO 0); + + -- Current soft symbol pair + SIGNAL soft_g1_current : unsigned(SOFT_WIDTH-1 DOWNTO 0); + SIGNAL soft_g2_current : unsigned(SOFT_WIDTH-1 DOWNTO 0); + + -- Shift registers for soft input data + SIGNAL g1_soft_sr : std_logic_vector(NUM_SYMBOLS * SOFT_WIDTH - 1 DOWNTO 0); + SIGNAL g2_soft_sr : std_logic_vector(NUM_SYMBOLS * SOFT_WIDTH - 1 DOWNTO 0); + + ATTRIBUTE ram_style : STRING; + ATTRIBUTE ram_style OF decision_mem : SIGNAL IS "block"; + ATTRIBUTE ram_style OF g1_soft_sr : SIGNAL IS "block"; + ATTRIBUTE ram_style OF g2_soft_sr : SIGNAL IS "block"; + ATTRIBUTE ram_style OF out_buf : SIGNAL IS "block"; + + ATTRIBUTE dont_touch : STRING; + ATTRIBUTE dont_touch OF state : SIGNAL IS "true"; + ATTRIBUTE dont_touch OF metrics_current : SIGNAL IS "true"; + ATTRIBUTE dont_touch OF metrics_next : SIGNAL IS "true"; + + ---------------------------------------------------------------------------- + -- Compute expected encoder output for given state and input bit + -- Returns (g1, g2) as 2-bit vector + ---------------------------------------------------------------------------- + FUNCTION compute_output(curr_state : INTEGER; input_bit : std_logic) + RETURN std_logic_vector IS + CONSTANT G1_POLY : std_logic_vector(6 DOWNTO 0) := "1111001"; -- 171 octal + CONSTANT G2_POLY : std_logic_vector(6 DOWNTO 0) := "1011011"; -- 133 octal + VARIABLE full_state : std_logic_vector(6 DOWNTO 0); + VARIABLE g1, g2 : std_logic; + BEGIN + full_state := input_bit & std_logic_vector(to_unsigned(curr_state, 6)); + + g1 := '0'; + FOR i IN 0 TO 6 LOOP + IF G1_POLY(i) = '1' THEN + g1 := g1 XOR full_state(6-i); + END IF; + END LOOP; + + g2 := '0'; + FOR i IN 0 TO 6 LOOP + IF G2_POLY(i) = '1' THEN + g2 := g2 XOR full_state(6-i); + END IF; + END LOOP; + + RETURN g1 & g2; + END FUNCTION; + + ---------------------------------------------------------------------------- + -- Soft Branch Metric Calculation + ---------------------------------------------------------------------------- + -- Computes distance between received soft values and expected bits + -- + -- Convention: + -- soft = 0 means strong '0' + -- soft = SOFT_MAX means strong '1' + -- + -- If expected = '0': metric = soft_value (low soft = good match) + -- If expected = '1': metric = SOFT_MAX - soft_value (high soft = good match) + -- + -- Total branch metric = metric_g1 + metric_g2 + ---------------------------------------------------------------------------- + FUNCTION soft_branch_metric( + soft_g1 : unsigned; + soft_g2 : unsigned; + expected : std_logic_vector(1 DOWNTO 0) -- g1 & g2 + ) RETURN unsigned IS + VARIABLE metric_g1 : unsigned(SOFT_WIDTH DOWNTO 0); + VARIABLE metric_g2 : unsigned(SOFT_WIDTH DOWNTO 0); + VARIABLE total : unsigned(SOFT_WIDTH+1 DOWNTO 0); + BEGIN + -- G1 metric + IF expected(1) = '0' THEN + -- Expected '0': low soft value is good + metric_g1 := resize(soft_g1, SOFT_WIDTH+1); + ELSE + -- Expected '1': high soft value is good, so metric = MAX - soft + metric_g1 := to_unsigned(SOFT_MAX, SOFT_WIDTH+1) - resize(soft_g1, SOFT_WIDTH+1); + END IF; + + -- G2 metric + IF expected(0) = '0' THEN + metric_g2 := resize(soft_g2, SOFT_WIDTH+1); + ELSE + metric_g2 := to_unsigned(SOFT_MAX, SOFT_WIDTH+1) - resize(soft_g2, SOFT_WIDTH+1); + END IF; + + -- Total branch metric + total := resize(metric_g1, SOFT_WIDTH+2) + resize(metric_g2, SOFT_WIDTH+2); + + RETURN total; + END FUNCTION; + +BEGIN + + -- BRAM write process + PROCESS(clk) + BEGIN + IF rising_edge(clk) THEN + IF dec_wr_en = '1' THEN + decision_mem(dec_wr_addr) <= dec_wr_data; + END IF; + END IF; + END PROCESS; + + -- BRAM read process + PROCESS(clk) + BEGIN + IF rising_edge(clk) THEN + dec_rd_data <= decision_mem(dec_rd_addr); + END IF; + END PROCESS; + + -- Extract current soft symbols from shift register LSBs + soft_g1_current <= unsigned(g1_soft_sr(SOFT_WIDTH-1 DOWNTO 0)); + soft_g2_current <= unsigned(g2_soft_sr(SOFT_WIDTH-1 DOWNTO 0)); + + -- Main FSM + PROCESS(clk, aresetn) + VARIABLE prev_state_0, prev_state_1 : INTEGER RANGE 0 TO NUM_STATES-1; + VARIABLE input_bit : std_logic; + VARIABLE expected_0, expected_1 : std_logic_vector(1 DOWNTO 0); + VARIABLE branch_0, branch_1 : unsigned(SOFT_WIDTH+1 DOWNTO 0); + VARIABLE metric_0, metric_1 : unsigned(METRIC_WIDTH-1 DOWNTO 0); + VARIABLE min_metric : unsigned(METRIC_WIDTH-1 DOWNTO 0); + VARIABLE best_state_var : INTEGER RANGE 0 TO NUM_STATES-1; + BEGIN + IF aresetn = '0' THEN + state <= IDLE; + busy <= '0'; + done <= '0'; + dec_wr_en <= '0'; + time_step <= 0; + state_idx <= 0; + metrics_next <= (OTHERS => (OTHERS => '0')); + g1_soft_sr <= (OTHERS => '0'); + g2_soft_sr <= (OTHERS => '0'); + best_metric <= (OTHERS => '1'); + + ELSIF rising_edge(clk) THEN + done <= '0'; + dec_wr_en <= '0'; + + CASE state IS + + WHEN IDLE => + busy <= '0'; + IF start = '1' THEN + state <= INITIALIZE; + busy <= '1'; + state_idx <= 0; + -- Parallel load shift registers from input vectors + g1_soft_sr <= input_soft_g1; + g2_soft_sr <= input_soft_g2; + END IF; + + WHEN INITIALIZE => + IF state_idx < NUM_STATES THEN + IF state_idx = 0 THEN + metrics_current(state_idx) <= (OTHERS => '0'); + ELSE + metrics_current(state_idx) <= to_unsigned(INF_METRIC, METRIC_WIDTH); + END IF; + state_idx <= state_idx + 1; + ELSE + state <= ACS_COMPUTE; + state_idx <= 0; + time_step <= 0; + END IF; + + WHEN ACS_COMPUTE => + IF time_step < NUM_SYMBOLS THEN + IF state_idx < NUM_STATES THEN + -- Butterfly computation + prev_state_0 := state_idx / 2; + prev_state_1 := (state_idx / 2) + 32; + input_bit := std_logic(to_unsigned(state_idx MOD 2, 1)(0)); + + -- Path from prev_state_0 + expected_0 := compute_output(prev_state_0, input_bit); + branch_0 := soft_branch_metric(soft_g1_current, soft_g2_current, expected_0); + metric_0 := metrics_current(prev_state_0) + + resize(branch_0, METRIC_WIDTH); + + -- Path from prev_state_1 + expected_1 := compute_output(prev_state_1, input_bit); + branch_1 := soft_branch_metric(soft_g1_current, soft_g2_current, expected_1); + metric_1 := metrics_current(prev_state_1) + + resize(branch_1, METRIC_WIDTH); + + -- Select survivor + IF metric_0 <= metric_1 THEN + metrics_next(state_idx) <= metric_0; + dec_wr_data <= '0'; + ELSE + metrics_next(state_idx) <= metric_1; + dec_wr_data <= '1'; + END IF; + + dec_wr_addr <= time_step * NUM_STATES + state_idx; + dec_wr_en <= '1'; + state_idx <= state_idx + 1; + ELSE + -- Done with all states for this time step + metrics_current <= metrics_next; + state_idx <= 0; + time_step <= time_step + 1; + -- Shift right: move to next symbol pair + g1_soft_sr <= (SOFT_WIDTH-1 DOWNTO 0 => '0') & + g1_soft_sr(NUM_SYMBOLS*SOFT_WIDTH-1 DOWNTO SOFT_WIDTH); + g2_soft_sr <= (SOFT_WIDTH-1 DOWNTO 0 => '0') & + g2_soft_sr(NUM_SYMBOLS*SOFT_WIDTH-1 DOWNTO SOFT_WIDTH); + END IF; + ELSE + state <= FIND_BEST; + state_idx <= 0; + END IF; + + WHEN FIND_BEST => + IF state_idx = 0 THEN + min_metric := metrics_current(0); + best_state_var := 0; + state_idx <= 1; + ELSIF state_idx < NUM_STATES THEN + IF metrics_current(state_idx) < min_metric THEN + min_metric := metrics_current(state_idx); + best_state_var := state_idx; + END IF; + state_idx <= state_idx + 1; + ELSE + tb_state <= best_state_var; + tb_time <= NUM_SYMBOLS - 1; + best_metric <= min_metric; + dec_rd_addr <= (NUM_SYMBOLS-1) * NUM_STATES + best_state_var; + state <= TB_FETCH; + END IF; + + WHEN TB_FETCH => + -- Cycle 1: Issue BRAM read + state <= TB_USE; + + WHEN TB_USE => + -- Cycle 2: Use the fetched decision + IF tb_time >= 0 THEN + -- Output decoded bit + out_buf(tb_time) <= std_logic(to_unsigned(tb_state MOD 2, 1)(0)); + + -- Move to previous state based on decision + IF dec_rd_data = '0' THEN + tb_state <= tb_state / 2; + ELSE + tb_state <= (tb_state / 2) + 32; + END IF; + + tb_time <= tb_time - 1; + + -- Fetch next decision (if not done) + IF tb_time > 0 THEN + IF dec_rd_data = '0' THEN + dec_rd_addr <= (tb_time-1) * NUM_STATES + (tb_state / 2); + ELSE + dec_rd_addr <= (tb_time-1) * NUM_STATES + ((tb_state / 2) + 32); + END IF; + state <= TB_FETCH; + ELSE + state <= COMPLETE; + END IF; + ELSE + state <= COMPLETE; + END IF; + + WHEN COMPLETE => + done <= '1'; + busy <= '0'; + state <= IDLE; + + END CASE; + END IF; + END PROCESS; + + output_bits <= out_buf; + debug_path_metric <= std_logic_vector(resize(best_metric, 16)); + +END ARCHITECTURE rtl; diff --git a/vivado_pid1622766.debug b/vivado_pid1622766.debug new file mode 100644 index 0000000..3c0383f --- /dev/null +++ b/vivado_pid1622766.debug @@ -0,0 +1,89 @@ +#-------------------------------------------------------------------------- +# Xilinx Vivado v2022.2 (64-bit) +# SW Build: 3671981 on Fri Oct 14 04:59:54 MDT 2022 +# IP Build: 3669848 on Fri Oct 14 08:30:02 MDT 2022 +# Current time: Sun Nov 23 13:55:44 PST 2025 +# Process ID (PID): 1622766 +# User: abraxas3d +# OS: Ubuntu +# Project: msk_axistream_debug_msb +# Part: xc7z010clg400-1 +# +# This file is an indication that an internal application error occurred. +# This information is useful for debugging. Please open a case with Xilinx. +# Technical Support with this file and a testcase attached. +#-------------------------------------------------------------------------- +Sun Nov 23 13:55:44 PST 2025 +ui.utils.h: ui.frmwork.cmd.CommandFailedException: Unknown exception occurred ui.frmwork.cmd.CommandFailedException: Unknown exception occurred + at ui.views.simulator.executive.simulationi.SimulationExecutive_getCallStacksData(Native Method) + at ui.views.Q.c.a.jTw(SourceFile:532) + at ui.views.Q.a.o$c.reset(SourceFile:395) + at ui.views.Q.a.o$b.reset(SourceFile:274) + at ui.views.Q.a.o.reset(SourceFile:67) + at ui.views.Q.a.p.reset(SourceFile:124) + at ui.views.Q.a.p.handleTclEvent(SourceFile:114) + at ui.frmwork.a.m.c(SourceFile:42) + at ui.frmwork.D.i(SourceFile:216) + at ui.frmwork.D.fireTclEvent(SourceFile:139) + at ui.views.simulator.executive.simulationi.SimulationExecutive_setTreeWindowTreeHeight(Native Method) + at ui.views.Q.c.a.e(SourceFile:1221) + at ui.views.Q.i.c.jUj(SourceFile:122) + at ui.views.Q.i.f.componentResized(SourceFile:145) + at java.desktop/java.awt.Component.processComponentEvent(Component.java:6461) + at java.desktop/java.awt.Component.processEvent(Component.java:6415) + at java.desktop/java.awt.Container.processEvent(Container.java:2263) + at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5011) + at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2321) + at java.desktop/java.awt.Component.dispatchEvent(Component.java:4843) + at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:772) + at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721) + at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715) + at java.base/java.security.AccessController.doPrivileged(Native Method) + at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85) + at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95) + at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745) + at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:743) + at java.base/java.security.AccessController.doPrivileged(Native Method) + at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85) + at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742) + at ui.frmwork.a.d.dispatchEvent(SourceFile:92) + at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203) + at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124) + at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113) + at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109) + at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) + at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90) + + at ui.utils.d.c.p(SourceFile:984) + at ui.utils.d.c.i(SourceFile:282) + at ui.utils.q.i(SourceFile:267) + at ui.frmwork.D.fireTclEvent(SourceFile:143) + at ui.views.simulator.executive.simulationi.SimulationExecutive_setTreeWindowTreeHeight(Native Method) + at ui.views.Q.c.a.e(SourceFile:1221) + at ui.views.Q.i.c.jUj(SourceFile:122) + at ui.views.Q.i.f.componentResized(SourceFile:145) + at java.desktop/java.awt.Component.processComponentEvent(Component.java:6461) + at java.desktop/java.awt.Component.processEvent(Component.java:6415) + at java.desktop/java.awt.Container.processEvent(Container.java:2263) + at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5011) + at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2321) + at java.desktop/java.awt.Component.dispatchEvent(Component.java:4843) + at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:772) + at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721) + at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715) + at java.base/java.security.AccessController.doPrivileged(Native Method) + at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85) + at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95) + at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745) + at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:743) + at java.base/java.security.AccessController.doPrivileged(Native Method) + at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85) + at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742) + at ui.frmwork.a.d.dispatchEvent(SourceFile:92) + at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203) + at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124) + at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113) + at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109) + at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) + at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90) + diff --git a/vivado_pid1622766.str b/vivado_pid1622766.str new file mode 100644 index 0000000..8550fa3 --- /dev/null +++ b/vivado_pid1622766.str @@ -0,0 +1,4189 @@ +/* + +Xilinx Vivado v2022.2 (64-bit) [Major: 2022, Minor: 2] +SW Build: 3671981 on Fri Oct 14 04:59:54 MDT 2022 +IP Build: 3669848 on Fri Oct 14 08:30:02 MDT 2022 + +Process ID (PID): 1622766 +License: Customer +Mode: GUI Mode + +Current time: Sun Nov 23 13:40:26 PST 2025 +Time zone: Pacific Standard Time (America/Los_Angeles) + +OS: Ubuntu +OS Version: 6.8.0-87-generic +OS Architecture: amd64 +Available processors (cores): 60 + +Display: 16 +Screen size: 1920x1200 +Screen resolution (DPI): 100 +Available screens: 1 +Default font: family=Dialog,name=Dialog,style=plain,size=12 +Scale size: 12 + +Java version: 11.0.11 64-bit +Java home: /opt/Xilinx/Vivado/2022.2/tps/lnx64/jre11.0.11_9 +Java executable: /opt/Xilinx/Vivado/2022.2/tps/lnx64/jre11.0.11_9/bin/java +Java arguments: [-Dsun.java2d.pmoffscreen=false, -Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2, -Dsun.java2d.xrender=false, -Djdk.gtk.version=2, -Dsun.java2d.uiScale.enabled=false, -Xverify:none, -Dswing.aatext=true, -XX:-UsePerfData, -Djdk.map.althashing.threshold=512, -XX:StringTableSize=4072, --add-opens=java.desktop/com.sun.awt=ALL-UNNAMED, --add-opens=java.desktop/javax.swing.plaf.synth=ALL-UNNAMED, --add-opens=java.base/java.nio=ALL-UNNAMED, --add-opens=java.desktop/sun.swing=ALL-UNNAMED, --add-opens=java.desktop/javax.swing=ALL-UNNAMED, --add-opens=java.desktop/javax.swing.tree=ALL-UNNAMED, --add-opens=java.desktop/javax.swing.plaf.basic=ALL-UNNAMED, --add-opens=java.desktop/javax.swing.plaf.synth=ALL-UNNAMED, --add-opens=java.desktop/javax.swing.plaf.basic=ALL-UNNAMED, --add-opens=java.desktop/javax.swing=ALL-UNNAMED, --add-opens=java.desktop/javax.swing.tree=ALL-UNNAMED, --add-opens=java.desktop/java.awt.event=ALL-UNNAMED, --add-exports=java.desktop/javax.swing.plaf.synth=ALL-UNNAMED, --add-exports=java.base/java.nio=ALL-UNNAMED, --add-exports=java.desktop/sun.swing=ALL-UNNAMED, --add-exports=java.desktop/javax.swing=ALL-UNNAMED, --add-exports=java.desktop/javax.swing.tree=ALL-UNNAMED, --add-exports=java.desktop/javax.swing.plaf.basic=ALL-UNNAMED, --add-exports=java.desktop/sun.swing=ALL-UNNAMED, --add-exports=java.desktop/sun.swing.table=ALL-UNNAMED, --add-exports=java.desktop/sun.swing.plaf.synth=ALL-UNNAMED, --add-exports=java.desktop/sun.awt.shell=ALL-UNNAMED, --add-exports=java.base/sun.security.action=ALL-UNNAMED, --add-exports=java.desktop/sun.font=ALL-UNNAMED, --add-opens=java.desktop/sun.awt.X11=ALL-UNNAMED, -XX:NewSize=60m, -XX:MaxNewSize=60m, -Xms256m, -Xmx3072m, -Xss5m, -Xrs] +Java initial memory (-Xms): 256 MB +Java maximum memory (-Xmx): 3 GB + + +User name: abraxas3d +User home directory: /home/abraxas3d +User working directory: /home/abraxas3d/pluto_msk +User country: US +User language: en +User locale: en_US + +RDI_BASEROOT: /opt/Xilinx/Vivado +HDI_APPROOT: /opt/Xilinx/Vivado/2022.2 +RDI_DATADIR: /opt/Xilinx/Vivado/2022.2/data +RDI_BINDIR: /opt/Xilinx/Vivado/2022.2/bin + +Vivado preferences file: /home/abraxas3d/.Xilinx/Vivado/2022.2/vivado.xml +Vivado preferences directory: /home/abraxas3d/.Xilinx/Vivado/2022.2/ +Vivado layouts directory: /home/abraxas3d/.Xilinx/Vivado/2022.2/data/layouts +PlanAhead jar file: /opt/Xilinx/Vivado/2022.2/lib/classes/planAhead.jar +Vivado log file: /home/abraxas3d/pluto_msk/vivado.log +Vivado journal file: /home/abraxas3d/pluto_msk/vivado.jou +Engine tmp dir: ./.Xil/Vivado-1622766-mymelody + +Xilinx Environment Variables +---------------------------- +RDI_APPROOT: /opt/Xilinx/Vivado/2022.2 +RDI_BASEROOT: /opt/Xilinx/Vivado +RDI_BINROOT: /opt/Xilinx/Vivado/2022.2/bin +RDI_BUILD: yes +RDI_DATADIR: /opt/Xilinx/Vivado/2022.2/data +RDI_INSTALLROOT: /opt/Xilinx +RDI_INSTALLVER: 2022.2 +RDI_JAVA_PLATFORM: +RDI_JAVA_VERSION: 11.0.11_9 +RDI_LIBDIR: /opt/Xilinx/Vivado/2022.2/lib/lnx64.o/Ubuntu:/opt/Xilinx/Vivado/2022.2/lib/lnx64.o +RDI_OPT_EXT: .o +RDI_PATCHROOT: +RDI_PLATFORM: lnx64 +RDI_PREPEND_PATH: /opt/Xilinx/Vitis/2022.2/bin:/opt/Xilinx/Vivado/2022.2/ids_lite/ISE/bin/lin64 +RDI_PROG: /opt/Xilinx/Vivado/2022.2/bin/unwrapped/lnx64.o/vivado +RDI_TPS_ROOT: /opt/Xilinx/Vivado/2022.2/tps/lnx64 +RDI_USE_JDK11: True +XILINX: /opt/Xilinx/Vivado/2022.2/ids_lite/ISE +XILINX_DSP: /opt/Xilinx/Vivado/2022.2/ids_lite/ISE +XILINX_HLS: /opt/Xilinx/Vitis_HLS/2022.2 +XILINX_PLANAHEAD: /opt/Xilinx/Vivado/2022.2 +XILINX_SDK: /opt/Xilinx/Vitis/2022.2 +XILINX_VITIS: /opt/Xilinx/Vitis/2022.2 +XILINX_VIVADO: /opt/Xilinx/Vivado/2022.2 +XILINX_VIVADO_HLS: /opt/Xilinx/Vivado/2022.2 + + +GUI allocated memory: 256 MB +GUI max memory: 3,072 MB +Engine allocated memory: 1,587 MB + +Copyright 1986-2022 Xilinx, Inc. All Rights Reserved. + +*/ + +// TclEventType: START_GUI +// Tcl Message: start_gui +// HMemoryUtils.trashcanNow. Engine heap size: 1,592 MB. GUI used memory: 56 MB. Current time: 11/23/25, 1:40:27 PM PST +setText(RDIResource.CommandsInput_TYPE_TCL_COMMAND_HERE, "pwd", true); // h.a +// Tcl Command: 'pwd' +// Tcl Command: 'pwd' +// Tcl Message: pwd +// Tcl Message: /home/abraxas3d/pluto_msk +setText(RDIResource.CommandsInput_TYPE_TCL_COMMAND_HERE, "cd ..", true); // h.a +// Tcl Command: 'cd ..' +// Tcl Command: 'cd ..' +// Tcl Message: cd .. +setText(RDIResource.CommandsInput_TYPE_TCL_COMMAND_HERE, "pwd", true); // h.a +// Tcl Command: 'pwd' +// Tcl Command: 'pwd' +// Tcl Message: pwd +// Tcl Message: /home/abraxas3d +// Tcl Command: 'rdi::info_commands {d*}' +// Tcl Command: 'rdi::info_commands {l*}' +// Tcl Command: 'rdi::info_commands {ls*}' +// Tcl Command: 'rdi::match_options {ls} {}' +setText(RDIResource.CommandsInput_TYPE_TCL_COMMAND_HERE, "ls -la", true); // h.a +// Tcl Command: 'ls -la' +// Tcl Command: 'ls -la' +// Tcl Message: ls -la +// [GUI Memory]: 64 MB (+64637kb) [00:00:34] +// [Engine Memory]: 1,596 MB (+1522551kb) [00:00:34] +// Tcl Command: 'rdi::info_commands {l*}' +setText(RDIResource.CommandsInput_TYPE_TCL_COMMAND_HERE, "ls msk_*", true); // h.a +// Tcl Command: 'ls msk_*' +// Tcl Command: 'ls msk_*' +// Tcl Message: ls msk_* +// Tcl Message: /usr/bin/ls: cannot access 'msk_*': No such file or directory ambiguous command name "ls": lsearch lset lsort +setText(RDIResource.CommandsInput_TYPE_TCL_COMMAND_HERE, "pwd", true); // h.a +// Tcl Command: 'pwd' +// Tcl Command: 'pwd' +// Tcl Message: pwd +// Tcl Message: /home/abraxas3d +setText(RDIResource.CommandsInput_TYPE_TCL_COMMAND_HERE, "ls *.tcl", true); // h.a +// Tcl Command: 'ls *.tcl' +// Tcl Command: 'ls *.tcl' +// Tcl Message: ls *.tcl +// Tcl Message: /usr/bin/ls: cannot access '*.tcl': No such file or directory ambiguous command name "ls": lsearch lset lsort +// Tcl Command: 'rdi::info_commands {pw*}' +setText(RDIResource.CommandsInput_TYPE_TCL_COMMAND_HERE, "pwd", true); // h.a +// Tcl Command: 'pwd' +// Tcl Command: 'pwd' +// Tcl Message: pwd +// Tcl Message: /home/abraxas3d +// Tcl Command: 'rdi::info_commands {sour*}' +// Elapsed time: 15 seconds +setText(RDIResource.CommandsInput_TYPE_TCL_COMMAND_HERE, "source msk_modem_134byte"); // h.a +// Elapsed time: 29 seconds +setText(RDIResource.CommandsInput_TYPE_TCL_COMMAND_HERE, "source"); // h.a +selectMenuItem(RDIResourceCommand.RDICommands_PASTE, "Paste"); // ao +applyEnter(RDIResource.CommandsInput_TYPE_TCL_COMMAND_HERE, "source msk_modem_134byte_test.tcl"); // h.a +// Tcl Command: 'source msk_modem_134byte_test.tcl' +// Tcl Command: 'source msk_modem_134byte_test.tcl' +// TclEventType: LOAD_FEATURE +// Tcl Message: source msk_modem_134byte_test.tcl +// Tcl Message: # catch {close_sim -force} # cd [file dirname [info script]] # set project_name "msk_axistream_debug_msb" # set project_dir "./axistream_debug_project_msb" # set part_name "xc7z010clg400-1" # if {[file exists $project_dir]} { # file delete -force $project_dir # } +// TclEventType: DEBUG_PROBE_SET_CHANGE +// TclEventType: FLOW_ADDED +// TclEventType: FILE_SET_NEW +// TclEventType: RUN_ADD +// TclEventType: RUN_CURRENT +// TclEventType: PROJECT_DASHBOARD_NEW +// TclEventType: PROJECT_DASHBOARD_GADGET_NEW +// TclEventType: PROJECT_DASHBOARD_GADGET_CHANGE +// TclEventType: PROJECT_DASHBOARD_GADGET_NEW +// TclEventType: PROJECT_DASHBOARD_GADGET_CHANGE +// TclEventType: PROJECT_DASHBOARD_GADGET_NEW +// TclEventType: PROJECT_DASHBOARD_GADGET_CHANGE +// TclEventType: PROJECT_DASHBOARD_GADGET_NEW +// TclEventType: PROJECT_DASHBOARD_GADGET_CHANGE +// TclEventType: PROJECT_DASHBOARD_GADGET_NEW +// TclEventType: PROJECT_DASHBOARD_GADGET_CHANGE +// TclEventType: PROJECT_DASHBOARD_GADGET_NEW +// TclEventType: PROJECT_DASHBOARD_GADGET_CHANGE +// TclEventType: PROJECT_NEW +// [GUI Memory]: 72 MB (+5382kb) [00:01:55] +// [Engine Memory]: 1,681 MB (+5126kb) [00:01:55] +// [GUI Memory]: 102 MB (+27110kb) [00:01:56] +// WARNING: HEventQueue.dispatchEvent() is taking 2277 ms. +// TclEventType: FILE_SET_OPTIONS_CHANGE +// Tcl Message: # create_project $project_name $project_dir -part $part_name -force +// Tcl Message: INFO: [IP_Flow 19-234] Refreshing IP repositories INFO: [IP_Flow 19-1704] No user IP repositories specified INFO: [IP_Flow 19-2313] Loaded Vivado IP repository '/opt/Xilinx/Vivado/2022.2/data/ip'. +// HMemoryUtils.trashcanNow. Engine heap size: 1,804 MB. GUI used memory: 63 MB. Current time: 11/23/25, 1:42:12 PM PST +// TclEventType: FILE_SET_OPTIONS_CHANGE +// [Engine Memory]: 1,805 MB (+41488kb) [00:01:57] +// TclEventType: FILE_SET_OPTIONS_CHANGE +// TclEventType: PROJECT_CHANGE +// TclEventType: FILE_SET_OPTIONS_CHANGE +// TclEventType: FILE_SET_CHANGE +// Tcl Message: ======================================== +// Tcl Message: # puts "Adding VHDL source files..." +// Tcl Message: Adding VHDL source files... +// Tcl Message: # puts "Current directory: [pwd]" +// Tcl Message: Current directory: /home/abraxas3d +// Tcl Message: # puts "========================================" +// Tcl Message: ======================================== +// Tcl Message: # puts "\n--- PeakRDL Packages ---" +// Tcl Message: --- PeakRDL Packages --- +// Tcl Message: # safe_add_files sources_1 { # ./pluto_msk/rdl/src/axi4lite_intf_pkg.vhd # ./pluto_msk/rdl/src/reg_utils.vhd # } +// Tcl Message: ✓ Adding: ./pluto_msk/rdl/src/axi4lite_intf_pkg.vhd ✓ Adding: ./pluto_msk/rdl/src/reg_utils.vhd +// Tcl Message: # puts "\n--- CSR Support Components ---" +// Tcl Message: --- CSR Support Components --- +// Tcl Message: # safe_add_files sources_1 { # ./pluto_msk/src/cdc_resync.vhd # ./pluto_msk/src/pulse_detect.vhd # ./pluto_msk/src/data_capture.vhd # } +// Tcl Message: ✓ Adding: ./pluto_msk/src/cdc_resync.vhd ✓ Adding: ./pluto_msk/src/pulse_detect.vhd ✓ Adding: ./pluto_msk/src/data_capture.vhd +// Tcl Message: # puts "\n--- Register File & Packages ---" +// Tcl Message: --- Register File & Packages --- +// Tcl Message: # safe_add_files sources_1 { # ./pluto_msk/rdl/outputs/rtl/msk_top_regs_pkg.vhd # ./pluto_msk/rdl/outputs/rtl/msk_top_regs.vhd # } +// Tcl Message: ✓ Adding: ./pluto_msk/rdl/outputs/rtl/msk_top_regs_pkg.vhd ✓ Adding: ./pluto_msk/rdl/outputs/rtl/msk_top_regs.vhd +// Tcl Message: # puts "\n--- Low-Level Components ---" +// Tcl Message: --- Low-Level Components --- +// Tcl Message: # safe_add_files sources_1 { # ./pluto_msk/nco/src/sin_cos_lut.vhd # ./pluto_msk/prbs/src/prbs_gen.vhd # ./pluto_msk/prbs/src/prbs_mon.vhd # ./pluto_msk/lowpass_ema/src/lowpass_ema.vhd # ./pluto_msk/nco/src/nco.vhd # ./pluto_msk/pi_controller/src/pi_controller.vhd # ./pluto_msk/power_detector/src/power_detector.vhd # } +// Tcl Message: ✓ Adding: ./pluto_msk/nco/src/sin_cos_lut.vhd ✓ Adding: ./pluto_msk/prbs/src/prbs_gen.vhd ✓ Adding: ./pluto_msk/prbs/src/prbs_mon.vhd ✓ Adding: ./pluto_msk/lowpass_ema/src/lowpass_ema.vhd ✓ Adding: ./pluto_msk/nco/src/nco.vhd ✓ Adding: ./pluto_msk/pi_controller/src/pi_controller.vhd ✓ Adding: ./pluto_msk/power_detector/src/power_detector.vhd +// Tcl Message: # puts "\n--- Modulator/Demodulator ---" +// Tcl Message: --- Modulator/Demodulator --- +// Tcl Message: # safe_add_files sources_1 { # ./pluto_msk/msk_modulator/src/msk_modulator.vhd # ./pluto_msk/msk_demodulator/src/costas_loop.vhd # ./pluto_msk/msk_demodulator/src/msk_demodulator.vhd # } +// Tcl Message: ✓ Adding: ./pluto_msk/msk_modulator/src/msk_modulator.vhd ✓ Adding: ./pluto_msk/msk_demodulator/src/costas_loop.vhd ✓ Adding: ./pluto_msk/msk_demodulator/src/msk_demodulator.vhd +// Tcl Message: # puts "\n--- TX Path Components ---" +// Tcl Message: --- TX Path Components --- +// Tcl Message: # safe_add_files sources_1 { # ./pluto_msk/src/axis_dma_adapter.vhd # ./pluto_msk/src/byte_to_bit_deserializer.vhd # ./pluto_msk/src/axis_async_fifo.vhd # } +// Tcl Message: ✓ Adding: ./pluto_msk/src/axis_dma_adapter.vhd ✓ Adding: ./pluto_msk/src/byte_to_bit_deserializer.vhd ✓ Adding: ./pluto_msk/src/axis_async_fifo.vhd +// Tcl Message: # puts "\n--- RX Path Components ---" +// Tcl Message: --- RX Path Components --- +// Tcl Message: # safe_add_files sources_1 { # ./pluto_msk/src/frame_sync_detector.vhd # } +// Tcl Message: ✓ Adding: ./pluto_msk/src/frame_sync_detector.vhd +// Tcl Message: # puts "\n--- FEC Encoder/Decoder (K=7 Viterbi) ---" +// Tcl Message: --- FEC Encoder/Decoder (K=7 Viterbi) --- +// Tcl Message: # safe_add_files sources_1 { # ./pluto_msk/src/conv_encoder_k7.vhd # ./pluto_msk/src/viterbi_decoder_k7_simple.vhd # } +// Tcl Message: ✓ Adding: ./pluto_msk/src/conv_encoder_k7.vhd ✓ Adding: ./pluto_msk/src/viterbi_decoder_k7_simple.vhd +// Tcl Message: # puts "\n--- OV Frame Encoder/Decoder (134→268→134 bytes) ---" +// Tcl Message: --- OV Frame Encoder/Decoder (134→268→134 bytes) --- +// Tcl Message: # safe_add_files sources_1 { # ./pluto_msk/src/ov_frame_encoder.vhd # ./pluto_msk/src/ov_frame_decoder.vhd # } +// Tcl Message: ✓ Adding: ./pluto_msk/src/ov_frame_encoder.vhd ✓ Adding: ./pluto_msk/src/ov_frame_decoder.vhd +// Tcl Message: # puts "\n--- CSR Wrapper ---" +// Tcl Message: --- CSR Wrapper --- +// Tcl Message: # safe_add_files sources_1 { # ./pluto_msk/src/msk_top_csr.vhd # } +// Tcl Message: ✓ Adding: ./pluto_msk/src/msk_top_csr.vhd +// Tcl Message: # puts "\n--- Top Level ---" +// Tcl Message: --- Top Level --- +// Tcl Message: # safe_add_files sources_1 { # ./pluto_msk/src/msk_top.vhd # } +// Tcl Message: ✓ Adding: ./pluto_msk/src/msk_top.vhd +// Tcl Message: # puts "\n--- Testbench ---" +// Tcl Message: --- Testbench --- +// Tcl Message: # safe_add_files sim_1 { # ./tb_msk_modem_134byte.vhd # } +// Tcl Message: ✓ Adding: ./tb_msk_modem_134byte.vhd +// Tcl Message: # puts "\n========================================" +// Tcl Message: ======================================== +// Tcl Message: # puts "File addition complete" +// Tcl Message: File addition complete +// Tcl Message: # puts "========================================" +// Tcl Message: ======================================== +// Tcl Message: # puts "\nConfiguring simulation..." +// Tcl Message: Configuring simulation... +// Tcl Message: # update_compile_order -fileset sources_1 +// TclEventType: FILE_SET_CHANGE +// TclEventType: DG_GRAPH_STALE +// Tcl Message: # update_compile_order -fileset sim_1 +// TclEventType: FILE_SET_CHANGE +// TclEventType: DG_GRAPH_STALE +// TclEventType: FILE_SET_CHANGE +// TclEventType: FILE_SET_OPTIONS_CHANGE +// TclEventType: LAUNCH_SIM +// TclEventType: FILE_SET_OPTIONS_CHANGE +// Tcl Message: # set_property top tb_msk_modem_134byte [get_filesets sim_1] # set_property top_lib work [get_filesets sim_1] # puts "\n========================================" +// Tcl Message: ======================================== +// Tcl Message: # puts "Launching behavioral simulation..." +// Tcl Message: Launching behavioral simulation... +// Tcl Message: # puts "========================================" +// Tcl Message: ======================================== +// Tcl Message: # if {[catch {launch_simulation -simset sim_1 -mode behavioral} result]} { # puts "✗ Simulation launch failed: $result" # return # } +// Tcl Message: Command: launch_simulation -simset sim_1 -mode behavioral +// Tcl Message: INFO: [Vivado 12-12493] Simulation top is 'tb_msk_modem_134byte' +// Tcl Message: INFO: [Vivado 12-5682] Launching behavioral simulation in '/home/abraxas3d/axistream_debug_project_msb/msk_axistream_debug_msb.sim/sim_1/behav/xsim' INFO: [SIM-utils-51] Simulation object is 'sim_1' INFO: [SIM-utils-72] Using boost library from '/opt/Xilinx/Vivado/2022.2/tps/boost_1_72_0' INFO: [SIM-utils-54] Inspecting design source files for 'tb_msk_modem_134byte' in fileset 'sim_1'... INFO: [USF-XSim-97] Finding global include files... INFO: [USF-XSim-98] Fetching design files from 'sim_1'... INFO: [USF-XSim-2] XSim::Compile design +// Tcl Message: INFO: [USF-XSim-61] Executing 'COMPILE and ANALYZE' step in '/home/abraxas3d/axistream_debug_project_msb/msk_axistream_debug_msb.sim/sim_1/behav/xsim' +// Tcl Message: xvhdl --incr --relax -prj tb_msk_modem_134byte_vhdl.prj +// TclEventType: LAUNCH_SIM_LOG +// Tcl Message: INFO: [USF-XSim-69] 'compile' step finished in '2' seconds INFO: [USF-XSim-3] XSim::Elaborate design INFO: [USF-XSim-61] Executing 'ELABORATE' step in '/home/abraxas3d/axistream_debug_project_msb/msk_axistream_debug_msb.sim/sim_1/behav/xsim' +// Tcl Message: xelab --incr --debug typical --relax --mt 8 -L xil_defaultlib -L secureip --snapshot tb_msk_modem_134byte_behav xil_defaultlib.tb_msk_modem_134byte -log elaborate.log +// Tcl Message: Vivado Simulator v2022.2 Copyright 1986-1999, 2001-2022 Xilinx, Inc. All Rights Reserved. Running: /opt/Xilinx/Vivado/2022.2/bin/unwrapped/lnx64.o/xelab --incr --debug typical --relax --mt 8 -L xil_defaultlib -L secureip --snapshot tb_msk_modem_134byte_behav xil_defaultlib.tb_msk_modem_134byte -log elaborate.log Using 8 slave threads. Starting static elaboration Completed static elaboration Starting simulation data flow analysis Completed simulation data flow analysis +// TclEventType: LAUNCH_SIM +// Tcl Message: Built simulation snapshot tb_msk_modem_134byte_behav +// Tcl Message: execute_script: Time (s): cpu = 00:00:06 ; elapsed = 00:00:06 . Memory (MB): peak = 7062.309 ; gain = 0.000 ; free physical = 8326 ; free virtual = 26574 +// Tcl Message: INFO: [USF-XSim-69] 'elaborate' step finished in '6' seconds INFO: [USF-XSim-4] XSim::Simulate design INFO: [USF-XSim-61] Executing 'SIMULATE' step in '/home/abraxas3d/axistream_debug_project_msb/msk_axistream_debug_msb.sim/sim_1/behav/xsim' INFO: [USF-XSim-98] *** Running xsim +// Tcl Message: with args "tb_msk_modem_134byte_behav -key {Behavioral:sim_1:Functional:tb_msk_modem_134byte} -tclbatch {tb_msk_modem_134byte.tcl} -log {simulate.log}" +// Tcl Message: INFO: [USF-XSim-8] Loading simulator feature +// TclEventType: SIMULATION_CREATE_SIMULATION_OBJECT +// TclEventType: SIMULATION_UPDATE_SIMULATION_STATE +// TclEventType: SIMULATION_UPDATE_SCOPE_TREE +// TclEventType: SIMULATION_UPDATE_STACKS +// TclEventType: SIMULATION_UPDATE_OBJECT_TREE +// TclEventType: SIMULATION_UPDATE_PROTOCOL_INSTANCE_TREE +// TclEventType: SIMULATION_UPDATE_SCOPE_TREE +// TclEventType: SIMULATION_UPDATE_STACKS +// TclEventType: SIMULATION_UPDATE_OBJECT_TREE +// TclEventType: SIMULATION_UPDATE_PROTOCOL_INSTANCE_TREE +// TclEventType: SIMULATION_UPDATE_SCOPE_TREE +// TclEventType: SIMULATION_UPDATE_STACKS +// TclEventType: SIMULATION_UPDATE_OBJECT_TREE +// TclEventType: SIMULATION_UPDATE_PROTOCOL_INSTANCE_TREE +// Tcl Message: Time resolution is 1 ps +// Elapsed time: 19 seconds +closeView(PAResourceOtoP.PAViews_PROJECT_SUMMARY, "Project Summary"); // t +// TclEventType: WAVEFORM_UPDATE_TITLE +// TclEventType: WAVEFORM_OPEN_WCFG +// TclEventType: SIMULATION_UPDATE_SCOPE_TREE +// TclEventType: SIMULATION_UPDATE_STACKS +// TclEventType: SIMULATION_UPDATE_OBJECT_TREE +// TclEventType: SIMULATION_UPDATE_PROTOCOL_INSTANCE_TREE +// TclEventType: WAVEFORM_OPEN_WCFG +// TclEventType: WAVEFORM_DELAYED_MODEL_EVENT +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MODEL_EVENT +// Tcl Message: source tb_msk_modem_134byte.tcl +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// [GUI Memory]: 114 MB (+7137kb) [00:02:13] +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_MODEL_EVENT +// HMemoryUtils.trashcanNow. Engine heap size: 1,858 MB. GUI used memory: 123 MB. Current time: 11/23/25, 1:42:28 PM PST +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_UPDATE_TITLE +// TclEventType: WAVEFORM_DELAYED_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_TITLE +// TclEventType: SIMULATION_UPDATE_SIMULATION_STATE +// TclEventType: SIMULATION_CLEAR_CURRENT_LINE +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,861 MB. GUI used memory: 69 MB. Current time: 11/23/25, 1:42:32 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,861 MB. GUI used memory: 69 MB. Current time: 11/23/25, 1:42:36 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,861 MB. GUI used memory: 69 MB. Current time: 11/23/25, 1:42:38 PM PST +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,861 MB. GUI used memory: 69 MB. Current time: 11/23/25, 1:42:39 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,862 MB. GUI used memory: 69 MB. Current time: 11/23/25, 1:42:43 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,862 MB. GUI used memory: 72 MB. Current time: 11/23/25, 1:42:47 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// Elapsed time: 21 seconds +selectButton(RDIResource.ProgressDialog_BACKGROUND, "Background"); // a +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,862 MB. GUI used memory: 69 MB. Current time: 11/23/25, 1:42:50 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,863 MB. GUI used memory: 69 MB. Current time: 11/23/25, 1:42:53 PM PST +// TclEventType: SIMULATION_UPDATE_SCOPE_TREE +// TclEventType: SIMULATION_UPDATE_STACKS +// TclEventType: SIMULATION_UPDATE_OBJECT_TREE +// TclEventType: SIMULATION_UPDATE_PROTOCOL_INSTANCE_TREE +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,864 MB. GUI used memory: 88 MB. Current time: 11/23/25, 1:42:55 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: SIMULATION_UPDATE_SCOPE_TREE +// TclEventType: SIMULATION_UPDATE_STACKS +// TclEventType: SIMULATION_UPDATE_OBJECT_TREE +// TclEventType: SIMULATION_UPDATE_PROTOCOL_INSTANCE_TREE +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,865 MB. GUI used memory: 67 MB. Current time: 11/23/25, 1:42:56 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,865 MB. GUI used memory: 67 MB. Current time: 11/23/25, 1:43:00 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,865 MB. GUI used memory: 70 MB. Current time: 11/23/25, 1:43:03 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,865 MB. GUI used memory: 67 MB. Current time: 11/23/25, 1:43:07 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,865 MB. GUI used memory: 69 MB. Current time: 11/23/25, 1:43:08 PM PST +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,865 MB. GUI used memory: 67 MB. Current time: 11/23/25, 1:43:10 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,865 MB. GUI used memory: 70 MB. Current time: 11/23/25, 1:43:14 PM PST +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,866 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:43:17 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,866 MB. GUI used memory: 67 MB. Current time: 11/23/25, 1:43:21 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,866 MB. GUI used memory: 67 MB. Current time: 11/23/25, 1:43:24 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,866 MB. GUI used memory: 67 MB. Current time: 11/23/25, 1:43:28 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// Elapsed time: 40 seconds +selectCodeEditor(RDIResource.TclConsoleView_TCL_CONSOLE_CODE_EDITOR, 880, 704); // cD +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,866 MB. GUI used memory: 89 MB. Current time: 11/23/25, 1:43:32 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,866 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:43:35 PM PST +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,866 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:43:38 PM PST +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,866 MB. GUI used memory: 67 MB. Current time: 11/23/25, 1:43:39 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// Elapsed time: 10 seconds +selectCodeEditor(RDIResource.TclConsoleView_TCL_CONSOLE_CODE_EDITOR, 2, 333, true, false, false, false, false); // cD - Shift Key +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +selectCodeEditor(RDIResource.TclConsoleView_TCL_CONSOLE_CODE_EDITOR, 165, 377, false, false, false, true, false); // cD - Popup Trigger +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,866 MB. GUI used memory: 67 MB. Current time: 11/23/25, 1:43:42 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +selectMenuItem(RDIResource.TclConsoleView_COPY, "Copy"); // ao +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +selectCodeEditor(RDIResource.TclConsoleView_TCL_CONSOLE_CODE_EDITOR, 404, 444); // cD +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,866 MB. GUI used memory: 67 MB. Current time: 11/23/25, 1:43:46 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,866 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:43:49 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,866 MB. GUI used memory: 67 MB. Current time: 11/23/25, 1:43:53 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,866 MB. GUI used memory: 67 MB. Current time: 11/23/25, 1:43:57 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,866 MB. GUI used memory: 67 MB. Current time: 11/23/25, 1:44:00 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,866 MB. GUI used memory: 67 MB. Current time: 11/23/25, 1:44:04 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,867 MB. GUI used memory: 75 MB. Current time: 11/23/25, 1:44:07 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,867 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:44:09 PM PST +// TclEventType: SIMULATION_UPDATE_SCOPE_TREE +// TclEventType: SIMULATION_UPDATE_STACKS +// TclEventType: SIMULATION_UPDATE_OBJECT_TREE +// TclEventType: SIMULATION_UPDATE_PROTOCOL_INSTANCE_TREE +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// HMemoryUtils.trashcanNow. Engine heap size: 1,867 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:44:09 PM PST +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,867 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:44:12 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,867 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:44:16 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,867 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:44:19 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,867 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:44:23 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,867 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:44:26 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,867 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:44:30 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,867 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:44:33 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,867 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:44:37 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,867 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:44:39 PM PST +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,867 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:44:40 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,867 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:44:44 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,867 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:44:47 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,867 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:44:51 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,867 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:44:55 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,867 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:44:58 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,867 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:45:02 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,867 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:45:05 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,867 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:45:09 PM PST +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,867 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:45:09 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,867 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:45:12 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,868 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:45:16 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,868 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:45:20 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,868 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:45:23 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,868 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:45:27 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,868 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:45:30 PM PST +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,868 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:45:34 PM PST +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,868 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:45:37 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,868 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:45:41 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,868 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:45:45 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,868 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:45:48 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,868 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:45:52 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,868 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:45:56 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,868 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:45:59 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,868 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:46:03 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,868 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:46:06 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,868 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:46:10 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,868 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:46:14 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,868 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:46:17 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,868 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:46:21 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,869 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:46:24 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,869 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:46:28 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,869 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:46:31 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,869 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:46:35 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,869 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:46:38 PM PST +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,869 MB. GUI used memory: 69 MB. Current time: 11/23/25, 1:46:39 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,869 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:46:42 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,869 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:46:46 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,869 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:46:49 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,869 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:46:53 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,869 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:46:57 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,869 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:47:00 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,869 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:47:04 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,869 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:47:07 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,869 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:47:08 PM PST +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,869 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:47:11 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,869 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:47:15 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,869 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:47:18 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,869 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:47:22 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,869 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:47:26 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,869 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:47:29 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,870 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:47:33 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,870 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:47:36 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,870 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:47:39 PM PST +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,870 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:47:40 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,870 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:47:44 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,870 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:47:47 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,870 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:47:51 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,870 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:47:54 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,870 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:47:58 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,870 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:48:02 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,870 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:48:05 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,870 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:48:09 PM PST +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,870 MB. GUI used memory: 69 MB. Current time: 11/23/25, 1:48:09 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,870 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:48:12 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,870 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:48:16 PM PST +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,870 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:48:20 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,870 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:48:23 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,870 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:48:27 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,870 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:48:31 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,870 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:48:34 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,870 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:48:38 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,870 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:48:39 PM PST +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,870 MB. GUI used memory: 70 MB. Current time: 11/23/25, 1:48:42 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,870 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:48:45 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,870 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:48:49 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,870 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:48:52 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,870 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:48:56 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,870 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:49:00 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,870 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:49:03 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,870 MB. GUI used memory: 70 MB. Current time: 11/23/25, 1:49:07 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:49:09 PM PST +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:49:10 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:49:14 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:49:17 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:49:21 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:49:25 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:49:28 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:49:32 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:49:35 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:49:39 PM PST +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:49:39 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:49:42 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:49:46 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:49:49 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:49:53 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:49:57 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:50:00 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:50:04 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:50:07 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 69 MB. Current time: 11/23/25, 1:50:09 PM PST +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 70 MB. Current time: 11/23/25, 1:50:11 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:50:15 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:50:18 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:50:22 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:50:25 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:50:29 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:50:33 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:50:36 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 70 MB. Current time: 11/23/25, 1:50:39 PM PST +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 70 MB. Current time: 11/23/25, 1:50:40 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:50:44 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:50:47 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:50:51 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:50:54 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:50:58 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:51:02 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:51:05 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:51:09 PM PST +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:51:09 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:51:12 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:51:16 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:51:20 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:51:23 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:51:27 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:51:30 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:51:34 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:51:38 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:51:39 PM PST +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:51:41 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:51:45 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:51:48 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:51:52 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:51:56 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:51:59 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:52:03 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:52:06 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:52:09 PM PST +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:52:10 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:52:14 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:52:17 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:52:21 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:52:25 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:52:28 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:52:32 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:52:35 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:52:39 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:52:43 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:52:46 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:52:50 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 70 MB. Current time: 11/23/25, 1:52:54 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:52:57 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:53:01 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:53:05 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:53:08 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:53:12 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:53:15 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:53:19 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:53:23 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:53:26 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:53:30 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:53:33 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:53:37 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:53:41 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:53:44 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:53:48 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:53:51 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:53:55 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:53:58 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:54:02 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:54:06 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:54:09 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:54:13 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:54:17 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:54:20 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:54:24 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,871 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:54:27 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,872 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:54:31 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,872 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:54:34 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,872 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:54:38 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,872 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:54:38 PM PST +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,872 MB. GUI used memory: 70 MB. Current time: 11/23/25, 1:54:41 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,872 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:54:45 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,872 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:54:48 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,872 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:54:52 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,872 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:54:56 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,872 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:54:59 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,872 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:55:03 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,872 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:55:06 PM PST +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,872 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:55:08 PM PST +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,872 MB. GUI used memory: 69 MB. Current time: 11/23/25, 1:55:10 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,872 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:55:13 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,872 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:55:17 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,872 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:55:20 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,872 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:55:24 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,872 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:55:27 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,872 MB. GUI used memory: 71 MB. Current time: 11/23/25, 1:55:31 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,873 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:55:35 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,873 MB. GUI used memory: 98 MB. Current time: 11/23/25, 1:55:38 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,873 MB. GUI used memory: 69 MB. Current time: 11/23/25, 1:55:38 PM PST +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// HMemoryUtils.trashcanNow. Engine heap size: 1,873 MB. GUI used memory: 68 MB. Current time: 11/23/25, 1:55:42 PM PST +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: WAVEFORM_MODEL_EVENT +// TclEventType: WAVEFORM_UPDATE_WAVEFORM +// TclEventType: WAVEFORM_UPDATE_COMMANDS +// TclEventType: WAVEFORM_MOVE_CURSOR +// TclEventType: SIMULATION_UPDATE_LATEST_TIME +// TclEventType: SIMULATION_UPDATE_SCOPE_TREE +// TclEventType: SIMULATION_UPDATE_STACKS +// CommandFailedException: Unknown exception occurred +/* +#-------------------------------------------------------------------------- +# Xilinx Vivado v2022.2 (64-bit) +# SW Build: 3671981 on Fri Oct 14 04:59:54 MDT 2022 +# IP Build: 3669848 on Fri Oct 14 08:30:02 MDT 2022 +# Current time: Sun Nov 23 13:55:44 PST 2025 +# Process ID (PID): 1622766 +# OS: Ubuntu +# User: abraxas3d +# Project: msk_axistream_debug_msb +# Part: xc7z010clg400-1 +# +# This file is an indication that an internal application error occurred. +# This information is useful for debugging. Please open a case with Xilinx. +# Technical Support with this file and a testcase attached. +#-------------------------------------------------------------------------- +ui.utils.h: ui.frmwork.cmd.CommandFailedException: Unknown exception occurred ui.frmwork.cmd.CommandFailedException: Unknown exception occurred + at ui.views.simulator.executive.simulationi.SimulationExecutive_getCallStacksData(Native Method) + at ui.views.Q.c.a.jTw(SourceFile:532) + at ui.views.Q.a.o$c.reset(SourceFile:395) + at ui.views.Q.a.o$b.reset(SourceFile:274) + at ui.views.Q.a.o.reset(SourceFile:67) + at ui.views.Q.a.p.reset(SourceFile:124) + at ui.views.Q.a.p.handleTclEvent(SourceFile:114) + at ui.frmwork.a.m.c(SourceFile:42) + at ui.frmwork.D.i(SourceFile:216) + at ui.frmwork.D.fireTclEvent(SourceFile:139) + at ui.views.simulator.executive.simulationi.SimulationExecutive_setTreeWindowTreeHeight(Native Method) + at ui.views.Q.c.a.e(SourceFile:1221) + at ui.views.Q.i.c.jUj(SourceFile:122) + at ui.views.Q.i.f.componentResized(SourceFile:145) + at java.desktop/java.awt.Component.processComponentEvent(Component.java:6461) + at java.desktop/java.awt.Component.processEvent(Component.java:6415) + at java.desktop/java.awt.Container.processEvent(Container.java:2263) + at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5011) + at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2321) + at java.desktop/java.awt.Component.dispatchEvent(Component.java:4843) + at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:772) + at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721) + at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715) + at java.base/java.security.AccessController.doPrivileged(Native Method) + at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85) + at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95) + at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745) + at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:743) + at java.base/java.security.AccessController.doPrivileged(Native Method) + at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85) + at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742) + at ui.frmwork.a.d.dispatchEvent(SourceFile:92) + at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203) + at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124) + at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113) + at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109) + at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) + at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90) + (See /home/abraxas3d/pluto_msk/vivado_pid1622766.debug) +*/