Merge FPGA repository back into UHD repository
The FPGA codebase was removed from the UHD repository in 2014 to reduce the size of the repository. However, over the last half-decade, the split between the repositories has proven more burdensome than it has been helpful. By merging the FPGA code back, it will be possible to create atomic commits that touch both FPGA and UHD codebases. Continuous integration testing is also simplified by merging the repositories, because it was previously difficult to automatically derive the correct UHD branch when testing a feature branch on the FPGA repository. This commit also updates the license files and paths therein. We are therefore merging the repositories again. Future development for FPGA code will happen in the same repository as the UHD host code and MPM code. == Original Codebase and Rebasing == The original FPGA repository will be hosted for the foreseeable future at its original local location: https://github.com/EttusResearch/fpga/ It can be used for bisecting, reference, and a more detailed history. The final commit from said repository to be merged here is 05003794e2da61cabf64dd278c45685a7abad7ec. This commit is tagged as v4.0.0.0-pre-uhd-merge. If you have changes in the FPGA repository that you want to rebase onto the UHD repository, simply run the following commands: - Create a directory to store patches (this should be an empty directory): mkdir ~/patches - Now make sure that your FPGA codebase is based on the same state as the code that was merged: cd src/fpga # Or wherever your FPGA code is stored git rebase v4.0.0.0-pre-uhd-merge Note: The rebase command may look slightly different depending on what exactly you're trying to rebase. - Create a patch set for your changes versus v4.0.0.0-pre-uhd-merge: git format-patch v4.0.0.0-pre-uhd-merge -o ~/patches Note: Make sure that only patches are stored in your output directory. It should otherwise be empty. Make sure that you picked the correct range of commits, and only commits you wanted to rebase were exported as patch files. - Go to the UHD repository and apply the patches: cd src/uhd # Or wherever your UHD repository is stored git am --directory fpga ~/patches/* rm -rf ~/patches # This is for cleanup == Contributors == The following people have contributed mainly to these files (this list is not complete): Co-authored-by: Alex Williams <alex.williams@ni.com> Co-authored-by: Andrej Rode <andrej.rode@ettus.com> Co-authored-by: Ashish Chaudhari <ashish@ettus.com> Co-authored-by: Ben Hilburn <ben.hilburn@ettus.com> Co-authored-by: Ciro Nishiguchi <ciro.nishiguchi@ni.com> Co-authored-by: Daniel Jepson <daniel.jepson@ni.com> Co-authored-by: Derek Kozel <derek.kozel@ettus.com> Co-authored-by: EJ Kreinar <ej@he360.com> Co-authored-by: Humberto Jimenez <humberto.jimenez@ni.com> Co-authored-by: Ian Buckley <ian.buckley@gmail.com> Co-authored-by: Jörg Hofrichter <joerg.hofrichter@ni.com> Co-authored-by: Jon Kiser <jon.kiser@ni.com> Co-authored-by: Josh Blum <josh@joshknows.com> Co-authored-by: Jonathon Pendlum <jonathan.pendlum@ettus.com> Co-authored-by: Martin Braun <martin.braun@ettus.com> Co-authored-by: Matt Ettus <matt@ettus.com> Co-authored-by: Michael West <michael.west@ettus.com> Co-authored-by: Moritz Fischer <moritz.fischer@ettus.com> Co-authored-by: Nick Foster <nick@ettus.com> Co-authored-by: Nicolas Cuervo <nicolas.cuervo@ettus.com> Co-authored-by: Paul Butler <paul.butler@ni.com> Co-authored-by: Paul David <paul.david@ettus.com> Co-authored-by: Ryan Marlow <ryan.marlow@ettus.com> Co-authored-by: Sugandha Gupta <sugandha.gupta@ettus.com> Co-authored-by: Sylvain Munaut <tnt@246tNt.com> Co-authored-by: Trung Tran <trung.tran@ettus.com> Co-authored-by: Vidush Vishwanath <vidush.vishwanath@ettus.com> Co-authored-by: Wade Fife <wade.fife@ettus.com> Original-commit: bafa9d95453387814ef25e6b6256ba8db2df612f
This commit is contained in:
co-authored by
Alex Williams
Andrej Rode
Ashish Chaudhari
Ben Hilburn
Ciro Nishiguchi
Daniel Jepson
Derek Kozel
EJ Kreinar
Humberto Jimenez
Ian Buckley
Jörg Hofrichter
Jon Kiser
Josh Blum
Jonathon Pendlum
Matt Ettus
Michael West
Moritz Fischer
Nick Foster
Nicolas Cuervo
Paul Butler
Paul David
Ryan Marlow
Sugandha Gupta
Sylvain Munaut
Trung Tran
Vidush Vishwanath
Wade Fife
parent
74893643ca
commit
6b67702ad7
@@ -0,0 +1,8 @@
|
||||
build
|
||||
build-*
|
||||
isim*
|
||||
fuse*
|
||||
tmp*
|
||||
*.log
|
||||
*.jou
|
||||
*impact*
|
||||
@@ -0,0 +1,191 @@
|
||||
#
|
||||
# Copyright 2016-2018 Ettus Research, a National Instruments Company
|
||||
# Copyright 2019 Ettus Research, a National Instruments Brand
|
||||
#
|
||||
|
||||
# NOTE: All comments prefixed with a "##" will be displayed as a part of the "make help" target
|
||||
##-------------------
|
||||
##USRP N3XX FPGA Help
|
||||
##-------------------
|
||||
##Usage:
|
||||
## make <Targets> <Options>
|
||||
##
|
||||
##Output:
|
||||
## build/usrp_<product>_fpga_<image_type>.bit: Configuration bitstream with header
|
||||
## build/usrp_<product>_fpga_<image_type>.dts: Device tree source file
|
||||
## build/usrp_<product>_fpga_<image_type>.rpt: Build report (includes utilization and timing summary)
|
||||
|
||||
# Debug Options
|
||||
# Uncomment this line or add to make arg to omit radio_clk (sourced from db) and use bus_clk as radio_clk
|
||||
# OPTIONS += NO_DB=1
|
||||
# Uncomment this line to add two example Aurora loopback lanes on the general NPIO bus.
|
||||
# OPTIONS += NPIO_LANES=2
|
||||
# Uncomment this line to add four example Aurora loopback lanes on the QSFP NPIO bus.
|
||||
# OPTIONS += QSFP_LANES=4
|
||||
|
||||
# Additional definitions specific to the various targets:
|
||||
WX_DEFS=SFP0_WR=1 SFP1_10GBE=1 USE_REPLAY=1 BUILD_WR=1 BUILD_10G=1 $(OPTIONS)
|
||||
HG_DEFS=SFP0_1GBE=1 SFP1_10GBE=1 USE_REPLAY=1 BUILD_1G=1 BUILD_10G=1 $(OPTIONS)
|
||||
XG_DEFS=SFP0_10GBE=1 SFP1_10GBE=1 USE_REPLAY=1 BUILD_10G=1 $(OPTIONS)
|
||||
HA_DEFS=SFP0_1GBE=1 SFP1_AURORA=1 USE_REPLAY=1 BUILD_1G=1 BUILD_AURORA=1 $(OPTIONS)
|
||||
XA_DEFS=SFP0_10GBE=1 SFP1_AURORA=1 USE_REPLAY=1 BUILD_10G=1 BUILD_AURORA=1 $(OPTIONS)
|
||||
AA_DEFS=SFP0_AURORA=1 SFP1_AURORA=1 BUILD_AURORA=1 $(OPTIONS)
|
||||
XQ_DEFS=SFP0_WR=1 QSFP_10GBE=1 USE_REPLAY=1 BUILD_WR=1 BUILD_10G=1 QSFP_LANES=2 $(OPTIONS)
|
||||
AQ_DEFS=SFP0_10GBE=1 SFP1_10GBE=1 QSFP_AURORA=1 USE_REPLAY=1 BUILD_10G=1 BUILD_AURORA=1 QSFP_LANES=4 $(OPTIONS)
|
||||
|
||||
# Defaults specific to the various targets:
|
||||
N300_DEFAULTS:=DEFAULT_RFNOC_IMAGE_CORE_FILE=n300_rfnoc_image_core.v DEFAULT_EDGE_FILE=$(abspath n300_static_router.hex)
|
||||
N310_DEFAULTS:=DEFAULT_RFNOC_IMAGE_CORE_FILE=n310_rfnoc_image_core.v DEFAULT_EDGE_FILE=$(abspath n310_static_router.hex)
|
||||
N320_DEFAULTS:=DEFAULT_RFNOC_IMAGE_CORE_FILE=n320_rfnoc_image_core.v DEFAULT_EDGE_FILE=$(abspath n320_static_router.hex)
|
||||
N300AA_DEFAULTS:=DEFAULT_RFNOC_IMAGE_CORE_FILE=n300_bist_image_core.v DEFAULT_EDGE_FILE=$(abspath n300_bist_static_router.hex)
|
||||
N310AA_DEFAULTS:=DEFAULT_RFNOC_IMAGE_CORE_FILE=n310_bist_image_core.v DEFAULT_EDGE_FILE=$(abspath n310_bist_static_router.hex)
|
||||
|
||||
# Set build option (check RTL, run synthesis, or do a full build)
|
||||
ifndef TARGET
|
||||
ifdef CHECK
|
||||
TARGET = rtl
|
||||
else ifdef SYNTH
|
||||
TARGET = synth
|
||||
else
|
||||
TARGET = bin
|
||||
endif
|
||||
endif
|
||||
TOP ?= n3xx
|
||||
|
||||
# vivado_build($1=Device, $2=Definitions, $3=Defaults)
|
||||
# Device: N300, N310, or N320
|
||||
# Definitions: See above (*_DEFS)
|
||||
# Defaults: See above (*_DEFAULTS)
|
||||
vivado_build = make -f Makefile.n3xx.inc $(TARGET) NAME=$@ ARCH=$(XIL_ARCH_$1) PART_ID=$(XIL_PART_ID_$1) $2 TOP_MODULE=$(TOP) EXTRA_DEFS="$2" $3
|
||||
|
||||
# post_build($1=Device, $2=Option)
|
||||
ifeq ($(TARGET),bin)
|
||||
post_build = @\
|
||||
mkdir -p build; \
|
||||
echo "Exporting bitstream file..."; \
|
||||
cp build-$(1)_$(2)/n3xx.bit build/usrp_`echo $(1) | tr A-Z a-z`_fpga_$(2).bit; \
|
||||
echo "Exporting build report..."; \
|
||||
cp build-$(1)_$(2)/build.rpt build/usrp_`echo $(1) | tr A-Z a-z`_fpga_$(2).rpt; \
|
||||
echo "Build DONE ... $(1)_$(2)";
|
||||
else
|
||||
post_build = @echo "Skipping bitfile export."
|
||||
endif
|
||||
|
||||
##
|
||||
##Supported Targets
|
||||
##-----------------
|
||||
|
||||
all: N300_HG N300_XG N310_HG N310_XG N320_HG N320_XG ##(Default target)
|
||||
|
||||
##N310_WX: 1GigE White Rabbit on SFP+ Port0, 10Gig on SFP+ Port1.
|
||||
N310_WX: build/usrp_n310_fpga_WX.dts
|
||||
$(call vivado_build,N310,$(WX_DEFS) N310=1,$(N310_DEFAULTS))
|
||||
$(call post_build,N310,WX)
|
||||
|
||||
##N310_HG: 1GigE on SFP+ Port0, 10Gig on SFP+ Port1.
|
||||
N310_HG: build/usrp_n310_fpga_HG.dts
|
||||
$(call vivado_build,N310,$(HG_DEFS) N310=1,$(N310_DEFAULTS))
|
||||
$(call post_build,N310,HG)
|
||||
|
||||
##N310_XG: 10GigE on SFP+ Port0, 10Gig on SFP+ Port1.
|
||||
N310_XG: build/usrp_n310_fpga_XG.dts
|
||||
$(call vivado_build,N310,$(XG_DEFS) N310=1,$(N310_DEFAULTS))
|
||||
$(call post_build,N310,XG)
|
||||
|
||||
##N310_HA: 1Gig on SFP+ Port0, Aurora on SFP+ Port1.
|
||||
N310_HA: build/usrp_n310_fpga_HA.dts
|
||||
$(call vivado_build,N310,$(HA_DEFS) N310=1,$(N310_DEFAULTS))
|
||||
$(call post_build,N310,HA)
|
||||
|
||||
##N310_XA: 10Gig on SFP+ Port0, Aurora on SFP+ Port1.
|
||||
N310_XA: build/usrp_n310_fpga_XA.dts
|
||||
$(call vivado_build,N310,$(XA_DEFS) N310=1,$(N310_DEFAULTS))
|
||||
$(call post_build,N310,XA)
|
||||
|
||||
##N310_AA: Aurora on SFP+ Port0, Aurora on SFP+ Port1.
|
||||
N310_AA: build/usrp_n310_fpga_AA.dts
|
||||
$(call vivado_build,N310,$(AA_DEFS) N310=1,$(N310AA_DEFAULTS))
|
||||
$(call post_build,N310,AA)
|
||||
|
||||
##N300_WX: 1GigE White Rabbit on SFP+ Port0, 10Gig on SFP+ Port1.
|
||||
N300_WX: build/usrp_n300_fpga_WX.dts
|
||||
$(call vivado_build,N300,$(WX_DEFS) N300=1,$(N300_DEFAULTS))
|
||||
$(call post_build,N300,WX)
|
||||
|
||||
##N300_HG: 1GigE on SFP+ Port0, 10Gig on SFP+ Port1.
|
||||
N300_HG: build/usrp_n300_fpga_HG.dts
|
||||
$(call vivado_build,N300,$(HG_DEFS) N300=1,$(N300_DEFAULTS))
|
||||
$(call post_build,N300,HG)
|
||||
|
||||
##N300_XG: 10GigE on SFP+ Port0, 10Gig on SFP+ Port1.
|
||||
N300_XG: build/usrp_n300_fpga_XG.dts
|
||||
$(call vivado_build,N300,$(XG_DEFS) N300=1,$(N300_DEFAULTS))
|
||||
$(call post_build,N300,XG)
|
||||
|
||||
##N300_HA: 1Gig on SFP+ Port0, Aurora on SFP+ Port1.
|
||||
N300_HA: build/usrp_n300_fpga_HA.dts
|
||||
$(call vivado_build,N300,$(HA_DEFS) N300=1,$(N300_DEFAULTS))
|
||||
$(call post_build,N300,HA)
|
||||
|
||||
##N300_XA: 10Gig on SFP+ Port0, Aurora on SFP+ Port1.
|
||||
N300_XA: build/usrp_n300_fpga_XA.dts
|
||||
$(call vivado_build,N300,$(XA_DEFS) N300=1,$(N300_DEFAULTS))
|
||||
$(call post_build,N300,XA)
|
||||
|
||||
##N300_AA: Aurora on SFP+ Port0, Aurora on SFP+ Port1.
|
||||
N300_AA: build/usrp_n300_fpga_AA.dts
|
||||
$(call vivado_build,N300,$(AA_DEFS) N300=1,$(N300AA_DEFAULTS))
|
||||
$(call post_build,N300,AA)
|
||||
|
||||
##N320_WX: 1GigE White Rabbit on SFP+ Port0, 10Gig on SFP+ Port1.
|
||||
N320_WX: build/usrp_n320_fpga_WX.dts
|
||||
$(call vivado_build,N320,$(WX_DEFS) N320=1,$(N320_DEFAULTS))
|
||||
$(call post_build,N320,WX)
|
||||
|
||||
##N320_HG: 1GigE on SFP+ Port0, 10Gig on SFP+ Port1.
|
||||
N320_HG: build/usrp_n320_fpga_HG.dts
|
||||
$(call vivado_build,N320,$(HG_DEFS) N320=1,$(N320_DEFAULTS))
|
||||
$(call post_build,N320,HG)
|
||||
|
||||
##N320_XG: 10GigE on SFP+ Port0, 10Gig on SFP+ Port1.
|
||||
N320_XG: build/usrp_n320_fpga_XG.dts
|
||||
$(call vivado_build,N320,$(XG_DEFS) N320=1,$(N320_DEFAULTS))
|
||||
$(call post_build,N320,XG)
|
||||
|
||||
##N320_XQ: WR on SFP+ Port0, 10Gig on QSFP+ Port0,1.
|
||||
N320_XQ: build/usrp_n320_fpga_XQ.dts
|
||||
$(call vivado_build,N320,$(XQ_DEFS) N320=1,$(N320_DEFAULTS))
|
||||
$(call post_build,N320,XQ)
|
||||
|
||||
##N320_AQ: 10Gig on SFP+ Port0,1 Aurora on QSFP+ Port0,1,2,3.
|
||||
N320_AQ: build/usrp_n320_fpga_AQ.dts
|
||||
$(call vivado_build,N320,$(AQ_DEFS) N320=1,$(N320_DEFAULTS))
|
||||
$(call post_build,N320,AQ)
|
||||
|
||||
build/%.dts: dts/%.dts dts/*.dtsi
|
||||
-mkdir -p build
|
||||
${CC} -o $@ -E -I dts -nostdinc -undef -x assembler-with-cpp -D__DTS__ $<
|
||||
|
||||
clean: ##Clean up all target build outputs.
|
||||
@echo "Cleaning targets..."
|
||||
@rm -rf build-N3*_*
|
||||
@rm -rf build
|
||||
|
||||
cleanall: ##Clean up all target and ip build outputs.
|
||||
@echo "Cleaning targets and IP..."
|
||||
@rm -rf build-ip
|
||||
@rm -rf build-N3*_*
|
||||
@rm -rf build
|
||||
|
||||
help: ##Show this help message.
|
||||
@grep -h "##" Makefile | grep -v "\"##\"" | sed -e 's/\\$$//' | sed -e 's/##//'
|
||||
|
||||
##
|
||||
##Supported Options
|
||||
##-----------------
|
||||
##GUI=1 Launch the build in the Vivado GUI.
|
||||
##CHECK=1 Launch the syntax checker instead of building a bitfile.
|
||||
##SYNTH=1 Launch the build but stop after synthesis.
|
||||
##TOP=<module> Specify a top module for syntax checking. (Optional. Default is the bitfile top)
|
||||
|
||||
.PHONY: all clean cleanall help
|
||||
@@ -0,0 +1,161 @@
|
||||
#
|
||||
# Copyright 2008-2019 Ettus Research, a National Instruments Brand
|
||||
#
|
||||
|
||||
##################################################
|
||||
# Project Setup
|
||||
##################################################
|
||||
# TOP_MODULE = <Input arg>
|
||||
# NAME = <Input arg>
|
||||
# PART_ID = <Input arg>
|
||||
# ARCH = <Input arg>
|
||||
|
||||
##################################################
|
||||
# Include other makefiles
|
||||
##################################################
|
||||
|
||||
BASE_DIR = $(abspath ..)
|
||||
IP_DIR = $(abspath ./ip)
|
||||
include $(BASE_DIR)/../tools/make/viv_design_builder.mak
|
||||
|
||||
include $(IP_DIR)/Makefile.inc
|
||||
include coregen_dsp/Makefile.srcs
|
||||
include $(LIB_DIR)/ip/Makefile.inc
|
||||
include $(LIB_DIR)/hls/Makefile.inc
|
||||
include $(LIB_DIR)/control/Makefile.srcs
|
||||
include $(LIB_DIR)/fifo/Makefile.srcs
|
||||
include $(LIB_DIR)/simple_gemac/Makefile.srcs
|
||||
include $(LIB_DIR)/axi/Makefile.srcs
|
||||
include $(LIB_DIR)/timing/Makefile.srcs
|
||||
include $(LIB_DIR)/packet_proc/Makefile.srcs
|
||||
include $(LIB_DIR)/xge/Makefile.srcs
|
||||
include $(LIB_DIR)/xge_interface/Makefile.srcs
|
||||
include $(LIB_DIR)/dsp/Makefile.srcs
|
||||
include $(LIB_DIR)/axi/Makefile.srcs
|
||||
include $(LIB_DIR)/white_rabbit/wr_cores_v4_2/Makefile.srcs
|
||||
include $(LIB_DIR)/rfnoc/Makefile.srcs
|
||||
include $(BASE_DIR)/n3xx/dboards/rh/Makefile.srcs
|
||||
include $(BASE_DIR)/n3xx/dboards/mg/Makefile.srcs
|
||||
include $(BASE_DIR)/n3xx/dboards/common/Makefile.srcs
|
||||
# For sake of convenience, we include the Makefile.srcs for DRAM FIFO, DDC, and
|
||||
# DUC, and of course the radio. Any other block needs to use the
|
||||
# RFNOC_OOT_MAKEFILE_SRCS variable (see below).
|
||||
include $(LIB_DIR)/rfnoc/blocks/rfnoc_block_axi_ram_fifo/Makefile.srcs
|
||||
include $(LIB_DIR)/rfnoc/blocks/rfnoc_block_radio/Makefile.srcs
|
||||
include $(LIB_DIR)/rfnoc/blocks/rfnoc_block_ddc/Makefile.srcs
|
||||
include $(LIB_DIR)/rfnoc/blocks/rfnoc_block_duc/Makefile.srcs
|
||||
# If out-of-tree modules want to be compiled into this image, then they need to
|
||||
# pass in the RFNOC_OOT_MAKEFILE_SRCS as a list of Makefile.srcs files.
|
||||
# Those files need to amend the RFNOC_OOT_SRCS variable with a list of actual
|
||||
# source files.
|
||||
include $(RFNOC_OOT_MAKEFILE_SRCS)
|
||||
|
||||
IMAGE_CORE ?= $(DEFAULT_RFNOC_IMAGE_CORE_FILE)
|
||||
EDGE_FILE ?= $(DEFAULT_EDGE_FILE)
|
||||
|
||||
##################################################
|
||||
# Sources
|
||||
##################################################
|
||||
TOP_SRCS = \
|
||||
n3xx_core.v \
|
||||
n3xx_mgt_channel_wrapper.v \
|
||||
n3xx_mgt_wrapper.v \
|
||||
n3xx_mgt_io_core.v \
|
||||
n3xx_clocking.v \
|
||||
n3xx_db_fe_core.v \
|
||||
WrapBufg.vhd \
|
||||
$(IMAGE_CORE)
|
||||
|
||||
MB_CLOCKS_XDC = $(abspath mb_clocks.xdc)
|
||||
|
||||
MB_XDC = \
|
||||
mb_timing.xdc \
|
||||
mb_pins.xdc
|
||||
|
||||
ifdef BUILD_WR
|
||||
MB_XDC += $(abspath n3xx_wr.xdc)
|
||||
TOP_SRCS += \
|
||||
n3xx_wr_top.vhd \
|
||||
n3xx_serial_dac.vhd \
|
||||
n3xx_serial_dac_arb.vhd
|
||||
endif
|
||||
|
||||
ifdef BUILD_10G
|
||||
MB_XDC += $(abspath n310_10ge.xdc)
|
||||
endif
|
||||
|
||||
ifdef BUILD_1G
|
||||
MB_XDC += $(abspath n310_1ge.xdc)
|
||||
endif
|
||||
|
||||
ifdef BUILD_AURORA
|
||||
MB_XDC += $(abspath n310_aurora.xdc)
|
||||
endif
|
||||
|
||||
ifndef NO_DRAM_FIFOS
|
||||
DRAM_SRCS = $(IP_DRAM_XCI_SRCS) $(abspath n310_dram.xdc)
|
||||
else
|
||||
DRAM_SRCS =
|
||||
endif
|
||||
|
||||
ifdef N300
|
||||
DB_CLOCKS_XDC =
|
||||
DB_SRCS = $(MAGNESIUM_DB_TIMING_XDC) \
|
||||
$(MAGNESIUM_DB0_XDC) \
|
||||
$(MAGNESIUM_TOP_SRCS) $(MAGNESIUM_DB_SRCS)
|
||||
endif
|
||||
|
||||
ifdef N310
|
||||
DB_CLOCKS_XDC =
|
||||
DB_SRCS = $(MAGNESIUM_DB_TIMING_XDC) \
|
||||
$(MAGNESIUM_DB0_XDC) $(MAGNESIUM_DB1_XDC) \
|
||||
$(MAGNESIUM_TOP_SRCS) $(MAGNESIUM_DB_SRCS)
|
||||
endif
|
||||
|
||||
ifdef N320
|
||||
DB_CLOCKS_XDC = $(RHODIUM_DB_CLOCKS_XDC)
|
||||
DB_SRCS = $(RHODIUM_DB_XDC) \
|
||||
$(RHODIUM_TOP_SRCS) $(RHODIUM_DB_SRCS)
|
||||
endif
|
||||
|
||||
DB_SRCS += $(DB_COMMON_SRCS)
|
||||
|
||||
# The XDC files must be read in a specific order, motherboard first and then daughterboard,
|
||||
# and the clocking XDC files must be before other XDC files.
|
||||
# Outside of that, all the other sources can be read in any order desired.
|
||||
DESIGN_SRCS = $(MB_CLOCKS_XDC) $(DB_CLOCKS_XDC) $(abspath $(MB_XDC)) $(DB_SRCS) \
|
||||
$(abspath $(TOP_SRCS)) $(AXI_SRCS) $(FIFO_SRCS) \
|
||||
$(CONTROL_LIB_SRCS) $(SDR_LIB_SRCS) $(SERDES_SRCS) \
|
||||
$(SIMPLE_GEMAC_SRCS) $(TIMING_SRCS) $(COREGEN_DSP_SRCS) \
|
||||
$(UDP_SRCS) $(EXTRAM_SRCS) $(WISHBONE_SRCS) \
|
||||
$(XGE_SRCS) $(XGE_INTERFACE_SRCS) $(AURORA_PHY_SRCS) \
|
||||
$(TEN_GIGE_PHY_SRCS) $(ONE_GIGE_PHY_SRCS) \
|
||||
$(PACKET_PROC_SRCS) $(DSP_SRCS) $(DRAM_SRCS) \
|
||||
$(RADIO_SRCS) $(CAP_GEN_GENERIC_SRCS) $(IP_XCI_SRCS) $(BD_SRCS) \
|
||||
$(RFNOC_SRCS) $(RFNOC_OOT_SRCS) $(LIB_IP_XCI_SRCS) $(LIB_HLS_IP_SRCS) \
|
||||
$(WHITE_RABBIT_SRCS) \
|
||||
$(RFNOC_FRAMEWORK_SRCS) \
|
||||
$(RFNOC_BLOCK_AXI_RAM_FIFO_SRCS) \
|
||||
$(RFNOC_BLOCK_DUC_SRCS) $(RFNOC_BLOCK_DDC_SRCS) \
|
||||
$(RFNOC_BLOCK_RADIO_SRCS)
|
||||
|
||||
EDGE_TBL_DEF="RFNOC_EDGE_TBL_FILE=$(EDGE_FILE)"
|
||||
|
||||
##################################################
|
||||
# Dependency Targets
|
||||
##################################################
|
||||
.SECONDEXPANSION:
|
||||
|
||||
VERILOG_DEFS=$(EXTRA_DEFS) $(CUSTOM_DEFS) $(GIT_HASH_VERILOG_DEF) $(EDGE_TBL_DEF)
|
||||
|
||||
# DESIGN_SRCS and VERILOG_DEFS must be defined
|
||||
bin: .prereqs $$(DESIGN_SRCS) ip
|
||||
$(call BUILD_VIVADO_DESIGN,$(abspath ./build_n3xx.tcl),$(TOP_MODULE),$(ARCH),$(PART_ID))
|
||||
|
||||
synth: .prereqs $$(DESIGN_SRCS) ip
|
||||
$(call BUILD_VIVADO_DESIGN,$(TOOLS_DIR)/scripts/viv_synth.tcl,$(TOP_MODULE),$(ARCH),$(PART_ID))
|
||||
|
||||
rtl: .prereqs $$(DESIGN_SRCS) ip
|
||||
$(call CHECK_VIVADO_DESIGN,$(TOOLS_DIR)/scripts/viv_check_syntax.tcl,$(TOP_MODULE),$(ARCH),$(PART_ID))
|
||||
|
||||
.PHONY: bin rtl
|
||||
@@ -0,0 +1,172 @@
|
||||
--------------------------------------------------------------------------------
|
||||
--
|
||||
-- File: WrapBufg.vhd
|
||||
-- Author: Robert Atkinson
|
||||
-- Original Project: RF-RIO
|
||||
-- Date: 13 January 2012
|
||||
--
|
||||
--------------------------------------------------------------------------------
|
||||
-- Copyright 2012 Ettus Research, A National Instruments Company
|
||||
-- SPDX-License-Identifier: GPL-3.0
|
||||
--------------------------------------------------------------------------------
|
||||
--
|
||||
-- Purpose: This is a simple wrapper around a BUFG to make instantiating BUFGCTRLs
|
||||
-- easier without a headache to relearn the port usage each time. This
|
||||
-- wrapper only supports a single input clock. When disabled, the BUFG
|
||||
-- output is zero.
|
||||
--
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
library UNISIM;
|
||||
use UNISIM.vcomponents.all;
|
||||
|
||||
|
||||
entity WrapBufg is
|
||||
generic(
|
||||
-- ClkIn is selected by default if set to true, otherwise zero.
|
||||
kEnableByDefault : boolean := false;
|
||||
-- If kIgnore is set to true, then the BUFG will switch inputs whenever
|
||||
-- the aCe signal changes as opposed to waiting for ClkIn to transition low.
|
||||
kIgnore : boolean := false;
|
||||
-- If aCe is asynchronous to ClkIn, set this generic to true and the select
|
||||
-- lines of the BUFGCTRL will be used. If aCe is synchronous to ClkIn, then the CE pins
|
||||
-- will be used - note that this requires that setup and hold times be met! If aCe is
|
||||
-- synchronous to ClkIn but no timing relationship is really needed then set this to true.
|
||||
kEnableIsAsync : boolean := false
|
||||
);
|
||||
port(
|
||||
-- Input clock
|
||||
ClkIn : in std_logic;
|
||||
-- Enable to the BUFG - this signal is treated either asynchronously
|
||||
-- or synchronously based on the value of the kEnableIsAsync generic.
|
||||
aCe : in std_logic;
|
||||
-- Clock output
|
||||
ClkOut : out std_logic
|
||||
);
|
||||
end WrapBufg;
|
||||
|
||||
|
||||
architecture rtl of WrapBufg is
|
||||
|
||||
signal iCe0,
|
||||
iCe1,
|
||||
aSel0,
|
||||
aSel1,
|
||||
kIgnore0 : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
-- From Data Sheet:
|
||||
-- The BUFGCTRL is designed to switch between two clock inputs without the possibility of a
|
||||
-- glitch. When the presently selected clock transitions from High to Low after S0 and S1
|
||||
-- changes, the output is kept Low until the other (to-be-selected) clock has transitioned from
|
||||
-- High to Low. Then the new clock starts driving the output. The default configuration for
|
||||
-- BUFGCTRL is falling edge sensitive and held at Low prior to the input switching.
|
||||
-- BUFGCTRL can also be rising edge sensitive and held at High prior to the input switching
|
||||
-- by using the INIT_OUT attribute.
|
||||
-- In some applications the conditions previously described are not desirable. Asserting the
|
||||
-- IGNORE pins will bypass the BUFGCTRL from detecting the conditions for switching
|
||||
-- between two clock inputs. In other words, asserting IGNORE causes the MUX to switch
|
||||
-- the inputs at the instant the select pin changes. IGNORE0 causes the output to switch away
|
||||
-- from the I0 input immediately when the select pin changes, while IGNORE1 causes the
|
||||
-- output to switch away from the I1 input immediately when the select pin changes.
|
||||
-- Selection of an input clock requires a "select" pair (S0 and CE0, or S1 and CE1) to be
|
||||
-- asserted High. If either S or CE is not asserted High, the desired input will not be selected.
|
||||
-- In normal operation, both S and CE pairs (all four select lines) are not expected to be
|
||||
-- asserted High simultaneously. Typically only one pin of a "select" pair is used as a select
|
||||
-- line, while the other pin is tied High.
|
||||
|
||||
-- If the aCe input is async to the I clock, then use the select pins
|
||||
-- of the BUFGCTRL since setup and hold times at the S* pins do not have
|
||||
-- to be met. Enable both Select pins if the aCe signal is synchronous to the I clock.
|
||||
aSel0 <= aCe when kEnableIsAsync else
|
||||
'1';
|
||||
aSel1 <= not aCe when kEnableIsAsync else
|
||||
'1';
|
||||
|
||||
-- Only use the CE pins when the input aCe signal is synchronous to the I clock.
|
||||
iCe0 <= '1' when kEnableIsAsync else
|
||||
aCe;
|
||||
iCe1 <= '1' when kEnableIsAsync else
|
||||
not aCe;
|
||||
|
||||
-- No PkgNiUtilities for me.
|
||||
kIgnore0 <= '1' when kIgnore else
|
||||
'0';
|
||||
|
||||
--vhook_i BUFGCTRL GlobalBuffer
|
||||
--vhook_a {^IS_(.*)} '0'
|
||||
--vhook_a INIT_OUT 0
|
||||
--vhook_a PRESELECT_I0 kEnableByDefault
|
||||
--vhook_a PRESELECT_I1 not kEnableByDefault
|
||||
--vhook_a O ClkOut
|
||||
--vhook_a CE0 iCe0
|
||||
--vhook_a CE1 iCe1
|
||||
--vhook_a I0 ClkIn
|
||||
--vhook_a I1 '0'
|
||||
--vhook_a IGNORE0 kIgnore0
|
||||
--vhook_a IGNORE1 '1'
|
||||
--vhook_a S0 aSel0
|
||||
--vhook_a S1 aSel1
|
||||
GlobalBuffer: BUFGCTRL
|
||||
generic map (
|
||||
INIT_OUT => 0, --integer:=0
|
||||
IS_CE0_INVERTED => '0', --bit:='0'
|
||||
IS_CE1_INVERTED => '0', --bit:='0'
|
||||
IS_I0_INVERTED => '0', --bit:='0'
|
||||
IS_I1_INVERTED => '0', --bit:='0'
|
||||
IS_IGNORE0_INVERTED => '0', --bit:='0'
|
||||
IS_IGNORE1_INVERTED => '0', --bit:='0'
|
||||
IS_S0_INVERTED => '0', --bit:='0'
|
||||
IS_S1_INVERTED => '0', --bit:='0'
|
||||
PRESELECT_I0 => kEnableByDefault, --boolean:=false
|
||||
PRESELECT_I1 => not kEnableByDefault) --boolean:=false
|
||||
port map (
|
||||
O => ClkOut, --out std_ulogic
|
||||
CE0 => iCe0, --in std_ulogic
|
||||
CE1 => iCe1, --in std_ulogic
|
||||
I0 => ClkIn, --in std_ulogic
|
||||
I1 => '0', --in std_ulogic
|
||||
IGNORE0 => kIgnore0, --in std_ulogic
|
||||
IGNORE1 => '1', --in std_ulogic
|
||||
S0 => aSel0, --in std_ulogic
|
||||
S1 => aSel1); --in std_ulogic
|
||||
|
||||
|
||||
--vscan Begin Add Explain Clock
|
||||
--vscan # These are the outputs of the BUFGCTRLs in the WrapBufg module. VScan
|
||||
--vscan # sees the output as glitchy but the clocks are guaranteed to switch
|
||||
--vscan # in a glitchless fashion provided that either setup and hold times
|
||||
--vscan # are met at the CE pins of the BUFGCTRL (these paths are analyzed by the
|
||||
--vscan # tools for timing) or the CE pins are hardwired and the S pins are used
|
||||
--vscan # which require no timing relationship to the input clocks.
|
||||
--vscan *[WrapBufg]GlobalBuffer/[BUFGCTRL]O
|
||||
--vscan End Add Explain Clock
|
||||
|
||||
|
||||
-- Check that enable lines match up with the generics of the BUFGCTRL
|
||||
--vscan vscan_off
|
||||
--synthesis translate_off
|
||||
SimProcess: process
|
||||
begin
|
||||
wait for 1 ns;
|
||||
if kEnableIsAsync then
|
||||
assert kEnableByDefault = (aSel0 = '1')
|
||||
report "Initial condition on enable lines do not match between" & LF
|
||||
& "the BUFGCTRL generic and the SEL line"
|
||||
severity error;
|
||||
else
|
||||
assert kEnableByDefault = (iCe0 = '1')
|
||||
report "Initial condition on enable lines do not match between" & LF
|
||||
& "the BUFGCTRL generic and the CE line"
|
||||
severity error;
|
||||
end if;
|
||||
wait;
|
||||
end process SimProcess;
|
||||
--synthesis translate_on
|
||||
--vscan vscan_on
|
||||
|
||||
end rtl;
|
||||
@@ -0,0 +1,39 @@
|
||||
#
|
||||
# Copyright 2016 Ettus Research
|
||||
#
|
||||
|
||||
source $::env(VIV_TOOLS_DIR)/scripts/viv_utils.tcl
|
||||
source $::env(VIV_TOOLS_DIR)/scripts/viv_strategies.tcl
|
||||
|
||||
# STEP#1: Create project, add sources, refresh IP
|
||||
vivado_utils::initialize_project
|
||||
|
||||
# STEP#2: Run synthesis
|
||||
vivado_utils::synthesize_design
|
||||
vivado_utils::generate_post_synth_reports
|
||||
|
||||
# STEP#3: Run implementation strategy
|
||||
set n3xx_strategy [dict create]
|
||||
dict set n3xx_strategy "opt_design.is_enabled" 1
|
||||
dict set n3xx_strategy "opt_design.directive" "NoBramPowerOpt"
|
||||
dict set n3xx_strategy "post_opt_power_opt_design.is_enabled" 0
|
||||
dict set n3xx_strategy "place_design.directive" "ExtraNetDelay_high"
|
||||
dict set n3xx_strategy "post_place_power_opt_design.is_enabled" 0
|
||||
dict set n3xx_strategy "post_place_phys_opt_design.is_enabled" 1
|
||||
dict set n3xx_strategy "post_place_phys_opt_design.directive" "AggressiveExplore"
|
||||
dict set n3xx_strategy "route_design.directive" "Explore"
|
||||
dict set n3xx_strategy "route_design.more_options" "-tns_cleanup"
|
||||
dict set n3xx_strategy "post_route_phys_opt_design.is_enabled" 1
|
||||
dict set n3xx_strategy "post_route_phys_opt_design.directive" "Explore"
|
||||
vivado_strategies::implement_design $n3xx_strategy
|
||||
|
||||
# STEP#4: Generate reports
|
||||
vivado_utils::generate_post_route_reports
|
||||
|
||||
# STEP#5: Generate a bitstream, netlist and debug probes
|
||||
set_property BITSTREAM.CONFIG.USR_ACCESS TIMESTAMP [get_designs *]
|
||||
set byte_swap_bin 1
|
||||
vivado_utils::write_implementation_outputs $byte_swap_bin
|
||||
|
||||
# Cleanup
|
||||
vivado_utils::close_batch_project
|
||||
@@ -0,0 +1,4 @@
|
||||
_xmsgs
|
||||
*.log
|
||||
*.ncf
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
fir_compiler_v5_0
|
||||
@@ -0,0 +1,17 @@
|
||||
#
|
||||
# Copyright 2012 Ettus Research LLC
|
||||
#
|
||||
|
||||
##################################################
|
||||
# Coregen Sources
|
||||
##################################################
|
||||
|
||||
COREGEN_DSP_SRCS = $(abspath $(addprefix $(BASE_DIR)/../top/n3xx/coregen_dsp/, \
|
||||
hbdec1.v \
|
||||
hbdec1.ngc \
|
||||
hbdec2.v \
|
||||
hbdec2.ngc \
|
||||
hbdec3.v \
|
||||
hbdec3.ngc \
|
||||
))
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,18 @@
|
||||
#
|
||||
# Copyright 2018 Ettus Research, a National Instruments Company
|
||||
#
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
#
|
||||
|
||||
##################################################
|
||||
# DB COMMON Sources
|
||||
##################################################
|
||||
DB_COMMON_SRCS = $(abspath $(addprefix $(BASE_DIR)/n3xx/dboards/common/, \
|
||||
PkgRegs.vhd \
|
||||
sync/CrossTrigger.vhd \
|
||||
sync/Pulser.vhd \
|
||||
sync/TdcTop.vhd \
|
||||
sync/TdcWrapper.vhd \
|
||||
sync/TdcCore.edf \
|
||||
sync/SyncRegsIfc.edf \
|
||||
))
|
||||
@@ -0,0 +1,314 @@
|
||||
--
|
||||
-- Copyright 2018 Ettus Research, a National Instruments Company
|
||||
--
|
||||
-- SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
--
|
||||
-- This package contains functions for reading and writing N310 registers.
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
|
||||
package PkgRegs is
|
||||
|
||||
|
||||
-- RegPort Type Definitions : ---------------------------------------------------------
|
||||
-- ------------------------------------------------------------------------------------
|
||||
|
||||
constant kAddressWidth : integer := 16;
|
||||
|
||||
subtype InterfaceData_t is std_logic_vector(31 downto 0);
|
||||
type RegDataAry_t is array (natural range <>) of InterfaceData_t;
|
||||
constant kRegPortDataZero : InterfaceData_t := (others => '0');
|
||||
|
||||
-- The type of the signal used to communicate from the Interface
|
||||
-- component to the frameworks
|
||||
type RegPortIn_t is record
|
||||
Address : unsigned(kAddressWidth - 1 downto 0);
|
||||
Data : InterfaceData_t;
|
||||
Rd : boolean; -- Must be a one clock cycle pulse
|
||||
Wt : boolean; -- Must be a one clock cycle pulse
|
||||
end record;
|
||||
|
||||
-- The type of the signal used to communicate to the Interface
|
||||
-- component from the frameworks
|
||||
-- Ready is just the Ready signal from the Handshake component.
|
||||
-- Address in RegPortIn_t should be valid in the cycle where Data, DataValid,
|
||||
-- or Ready are being sampled by the bus communication interface.
|
||||
type RegPortOut_t is record
|
||||
Data : InterfaceData_t;
|
||||
DataValid : boolean; -- Must be a one clock cycle pulse
|
||||
Ready : boolean; -- Must be valid one clock after Wt assertion
|
||||
end record;
|
||||
|
||||
-- Constants for the RegPort
|
||||
constant kRegPortInZero : RegPortIn_t := (
|
||||
Address => to_unsigned(0,kAddressWidth),
|
||||
Data => (others => '0'),
|
||||
Rd => false,
|
||||
Wt => false);
|
||||
|
||||
constant kRegPortOutZero : RegPortOut_t := (
|
||||
Data => (others=>'0'),
|
||||
DataValid => false,
|
||||
Ready => true);
|
||||
|
||||
|
||||
|
||||
-- Register Offset Types : ------------------------------------------------------------
|
||||
-- ------------------------------------------------------------------------------------
|
||||
|
||||
-- Custom type for defining register spaces. Is it assumed that all defined register
|
||||
-- addresses for each space are kOffset <= Address < kOffset+kWidth. Therefore when
|
||||
-- Address equals kOffset+kWidth, we are not talking to this space but the space
|
||||
-- above it.
|
||||
type RegOffset_t is record
|
||||
kOffset : integer;
|
||||
kWidth : integer;
|
||||
end record;
|
||||
|
||||
constant kRegOffsetZero : RegOffset_t := (kOffset => 16#0#, kWidth => 16#04#);
|
||||
|
||||
|
||||
|
||||
-- Access Functions : -----------------------------------------------------------------
|
||||
-- ------------------------------------------------------------------------------------
|
||||
|
||||
-- Helper function to combine register ports on their way back upstream.
|
||||
function "+" (L, R : RegPortOut_t) return RegPortOut_t;
|
||||
|
||||
function Mask(RegPortIn : in RegPortIn_t;
|
||||
kRegisterOffset : in RegOffset_t) return RegPortIn_t;
|
||||
|
||||
-- Helper functions to determine when a register is targeted by the RegPort. There
|
||||
-- are three groups: RegSelected, RegWrite, and RegRead. The latter two call
|
||||
-- RegSelected to determine if a register is targeted and being read or written.
|
||||
-- RegSelected is also overloaded to accommodate the RegOffset_t type.
|
||||
-- function RegSelected (RegPortIn : RegPortIn_t;
|
||||
-- RegisterOffset : RegOffset_t) return boolean;
|
||||
function RegSelected (RegOffset : integer;
|
||||
RegPortIn : RegPortIn_t) return boolean;
|
||||
function RegWrite (Address : integer;
|
||||
RegPortIn : RegPortIn_t) return boolean;
|
||||
function RegRead (Address : integer;
|
||||
RegPortIn : RegPortIn_t) return boolean;
|
||||
|
||||
function OrArray(ArrayIn : RegDataAry_t) return std_logic_vector;
|
||||
|
||||
|
||||
|
||||
|
||||
-- Flattening Functions : -------------------------------------------------------------
|
||||
-- ------------------------------------------------------------------------------------
|
||||
|
||||
constant kFlatRegPortInSize : natural := kAddressWidth +
|
||||
InterfaceData_t'length +
|
||||
2;
|
||||
|
||||
subtype FlatRegPortIn_t is std_logic_vector(kFlatRegPortInSize-1 downto 0);
|
||||
|
||||
constant kFlatRegPortOutSize : natural := InterfaceData_t'length +
|
||||
2;
|
||||
|
||||
subtype FlatRegPortOut_t is std_logic_vector(kFlatRegPortOutSize-1 downto 0);
|
||||
|
||||
function Flatten(Var : RegPortIn_t) return FlatRegPortIn_t;
|
||||
function Unflatten(Var : FlatRegPortIn_t) return RegPortIn_t;
|
||||
|
||||
function Flatten(Var : RegPortOut_t) return FlatRegPortOut_t;
|
||||
function Unflatten(Var : FlatRegPortOut_t) return RegPortOut_t;
|
||||
|
||||
|
||||
|
||||
|
||||
end PkgRegs;
|
||||
|
||||
|
||||
package body PkgRegs is
|
||||
|
||||
-- Combines RegPortOut_t types together
|
||||
function "+" (L, R : RegPortOut_t) return RegPortOut_t
|
||||
is
|
||||
variable ReturnVal : RegPortOut_t;
|
||||
begin
|
||||
ReturnVal := kRegPortOutZero;
|
||||
ReturnVal.Data := L.Data or R.Data;
|
||||
ReturnVal.DataValid := L.DataValid or R.DataValid;
|
||||
ReturnVal.Ready := L.Ready and R.Ready;
|
||||
return ReturnVal;
|
||||
end function;
|
||||
|
||||
|
||||
-- This function lops off the portion of the register bus that is
|
||||
-- decoded in the InAddrSpace function in order to reduce the number of bits
|
||||
-- decoded by the register read logic. Also, the Rd and Wt strobes are gated
|
||||
-- as well.
|
||||
function Mask(RegPortIn : in RegPortIn_t;
|
||||
kRegisterOffset : in RegOffset_t) return RegPortIn_t
|
||||
is
|
||||
variable RegPortInVar : RegPortIn_t;
|
||||
variable InSpace : boolean := false;
|
||||
begin
|
||||
|
||||
InSpace := (RegPortIn.Address >= kRegisterOffset.kOffset) and
|
||||
(RegPortIn.Address < kRegisterOffset.kOffset + kRegisterOffset.kWidth);
|
||||
|
||||
-- Compare the most significant bits of the address bus downto the LSb
|
||||
-- that we just calculated.
|
||||
if InSpace then
|
||||
-- If in address space then allow Rd and Wt to assert
|
||||
RegPortInVar.Rd := RegPortIn.Rd;
|
||||
RegPortInVar.Wt := RegPortIn.Wt;
|
||||
else
|
||||
RegPortInVar.Rd := kRegPortInZero.Rd;
|
||||
RegPortInVar.Wt := kRegPortInZero.Wt;
|
||||
end if;
|
||||
|
||||
RegPortInVar.Data := RegPortIn.Data;
|
||||
RegPortInVar.Address := RegPortIn.Address - kRegisterOffset.kOffset;
|
||||
return RegPortInVar;
|
||||
end function Mask;
|
||||
|
||||
|
||||
-- Returns true when this chip is selected and the address matches the register.
|
||||
-- Note that RegOffset is divided by 4 before being compared against the register
|
||||
-- port Address value.
|
||||
function RegSelected (RegOffset : integer;
|
||||
RegPortIn : RegPortIn_t) return boolean is
|
||||
begin
|
||||
return RegPortIn.Address = to_unsigned(RegOffset, RegPortIn.Address'length);
|
||||
end function RegSelected;
|
||||
|
||||
-- Returns true when the register is being written.
|
||||
function RegWrite (Address : integer;
|
||||
RegPortIn : RegPortIn_t) return boolean is
|
||||
begin
|
||||
return RegSelected(Address, RegPortIn) and RegPortIn.Wt;
|
||||
end function RegWrite;
|
||||
|
||||
-- Returns true when the register is being read.
|
||||
function RegRead (Address : integer;
|
||||
RegPortIn : RegPortIn_t) return boolean is
|
||||
begin
|
||||
return RegSelected(Address, RegPortIn) and RegPortIn.Rd;
|
||||
end function RegRead;
|
||||
|
||||
-- Overloaded version of RegSelected for the RegOffset_t
|
||||
-- NOTE!!! Offset <= Address < Offset+Width
|
||||
-- Therefore, this function assumes that when Address = Offset+Width we are talking to
|
||||
-- a different register group than the one given in RegisterOffset.
|
||||
-- function RegSelected (RegPortIn : RegPortIn_t;
|
||||
-- RegisterOffset : RegOffset_t) return boolean is
|
||||
-- begin
|
||||
-- return (RegPortIn.Address >= to_unsigned(RegisterOffset.kOffset, RegPortIn.Address'length)) and
|
||||
-- (RegPortIn.Address < to_unsigned(RegisterOffset.kOffset + RegisterOffset.kWidth, RegPortIn.Address'length));
|
||||
-- end function RegSelected;
|
||||
|
||||
function OrArray(ArrayIn : RegDataAry_t) return std_logic_vector
|
||||
is
|
||||
variable ReturnVar : std_logic_vector(ArrayIn(ArrayIn'right)'range);
|
||||
begin
|
||||
ReturnVar := (others => '0');
|
||||
for i in ArrayIn'range loop
|
||||
ReturnVar := ReturnVar or ArrayIn(i);
|
||||
end loop;
|
||||
return ReturnVar;
|
||||
end function OrArray;
|
||||
|
||||
|
||||
function to_Boolean (s : std_ulogic) return boolean is
|
||||
begin
|
||||
return (To_X01(s)='1');
|
||||
end to_Boolean;
|
||||
|
||||
function to_StdLogic(b : boolean) return std_ulogic is
|
||||
begin
|
||||
if b then
|
||||
return '1';
|
||||
else
|
||||
return '0';
|
||||
end if;
|
||||
end to_StdLogic;
|
||||
|
||||
|
||||
|
||||
-----------------------------------------------------
|
||||
-- REG PORTS (FROM PkgCommunicationInterface)
|
||||
--
|
||||
-- subtype InterfaceData_t is std_logic_vector(31 downto 0);
|
||||
--
|
||||
-- constant kAddressWidth : positive := kAddressWidth - 2;
|
||||
--
|
||||
-- type RegPortIn_t is record
|
||||
-- Address : unsigned(kAddressWidth - 1 downto 0);
|
||||
-- Data : InterfaceData_t;
|
||||
-- Rd : boolean; -- Must be a one clock cycle pulse
|
||||
-- Wt : boolean; -- Must be a one clock cycle pulse
|
||||
-- end record;
|
||||
|
||||
function Flatten(Var : RegPortIn_t) return FlatRegPortIn_t is
|
||||
variable Index : natural;
|
||||
variable RetVar : FlatRegPortIn_t;
|
||||
begin
|
||||
Index := 0;
|
||||
RetVar(Index) := to_StdLogic(Var.Wt); Index := Index + 1;
|
||||
RetVar(Index) := to_StdLogic(Var.Rd); Index := Index + 1;
|
||||
RetVar(Index + Var.Data'length - 1 downto Index) := std_logic_vector(Var.Data);
|
||||
Index := Index + Var.Data'length;
|
||||
RetVar(Index + Var.Address'length - 1 downto Index) := std_logic_vector(Var.Address);
|
||||
Index := Index + Var.Address'length;
|
||||
|
||||
return RetVar;
|
||||
end function Flatten;
|
||||
|
||||
function Unflatten(Var : FlatRegPortIn_t) return RegPortIn_t is
|
||||
variable Index : natural;
|
||||
variable RetVal : RegPortIn_t;
|
||||
begin
|
||||
Index := 0;
|
||||
RetVal.Wt := to_Boolean(Var(Index)); Index := Index + 1;
|
||||
RetVal.Rd := to_Boolean(Var(Index)); Index := Index + 1;
|
||||
RetVal.Data := InterfaceData_t(Var(Index + RetVal.Data'length - 1 downto Index));
|
||||
Index := Index + RetVal.Data'length;
|
||||
RetVal.Address := unsigned(Var(Index + RetVal.Address'length - 1 downto Index));
|
||||
Index := Index + RetVal.Address'length;
|
||||
|
||||
return RetVal;
|
||||
end function Unflatten;
|
||||
|
||||
-- type RegPortOut_t is record
|
||||
-- Data : InterfaceData_t;
|
||||
-- DataValid : boolean; -- Must be a one clock cycle pulse
|
||||
-- Ready : boolean; -- Must be valid one clock after Wt assertion
|
||||
-- end record;
|
||||
|
||||
function Flatten(Var : RegPortOut_t) return FlatRegPortOut_t is
|
||||
variable Index : natural;
|
||||
variable RetVar : FlatRegPortOut_t;
|
||||
begin
|
||||
Index := 0;
|
||||
RetVar(Index) := to_StdLogic(Var.Ready); Index := Index + 1;
|
||||
RetVar(Index) := to_StdLogic(Var.DataValid); Index := Index + 1;
|
||||
RetVar(Index + Var.Data'length - 1 downto Index) := std_logic_vector(Var.Data);
|
||||
Index := Index + Var.Data'length;
|
||||
|
||||
return RetVar;
|
||||
end function Flatten;
|
||||
|
||||
function Unflatten(Var : FlatRegPortOut_t) return RegPortOut_t is
|
||||
variable Index : natural;
|
||||
variable RetVal : RegPortOut_t;
|
||||
begin
|
||||
Index := 0;
|
||||
RetVal.Ready := to_Boolean(Var(Index)); Index := Index + 1;
|
||||
RetVal.DataValid := to_Boolean(Var(Index)); Index := Index + 1;
|
||||
RetVal.Data := InterfaceData_t(Var(Index + RetVal.Data'length - 1 downto Index));
|
||||
Index := Index + RetVal.Data'length;
|
||||
|
||||
return RetVal;
|
||||
end function Unflatten;
|
||||
|
||||
|
||||
|
||||
end PkgRegs;
|
||||
@@ -0,0 +1,414 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright 2018 Ettus Research, a National Instruments Company
|
||||
--
|
||||
-- SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
--
|
||||
--
|
||||
-- Purpose:
|
||||
--
|
||||
-- Uses the RP and SP edges to cross a trigger from the RefClk domain to
|
||||
-- the SampleClk domain. The RP FE captures the input trigger and sends it to
|
||||
-- the SampleClk domain. There, it is double-synchronized but only allowed to pass
|
||||
-- when the SP RE occurs. The trigger (now in the SampleClk domain) is then passed
|
||||
-- through an elastic buffer before being sent on it's merry way.
|
||||
--
|
||||
-- Below is the latency through this module. If you assert rTriggerIn before or after
|
||||
-- the rRP RE, then you need to add/subtract the distance to the rRP RE.
|
||||
--
|
||||
-- Deterministic latency through this module is (starting at the rRP RE):
|
||||
-- Measured difference between rRP and sSP rising edges (using a TDC, positive value
|
||||
-- if rRP rises before sSP).
|
||||
-- + One period of sSP
|
||||
-- + Two periods of SampleClk (Double Sync)
|
||||
-- + (sElasticBufferPtr value + 1) * SampleClk Period
|
||||
-- + One period of SampleClk
|
||||
--
|
||||
-- How much skew between RP and SP can we allow and still safely pass triggers?
|
||||
-- Our "launch" edge is essentially the RP FE, and our "latch" edge is the SP RE.
|
||||
-- Consider the no skew (RP and SP edges align) case first. Our setup and hold budget
|
||||
-- is balanced at T/2. Based on this, it seems we can tolerate almost T/2 skew in either
|
||||
-- direction (ignoring a few Reference and Sample Clock cycles here and there).
|
||||
-- My recommendation is to keep the skew to a minimum, like less than T/4.
|
||||
-- In the context of the FTDC project for N310, this should be a no-brainer since
|
||||
-- the SP pulses are started only a few RefClk cycles after RP. The skew is
|
||||
-- easily verified by taking a FTDC measurement. If the skew is less than T/4, you can
|
||||
-- sleep easy. If not, then I recommend doing a comprehensive analysis of how much
|
||||
-- settling time you have between the trigger being launched from the RefClk domain
|
||||
-- and latched in the SampleClk domain.
|
||||
--
|
||||
-- vreview_group Tdc
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library unisim;
|
||||
use unisim.vcomponents.all;
|
||||
|
||||
|
||||
entity CrossTrigger is
|
||||
port (
|
||||
aReset : in boolean;
|
||||
|
||||
RefClk : in std_logic;
|
||||
-- For convenience while writing this, I have only considered the N3x0 case where
|
||||
-- rRP is slightly ahead of sSP in phase.
|
||||
rRP : in boolean;
|
||||
-- De-asserts the clock cycle after rTriggerIn asserts. Re-asserts after the
|
||||
-- second falling edge of rRP, indicating new triggers can be accepted.
|
||||
rReadyForInput : out boolean;
|
||||
-- Only one pulse will be output for each rising edge of rTriggerIn. rTriggerIn is
|
||||
-- ignored when rReadyForInput is de-asserted. All levels are ignored when Enable
|
||||
-- is de-asserted.
|
||||
rEnableTrigger : in boolean;
|
||||
rTriggerIn : in boolean;
|
||||
|
||||
SampleClk : in std_logic;
|
||||
sSP : in boolean;
|
||||
-- An elastic buffer just before the output is used to compensate for skew
|
||||
-- in sSP pulses across boards. Default should be in the middle of the 4 bit
|
||||
-- range at 7.
|
||||
sElasticBufferPtr : in unsigned(3 downto 0);
|
||||
-- Single-cycle pulse output.
|
||||
sTriggerOut : out boolean
|
||||
);
|
||||
end CrossTrigger;
|
||||
|
||||
|
||||
architecture rtl of CrossTrigger is
|
||||
|
||||
--vhook_sigstart
|
||||
--vhook_sigend
|
||||
|
||||
signal rRpFE,
|
||||
rRpDly,
|
||||
rTriggerToSClk,
|
||||
rTriggerCaptured,
|
||||
sSpRE,
|
||||
sSpDly : boolean;
|
||||
|
||||
signal sTriggerBuffer : unsigned(2**sElasticBufferPtr'length-1 downto 0);
|
||||
signal sTriggerInSClk, sTriggerInSClk_ms : boolean;
|
||||
|
||||
function to_StdLogic(b : boolean) return std_ulogic is
|
||||
begin
|
||||
if b then
|
||||
return '1';
|
||||
else
|
||||
return '0';
|
||||
end if;
|
||||
end to_StdLogic;
|
||||
|
||||
function to_Boolean (s : std_ulogic) return boolean is
|
||||
begin
|
||||
return (To_X01(s)='1');
|
||||
end to_Boolean;
|
||||
|
||||
attribute async_reg : string;
|
||||
attribute async_reg of sTriggerInSClk : signal is "TRUE";
|
||||
attribute async_reg of sTriggerInSClk_ms : signal is "TRUE";
|
||||
|
||||
begin
|
||||
|
||||
-- Reference Clock Domain Trigger Capture : -------------------------------------------
|
||||
-- The trigger input is captured whenever it is high. The captured value is reset
|
||||
-- by the falling edge of rRP.
|
||||
-- ------------------------------------------------------------------------------------
|
||||
|
||||
rRpFE <= rRpDly and not rRP;
|
||||
|
||||
CaptureTrigger : process(aReset, RefClk)
|
||||
begin
|
||||
if aReset then
|
||||
rTriggerCaptured <= false;
|
||||
rRpDly <= false;
|
||||
elsif rising_edge(RefClk) then
|
||||
rRpDly <= rRP;
|
||||
if not rEnableTrigger then
|
||||
rTriggerCaptured <= false;
|
||||
elsif rTriggerIn then
|
||||
-- Capture trigger whenever the input is asserted (so this will work with single
|
||||
-- cycle and multi-cycle pulses).
|
||||
rTriggerCaptured <= true;
|
||||
elsif rRpFE then
|
||||
-- Reset the captured trigger one cycle after the rRP FE.
|
||||
rTriggerCaptured <= false;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
-- Send Trigger To Sample Clock Domain : ----------------------------------------------
|
||||
-- Send the captured trigger on the falling edge of rRP.
|
||||
-- ------------------------------------------------------------------------------------
|
||||
SendTrigger : process(aReset, RefClk)
|
||||
begin
|
||||
if aReset then
|
||||
rTriggerToSClk <= false;
|
||||
elsif rising_edge(RefClk) then
|
||||
if not rEnableTrigger then
|
||||
rTriggerToSClk <= false;
|
||||
elsif rRpFE then
|
||||
rTriggerToSClk <= rTriggerCaptured;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
rReadyForInput <= not (rTriggerToSClk or rTriggerCaptured);
|
||||
|
||||
-- Capture Trigger in Sample Clock Domain : -------------------------------------------
|
||||
-- On the rising edge of sSP, capture the trigger. To keep things free of
|
||||
-- metastability, we double-sync the trigger into the SampleClk domain first.
|
||||
-- ------------------------------------------------------------------------------------
|
||||
|
||||
ReceiveAndProcessTrigger : process(aReset, SampleClk)
|
||||
begin
|
||||
if aReset then
|
||||
sSpDly <= false;
|
||||
sTriggerBuffer <= (others => '0');
|
||||
sTriggerOut <= false;
|
||||
sTriggerInSClk_ms <= false;
|
||||
sTriggerInSClk <= false;
|
||||
elsif rising_edge(SampleClk) then
|
||||
-- Edge detector delays.
|
||||
sSpDly <= sSP;
|
||||
|
||||
-- Double-synchronizer for trigger.
|
||||
sTriggerInSClk_ms <= rTriggerToSClk;
|
||||
sTriggerInSClk <= sTriggerInSClk_ms;
|
||||
|
||||
-- Delay chain for the elastic buffer. Move to the left people! Note that this
|
||||
-- operation incurs at least one cycle of delay. Also note the trigger input is
|
||||
-- gated with the SP RE.
|
||||
sTriggerBuffer <= sTriggerBuffer(sTriggerBuffer'high-1 downto 0) &
|
||||
to_stdlogic(sTriggerInSClk and sSpRE);
|
||||
|
||||
-- Based on the buffer pointer value select and flop the output one more time.
|
||||
sTriggerOut <= to_boolean(sTriggerBuffer(to_integer(sElasticBufferPtr)));
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Rising edge detectors.
|
||||
sSpRE <= sSP and not sSpDly;
|
||||
|
||||
|
||||
end rtl;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Testbench for CrossTrigger
|
||||
--
|
||||
-- Meh coverage on the triggers so far... but this tests general operation
|
||||
-- and latency.
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
--synopsys translate_off
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity tb_CrossTrigger is end tb_CrossTrigger;
|
||||
|
||||
architecture test of tb_CrossTrigger is
|
||||
|
||||
-- Sets up a 1.25 MHz period.
|
||||
constant kClksPerPulseMaxBits: integer := 10;
|
||||
constant kRpPeriodInRClks : integer := 8;
|
||||
constant kRpHighTimeInRClks : integer := 4;
|
||||
constant kSpPeriodInRClks : integer := 100;
|
||||
constant kSpHighTimeInRClks : integer := 50;
|
||||
|
||||
--vhook_sigstart
|
||||
signal aReset: boolean;
|
||||
signal RefClk: std_logic := '0';
|
||||
signal rEnablePulser: boolean;
|
||||
signal rEnableTrigger: boolean;
|
||||
signal rReadyForInput: boolean;
|
||||
signal rRP: boolean;
|
||||
signal rTriggerIn: boolean;
|
||||
signal SampleClk: std_logic := '0';
|
||||
signal sElasticBufferPtr: unsigned(3 downto 0);
|
||||
signal sEnablePulser: boolean;
|
||||
signal sSP: boolean;
|
||||
signal sTriggerOut: boolean;
|
||||
--vhook_sigend
|
||||
|
||||
signal StopSim : boolean;
|
||||
-- shared variable Rand : Random_t;
|
||||
constant kSPer : time := 8.000 ns; -- 125.00 MHz
|
||||
constant kRPer : time := 100.000 ns; -- 10.00 MHz
|
||||
|
||||
signal rRfiExpected: boolean:= true;
|
||||
signal sTriggerOutExpected: boolean:= false;
|
||||
|
||||
procedure ClkWait(
|
||||
signal Clk : in std_logic;
|
||||
X : positive := 1) is
|
||||
begin
|
||||
for i in 1 to X loop
|
||||
wait until rising_edge(Clk);
|
||||
end loop;
|
||||
end procedure ClkWait;
|
||||
|
||||
begin
|
||||
|
||||
SampleClk <= not SampleClk after kSPer/2 when not StopSim else '0';
|
||||
RefClk <= not RefClk after kRPer/2 when not StopSim else '0';
|
||||
|
||||
--vhook_e Pulser RpPulser
|
||||
--vhook_a Clk RefClk
|
||||
--vhook_a cLoadLimits true
|
||||
--vhook_a cPeriod to_unsigned(kRpPeriodInRClks,kClksPerPulseMaxBits)
|
||||
--vhook_a cHighTime to_unsigned(kRpHighTimeInRClks,kClksPerPulseMaxBits)
|
||||
--vhook_a cEnablePulse rEnablePulser
|
||||
--vhook_a cPulse rRP
|
||||
RpPulser: entity work.Pulser (rtl)
|
||||
generic map (kClksPerPulseMaxBits => kClksPerPulseMaxBits) --integer range 3:32 :=16
|
||||
port map (
|
||||
aReset => aReset, --in boolean
|
||||
Clk => RefClk, --in std_logic
|
||||
cLoadLimits => true, --in boolean
|
||||
cPeriod => to_unsigned(kRpPeriodInRClks,kClksPerPulseMaxBits), --in unsigned(kClksPerPulseMaxBits-1:0)
|
||||
cHighTime => to_unsigned(kRpHighTimeInRClks,kClksPerPulseMaxBits), --in unsigned(kClksPerPulseMaxBits-1:0)
|
||||
cEnablePulse => rEnablePulser, --in boolean
|
||||
cPulse => rRP); --out boolean
|
||||
|
||||
--vhook_e Pulser SpPulser
|
||||
--vhook_a Clk SampleClk
|
||||
--vhook_a cLoadLimits true
|
||||
--vhook_a cPeriod to_unsigned(kSpPeriodInRClks,kClksPerPulseMaxBits)
|
||||
--vhook_a cHighTime to_unsigned(kSpHighTimeInRClks,kClksPerPulseMaxBits)
|
||||
--vhook_a cEnablePulse sEnablePulser
|
||||
--vhook_a cPulse sSP
|
||||
SpPulser: entity work.Pulser (rtl)
|
||||
generic map (kClksPerPulseMaxBits => kClksPerPulseMaxBits) --integer range 3:32 :=16
|
||||
port map (
|
||||
aReset => aReset, --in boolean
|
||||
Clk => SampleClk, --in std_logic
|
||||
cLoadLimits => true, --in boolean
|
||||
cPeriod => to_unsigned(kSpPeriodInRClks,kClksPerPulseMaxBits), --in unsigned(kClksPerPulseMaxBits-1:0)
|
||||
cHighTime => to_unsigned(kSpHighTimeInRClks,kClksPerPulseMaxBits), --in unsigned(kClksPerPulseMaxBits-1:0)
|
||||
cEnablePulse => sEnablePulser, --in boolean
|
||||
cPulse => sSP); --out boolean
|
||||
|
||||
|
||||
main: process
|
||||
procedure SendTrigger is
|
||||
begin
|
||||
assert rReadyForInput
|
||||
report "RFI isn't high, so we can't issue a trigger" severity error;
|
||||
|
||||
-- Give it some action. We need to ideally test this for every phase offset of
|
||||
-- rTriggerIn with respect to the rising edge of rRP, but let's get to that later.
|
||||
-- For now, wait until a rising edge on rRP and then wait for most of the period
|
||||
-- to issue the trigger.
|
||||
wait until rRP and not rRP'delayed;
|
||||
wait for (kRpPeriodInRClks-3)*kRPer;
|
||||
rTriggerIn <= true;
|
||||
ClkWait(RefClk);
|
||||
rTriggerIn <= false;
|
||||
rRfiExpected <= false;
|
||||
|
||||
-- At this point, we wait until a sSP RE, plus two SampleClks, plus sElasticBufferPtr
|
||||
-- plus 1 worth of SampleClks, plus one more SampleClk, and then the trigger
|
||||
-- should appear.
|
||||
wait until not rRP and rRP'delayed;
|
||||
wait until sSP and not sSP'delayed;
|
||||
ClkWait(SampleClk,1);
|
||||
ClkWait(SampleClk, to_integer(sElasticBufferPtr)+1);
|
||||
sTriggerOutExpected <= true;
|
||||
ClkWait(SampleClk,1);
|
||||
sTriggerOutExpected <= false;
|
||||
wait until not rRP and rRP'delayed;
|
||||
ClkWait(RefClk,1);
|
||||
rRfiExpected <= true;
|
||||
end procedure SendTrigger;
|
||||
|
||||
begin
|
||||
rEnablePulser <= false;
|
||||
sEnablePulser <= false;
|
||||
rEnableTrigger <= true;
|
||||
sElasticBufferPtr <= to_unsigned(7, sElasticBufferPtr'length);
|
||||
|
||||
aReset <= true, false after 10 ns;
|
||||
ClkWait(RefClk,5);
|
||||
|
||||
-- Start up the pulsers and ensure nothing comes out of the trigger for a while.
|
||||
rEnablePulser <= true;
|
||||
ClkWait(RefClk, 3);
|
||||
ClkWait(SampleClk, 2);
|
||||
sEnablePulser <= true;
|
||||
|
||||
ClkWait(RefClk, kRpPeriodInRClks*5);
|
||||
assert (not sTriggerOut) and sTriggerOut'stable(kRpPeriodInRClks*5*kRPer)
|
||||
report "Rogue activity on sTriggerOut before rTriggerIn asserted!" severity error;
|
||||
assert (rReadyForInput) and rReadyForInput'stable(kRpPeriodInRClks*5*kRPer)
|
||||
report "Ready for Input was not high before trigger!" severity error;
|
||||
|
||||
|
||||
SendTrigger;
|
||||
|
||||
ClkWait(RefClk, kRpPeriodInRClks*5);
|
||||
|
||||
SendTrigger;
|
||||
|
||||
ClkWait(RefClk, kRpPeriodInRClks*5);
|
||||
|
||||
-- Turn off the trigger enable and send a trigger.
|
||||
rEnableTrigger <= false;
|
||||
ClkWait(RefClk);
|
||||
rTriggerIn <= true;
|
||||
ClkWait(RefClk);
|
||||
rTriggerIn <= false;
|
||||
|
||||
-- And nothing should happen.
|
||||
ClkWait(RefClk, kRpPeriodInRClks*5);
|
||||
assert (not sTriggerOut) and sTriggerOut'stable(kRpPeriodInRClks*5*kRPer)
|
||||
report "Rogue activity on sTriggerOut before rTriggerIn asserted!" severity error;
|
||||
|
||||
|
||||
ClkWait(RefClk, kRpPeriodInRClks*5);
|
||||
StopSim <= true;
|
||||
wait;
|
||||
end process;
|
||||
|
||||
|
||||
CheckRfi : process(RefClk)
|
||||
begin
|
||||
if falling_edge(RefClk) then
|
||||
assert rReadyForInput = rRfiExpected
|
||||
report "RFI didn't match expected" severity error;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
CheckTrigOut : process(SampleClk)
|
||||
begin
|
||||
if falling_edge(SampleClk) then
|
||||
assert sTriggerOut = sTriggerOutExpected
|
||||
report "Trigger Out didn't match expected" severity error;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
--vhook_e CrossTrigger dutx
|
||||
dutx: entity work.CrossTrigger (rtl)
|
||||
port map (
|
||||
aReset => aReset, --in boolean
|
||||
RefClk => RefClk, --in std_logic
|
||||
rRP => rRP, --in boolean
|
||||
rReadyForInput => rReadyForInput, --out boolean
|
||||
rEnableTrigger => rEnableTrigger, --in boolean
|
||||
rTriggerIn => rTriggerIn, --in boolean
|
||||
SampleClk => SampleClk, --in std_logic
|
||||
sSP => sSP, --in boolean
|
||||
sElasticBufferPtr => sElasticBufferPtr, --in unsigned(3:0)
|
||||
sTriggerOut => sTriggerOut); --out boolean
|
||||
|
||||
|
||||
end test;
|
||||
--synopsys translate_on
|
||||
@@ -0,0 +1,362 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright 2018 Ettus Research, a National Instruments Company
|
||||
--
|
||||
-- SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
--
|
||||
--
|
||||
-- Purpose:
|
||||
--
|
||||
-- The purpose of this module is to create a psuedo-clock "pulse" on the output
|
||||
-- cPulse whenever cEnablePulse is asserted.
|
||||
--
|
||||
-- The output period and high time are determined by the inputs cPeriod and
|
||||
-- cHighTime, where cPeriod must be greater than cHighTime+2. When these values
|
||||
-- are valid at the inputs, pulse cLoadLimits to load them into the pulser routine.
|
||||
-- It is not recommended to leave cEnablePulse asserted when loading new limits.
|
||||
--
|
||||
-- Dynamic period and duty cycle setup:
|
||||
-- 1) Disable the pulser by de-asserting cEnablePulse.
|
||||
-- 2) Load new period and duty cycle by modifying cPeriod and cHighTime. Pulse
|
||||
-- cLoadLimits for at least one Clk cycle.
|
||||
-- 3) Enable the pulser by asserting cEnablePulse.
|
||||
-- 4) Repeat 1-3 as necessary.
|
||||
--
|
||||
-- Static period and duty cycle setup:
|
||||
-- 1) Tie cLoadLimits to asserted.
|
||||
-- 2) Tie cPeriod and cHighTime to static values.
|
||||
-- 3) Enable and disable the pulser by asserting and de-asserting cEnablePulser at will.
|
||||
-- This input can also be tied asserted in this case.
|
||||
--
|
||||
-- vreview_group Tdc
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use ieee.math_real.all;
|
||||
|
||||
entity Pulser is
|
||||
generic (
|
||||
-- The pulse counter is kClksPerPulseMaxBits wide.
|
||||
-- Why 16? Then both cPeriod and cHighTime fit nicely into one 32 bit register!
|
||||
-- Minimum of 3 to make our default values for cHighTime work out.
|
||||
kClksPerPulseMaxBits : integer range 3 to 32 := 16
|
||||
);
|
||||
port (
|
||||
aReset : in boolean;
|
||||
Clk : in std_logic;
|
||||
|
||||
-- Pulse cLoadLimits when cPeriod and cHighTime are valid. Is it not recommended to
|
||||
-- load new limits when the output is enabled.
|
||||
-- Alternatively, cLoadLimits can be tied high if cPeriod and cHighTime are also
|
||||
-- tied to static values.
|
||||
cLoadLimits : in boolean;
|
||||
cPeriod : in unsigned(kClksPerPulseMaxBits - 1 downto 0);
|
||||
cHighTime : in unsigned(kClksPerPulseMaxBits - 1 downto 0);
|
||||
|
||||
-- When cEnablePulse is de-asserted, cPulse idles low on the following cycle.
|
||||
-- When asserted, cPulse will then assert within a few cycles.
|
||||
-- This input can be tied high, if desired, and the pulses will start several
|
||||
-- clock cycles after aReset de-assertion.
|
||||
cEnablePulse : in boolean;
|
||||
|
||||
-- When cEnablePulse is asserted, cPulse will produce a rising edge every
|
||||
-- cPeriod of the Clk input and a falling edge cHighTime cycles after
|
||||
-- the rising edge.
|
||||
cPulse : out boolean
|
||||
);
|
||||
end Pulser;
|
||||
|
||||
|
||||
architecture rtl of Pulser is
|
||||
|
||||
signal cCounter,
|
||||
cPeriodStored,
|
||||
cHighTimeStored : unsigned(cPeriod'range);
|
||||
|
||||
signal cSafeToStart_ms, cSafeToStart, cSafeToStartDly : boolean;
|
||||
|
||||
attribute ASYNC_REG : string;
|
||||
attribute ASYNC_REG of cSafeToStart_ms : signal is "true";
|
||||
attribute ASYNC_REG of cSafeToStart : signal is "true";
|
||||
|
||||
begin
|
||||
|
||||
--synthesis translate_off
|
||||
CheckInputRanges : process(Clk)
|
||||
begin
|
||||
if falling_edge(Clk) then
|
||||
-- +2 since we have the output high offset from the zero of the counter
|
||||
assert (cPeriodStored > cHighTimeStored + 2)
|
||||
report "cPeriod is not greater than cHighTime + 2" severity error;
|
||||
-- Ensure the high time is greater than 1...
|
||||
assert (cHighTimeStored > 1)
|
||||
report "cHighTime is not greater than 1" severity error;
|
||||
end if;
|
||||
end process;
|
||||
--synthesis translate_on
|
||||
|
||||
|
||||
-- ------------------------------------------------------------------------------------
|
||||
-- !!! SAFE COUNTER STARTUP !!!
|
||||
-- This counter starts safely, meaning it cannot start counting immediately after
|
||||
-- aReset de-assertion, because the counter cannot start until cSafeToStart asserts,
|
||||
-- which cannot happen until 1-2 clock cycles after aReset de-assertion.
|
||||
-- ------------------------------------------------------------------------------------
|
||||
CountFreqRefPeriod: process(aReset, Clk)
|
||||
begin
|
||||
if aReset then
|
||||
cCounter <= (others => '0');
|
||||
cSafeToStart_ms <= false;
|
||||
cSafeToStart <= false;
|
||||
cSafeToStartDly <= false;
|
||||
cPulse <= false;
|
||||
cPeriodStored <= (others => '1');
|
||||
-- This is a rather arbitrary start value, but we are guaranteed that it is
|
||||
-- less than the reset value of cPeriodStored as well as greater than 2,
|
||||
-- so it works well enough in case the module isn't set up correctly.
|
||||
cHighTimeStored <= to_unsigned(kClksPerPulseMaxBits+2,cHighTimeStored'length);
|
||||
elsif rising_edge(Clk) then
|
||||
-- Create a safe counter startup signal that asserts shortly after
|
||||
-- aReset de-assertion.
|
||||
cSafeToStart_ms <= true;
|
||||
cSafeToStart <= cSafeToStart_ms;
|
||||
-- In the case where cLoadLimits and cEnablePulse are tied high, we need to give
|
||||
-- them one cycle to load before starting the counter, so we delay cSafeToStart
|
||||
-- by one for the counter.
|
||||
cSafeToStartDly <= cSafeToStart;
|
||||
|
||||
if cEnablePulse and cSafeToStartDly then
|
||||
-- Simple counter increment until ceiling reached, then roll over.
|
||||
if cCounter >= cPeriodStored - 1 then
|
||||
cCounter <= (others => '0');
|
||||
else
|
||||
cCounter <= cCounter + 1;
|
||||
end if;
|
||||
|
||||
-- Pulse the output when counter is between 1 and cHighTimeStored.
|
||||
if cCounter = 1 then
|
||||
cPulse <= true;
|
||||
elsif cCounter >= cHighTimeStored+1 then
|
||||
cPulse <= false;
|
||||
end if;
|
||||
|
||||
else
|
||||
cPulse <= false;
|
||||
cCounter <= (others => '0');
|
||||
end if;
|
||||
|
||||
if cLoadLimits and cSafeToStart then
|
||||
cPeriodStored <= cPeriod;
|
||||
cHighTimeStored <= cHighTime;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end rtl;
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Testbench for Pulser
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
--synopsys translate_off
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use ieee.math_real.all;
|
||||
|
||||
entity tb_Pulser is end tb_Pulser;
|
||||
|
||||
architecture test of tb_Pulser is
|
||||
|
||||
constant kClksPerPulseMaxBits : integer := 16;
|
||||
|
||||
--vhook_sigstart
|
||||
signal aReset: boolean;
|
||||
signal cEnablePulse: boolean;
|
||||
signal cHighTime: unsigned(kClksPerPulseMaxBits-1 downto 0);
|
||||
signal Clk: std_logic := '0';
|
||||
signal cLoadLimits: boolean;
|
||||
signal cPeriod: unsigned(kClksPerPulseMaxBits-1 downto 0);
|
||||
signal cPulse: boolean;
|
||||
signal cPulseDut2: boolean;
|
||||
--vhook_sigend
|
||||
|
||||
signal StopSim : boolean;
|
||||
constant kPer : time := 10 ns;
|
||||
|
||||
signal CheckPulse : boolean := false;
|
||||
signal cPulseSl : std_logic := '0';
|
||||
signal cPulseDut2Sl : std_logic := '0';
|
||||
|
||||
procedure ClkWait(X : positive := 1) is
|
||||
begin
|
||||
for i in 1 to X loop
|
||||
wait until rising_edge(Clk);
|
||||
end loop;
|
||||
end procedure ClkWait;
|
||||
|
||||
begin
|
||||
|
||||
Clk <= not Clk after kPer/2 when not StopSim else '0';
|
||||
|
||||
main: process
|
||||
begin
|
||||
cEnablePulse <= false;
|
||||
aReset <= true, false after 10 ns;
|
||||
ClkWait(5);
|
||||
|
||||
-- Ensure the pulse is quiet for a while.
|
||||
ClkWait(100);
|
||||
assert cPulse'stable(kPer*100) and not cPulse
|
||||
report "pulse not stable at false at startup"
|
||||
severity error;
|
||||
|
||||
|
||||
-- Set up, then enable the pulse; expect it to go high after a few cycles.
|
||||
cPeriod <= to_unsigned(250,cPeriod'length);
|
||||
cHighTime <= to_unsigned(100,cPeriod'length);
|
||||
cLoadLimits <= true;
|
||||
ClkWait;
|
||||
cLoadLimits <= false;
|
||||
cEnablePulse <= true;
|
||||
ClkWait(2); -- pulse rises here
|
||||
wait until falling_edge(Clk);
|
||||
assert cPulse report "cPulse not high two cycles after enabling" severity error;
|
||||
-- After another clock cycle the checker below should be primed, so we can enable it.
|
||||
ClkWait;
|
||||
CheckPulse <= true;
|
||||
ClkWait(to_integer(cHighTime)-1);
|
||||
wait until falling_edge(Clk);
|
||||
assert not cPulse report "Pulse not low after high requirement" severity error;
|
||||
|
||||
-- Check the pulse high and low for a few cycles (duplicated below, but this also
|
||||
-- checks that it actually is toggling).
|
||||
for i in 0 to 100 loop
|
||||
ClkWait(to_integer(cPeriod) - to_integer(cHighTime));
|
||||
wait until falling_edge(Clk);
|
||||
assert cPulse report "Pulse not high when expected" severity error;
|
||||
ClkWait(to_integer(cHighTime));
|
||||
wait until falling_edge(Clk);
|
||||
assert not cPulse report "Pulse not low after high requirement" severity error;
|
||||
end loop;
|
||||
|
||||
-- Disable pulse, and check that it goes away for a long time
|
||||
cEnablePulse <= false;
|
||||
CheckPulse <= false;
|
||||
-- 2 is about the max time for it to go away.
|
||||
ClkWait(2);
|
||||
ClkWait(2**kClksPerPulseMaxBits);
|
||||
assert (not cPulse) and cPulse'stable(2**kClksPerPulseMaxBits*kPer)
|
||||
report "disable didn't work" severity error;
|
||||
|
||||
|
||||
-- Re-do all the initial tests with different periods and such.
|
||||
|
||||
-- Enable the pulse, expect it to go high after a few cycles
|
||||
cPeriod <= to_unsigned(10,cPeriod'length);
|
||||
cHighTime <= to_unsigned(5,cPeriod'length);
|
||||
cLoadLimits <= true;
|
||||
ClkWait;
|
||||
cLoadLimits <= false;
|
||||
cEnablePulse <= true;
|
||||
ClkWait(2); -- pulse rises here
|
||||
wait until falling_edge(Clk);
|
||||
assert cPulse report "cPulse not high two cycles after enabling" severity error;
|
||||
-- After another clock cycle the checker below should be primed, so we can enable it.
|
||||
ClkWait;
|
||||
CheckPulse <= true;
|
||||
ClkWait(to_integer(cHighTime)-1);
|
||||
wait until falling_edge(Clk);
|
||||
assert not cPulse report "Pulse not low after high requirement" severity error;
|
||||
|
||||
-- Check the pulse high and low for a few cycles (duplicated below, but this also
|
||||
-- checks that it actually is toggling).
|
||||
for i in 0 to 100 loop
|
||||
ClkWait(to_integer(cPeriod) - to_integer(cHighTime));
|
||||
wait until falling_edge(Clk);
|
||||
assert cPulse report "Pulse not high when expected" severity error;
|
||||
ClkWait(to_integer(cHighTime));
|
||||
wait until falling_edge(Clk);
|
||||
assert not cPulse report "Pulse not low after high requirement" severity error;
|
||||
end loop;
|
||||
|
||||
ClkWait(100);
|
||||
|
||||
|
||||
StopSim <= true;
|
||||
wait;
|
||||
end process;
|
||||
|
||||
cPulseSl <= '1' when cPulse else '0';
|
||||
|
||||
-- Test the period and duty cycle of the pulse.
|
||||
CheckPulseSpecs : process(cPulseSl)
|
||||
variable LastRise : time := 0 ns;
|
||||
begin
|
||||
if falling_edge(cPulseSl) then
|
||||
assert (not CheckPulse) or (now - LastRise = kPer*to_integer(cHighTime))
|
||||
report "High cycles requirement not met" severity error;
|
||||
elsif rising_edge(cPulseSl) then
|
||||
assert (not CheckPulse) or (now - LastRise = kPer*to_integer(cPeriod))
|
||||
report "Period requirement not met" & LF &
|
||||
"Act: " & time'image(now-LastRise) & LF &
|
||||
"Req: " & time'image(kPer*to_integer(cPeriod))
|
||||
severity error;
|
||||
LastRise := now;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
--vhook_e Pulser dutx
|
||||
dutx: entity work.Pulser (rtl)
|
||||
generic map (kClksPerPulseMaxBits => kClksPerPulseMaxBits) --integer range 3:32 :=16
|
||||
port map (
|
||||
aReset => aReset, --in boolean
|
||||
Clk => Clk, --in std_logic
|
||||
cLoadLimits => cLoadLimits, --in boolean
|
||||
cPeriod => cPeriod, --in unsigned(kClksPerPulseMaxBits-1:0)
|
||||
cHighTime => cHighTime, --in unsigned(kClksPerPulseMaxBits-1:0)
|
||||
cEnablePulse => cEnablePulse, --in boolean
|
||||
cPulse => cPulse); --out boolean
|
||||
|
||||
|
||||
--vhook_e Pulser dut2
|
||||
--vhook_a cLoadLimits true
|
||||
--vhook_a cPeriod to_unsigned(5,kClksPerPulseMaxBits)
|
||||
--vhook_a cHighTime to_unsigned(2,kClksPerPulseMaxBits)
|
||||
--vhook_a cEnablePulse true
|
||||
--vhook_a cPulse cPulseDut2
|
||||
dut2: entity work.Pulser (rtl)
|
||||
generic map (kClksPerPulseMaxBits => kClksPerPulseMaxBits) --integer range 3:32 :=16
|
||||
port map (
|
||||
aReset => aReset, --in boolean
|
||||
Clk => Clk, --in std_logic
|
||||
cLoadLimits => true, --in boolean
|
||||
cPeriod => to_unsigned(5,kClksPerPulseMaxBits), --in unsigned(kClksPerPulseMaxBits-1:0)
|
||||
cHighTime => to_unsigned(2,kClksPerPulseMaxBits), --in unsigned(kClksPerPulseMaxBits-1:0)
|
||||
cEnablePulse => true, --in boolean
|
||||
cPulse => cPulseDut2); --out boolean
|
||||
|
||||
cPulseDut2Sl <= '1' when cPulseDut2 else '0';
|
||||
|
||||
CheckDut2 : process (cPulseDut2Sl)
|
||||
variable LastRise : time := 0 ns;
|
||||
begin
|
||||
if falling_edge(cPulseDut2Sl) then
|
||||
assert (not CheckPulse) or (now - LastRise = kPer*2)
|
||||
report "DUT 2 High cycles requirement not met" severity error;
|
||||
elsif rising_edge(cPulseDut2Sl) then
|
||||
assert (not CheckPulse) or (now - LastRise = kPer*5)
|
||||
report "DUT 2 Period requirement not met" & LF &
|
||||
"Act: " & time'image(now-LastRise) & LF &
|
||||
"Req: " & time'image(kPer*5)
|
||||
severity error;
|
||||
LastRise := now;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
end test;
|
||||
--synopsys translate_on
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,397 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Copyright 2018 Ettus Research, a National Instruments Company
|
||||
--
|
||||
-- SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
--
|
||||
--
|
||||
-- Purpose:
|
||||
--
|
||||
-- Wrapper for the TDC and register control modules.
|
||||
--
|
||||
-- vreview_group Tdc
|
||||
-- vreview_reviewers dabaker sgupta jmarsar
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.PkgRegs.all;
|
||||
|
||||
entity TdcWrapper is
|
||||
port (
|
||||
-- Clocks and Resets : --------------------------------------------------------------
|
||||
-- Bus Clock and synchronous bus reset.
|
||||
BusClk : in std_logic;
|
||||
bBusReset : in std_logic;
|
||||
-- Reference Clock
|
||||
RefClk : in std_logic;
|
||||
-- Sample Clock
|
||||
SampleClk : in std_logic;
|
||||
-- Measurement Clock must run at a very specific frequency, determined by the
|
||||
-- SampleClk, RefClk, and Sync Pulse rates... oh and a lot of math.
|
||||
MeasClk : in std_logic;
|
||||
|
||||
|
||||
-- Register Port: -------------------------------------------------------------------
|
||||
bSyncRegPortOut : out RegPortOut_t;
|
||||
bSyncRegPortIn : in RegPortIn_t;
|
||||
|
||||
|
||||
-- PPS In and Out : -----------------------------------------------------------------
|
||||
-- Only required to pulse 1 RefClk cycle.
|
||||
rPpsPulse : in std_logic;
|
||||
-- PPS pulse output on the SampleClk domain.
|
||||
sPpsPulse : out std_logic;
|
||||
|
||||
|
||||
-- Sync Pulse Outputs : -------------------------------------------------------------
|
||||
-- The repeating pulses can be useful for many things, including passing triggers.
|
||||
rRpTransfer : out std_logic;
|
||||
sSpTransfer : out std_logic;
|
||||
|
||||
-- Pin bouncers out and in. Must go to unused and unconnected pins on the FPGA!
|
||||
rGatedPulseToPin : inout std_logic;
|
||||
sGatedPulseToPin : inout std_logic
|
||||
);
|
||||
end TdcWrapper;
|
||||
|
||||
|
||||
architecture struct of TdcWrapper is
|
||||
|
||||
component SyncRegsIfc
|
||||
port (
|
||||
aBusReset : in std_logic;
|
||||
bBusReset : in std_logic;
|
||||
BusClk : in std_logic;
|
||||
aTdcReset : out std_logic;
|
||||
bRegPortInFlat : in std_logic_vector(49 downto 0);
|
||||
bRegPortOutFlat : out std_logic_vector(33 downto 0);
|
||||
RefClk : in std_logic;
|
||||
rResetTdc : out std_logic;
|
||||
rResetTdcDone : in std_logic;
|
||||
rEnableTdc : out std_logic;
|
||||
rReRunEnable : out std_logic;
|
||||
rEnablePpsCrossing : out std_logic;
|
||||
rPpsPulseCaptured : in std_logic;
|
||||
rPulserEnableDelayVal : out std_logic_vector(3 downto 0);
|
||||
SampleClk : in std_logic;
|
||||
sPpsClkCrossDelayVal : out std_logic_vector(3 downto 0);
|
||||
MeasClk : in std_logic;
|
||||
mRpOffset : in std_logic_vector(39 downto 0);
|
||||
mSpOffset : in std_logic_vector(39 downto 0);
|
||||
mOffsetsDone : in std_logic;
|
||||
mOffsetsValid : in std_logic;
|
||||
rLoadRePulseCounts : out std_logic;
|
||||
rRePulsePeriodInRClks : out std_logic_vector(23 downto 0);
|
||||
rRePulseHighTimeInRClks : out std_logic_vector(23 downto 0);
|
||||
rLoadRpCounts : out std_logic;
|
||||
rRpPeriodInRClks : out std_logic_vector(15 downto 0);
|
||||
rRpHighTimeInRClks : out std_logic_vector(15 downto 0);
|
||||
rLoadRptCounts : out std_logic;
|
||||
rRptPeriodInRClks : out std_logic_vector(15 downto 0);
|
||||
rRptHighTimeInRClks : out std_logic_vector(15 downto 0);
|
||||
sLoadSpCounts : out std_logic;
|
||||
sSpPeriodInSClks : out std_logic_vector(15 downto 0);
|
||||
sSpHighTimeInSClks : out std_logic_vector(15 downto 0);
|
||||
sLoadSptCounts : out std_logic;
|
||||
sSptPeriodInSClks : out std_logic_vector(15 downto 0);
|
||||
sSptHighTimeInSClks : out std_logic_vector(15 downto 0));
|
||||
end component;
|
||||
|
||||
-- Generic values for the TdcTop instantiation below. These generics are the maximum
|
||||
-- of possible values for all combinations of Sample and Reference clocks for the N3xx
|
||||
-- family of devices.
|
||||
constant kRClksPerRePulsePeriodBitsMax : integer := 24;
|
||||
constant kRClksPerRpPeriodBitsMax : integer := 16;
|
||||
constant kSClksPerSpPeriodBitsMax : integer := 16;
|
||||
constant kPulsePeriodCntSize : integer := 13;
|
||||
-- The following are ideal values for balancing measurement time and accuracy, based
|
||||
-- on calcs given in the spec doc.
|
||||
constant kFreqRefPeriodsToCheckSize : integer := 17;
|
||||
constant kSyncPeriodsToStampSize : integer := 10;
|
||||
|
||||
--vhook_sigstart
|
||||
signal aTdcReset: std_logic;
|
||||
signal bSyncRegPortInFlat: std_logic_vector(49 downto 0);
|
||||
signal bSyncRegPortOutFlat: std_logic_vector(33 downto 0);
|
||||
signal mOffsetsDone: boolean;
|
||||
signal mOffsetsValid: boolean;
|
||||
signal mRpOffset: unsigned(kPulsePeriodCntSize+kSyncPeriodsToStampSize+kFreqRefPeriodsToCheckSize-1 downto 0);
|
||||
signal mSpOffset: unsigned(kPulsePeriodCntSize+kSyncPeriodsToStampSize+kFreqRefPeriodsToCheckSize-1 downto 0);
|
||||
signal rEnablePpsCrossing: std_logic;
|
||||
signal rEnableTdc: std_logic;
|
||||
signal rLoadRePulseCounts: std_logic;
|
||||
signal rLoadRpCounts: std_logic;
|
||||
signal rLoadRptCounts: std_logic;
|
||||
signal rPpsPulseCaptured: boolean;
|
||||
signal rPulserEnableDelayVal: std_logic_vector(3 downto 0);
|
||||
signal rRePulseHighTimeInRClks: std_logic_vector(kRClksPerRePulsePeriodBitsMax-1 downto 0);
|
||||
signal rRePulsePeriodInRClks: std_logic_vector(kRClksPerRePulsePeriodBitsMax-1 downto 0);
|
||||
signal rReRunEnable: std_logic;
|
||||
signal rResetTdc: std_logic;
|
||||
signal rResetTdcDone: boolean;
|
||||
signal rRpHighTimeInRClks: std_logic_vector(kRClksPerRpPeriodBitsMax-1 downto 0);
|
||||
signal rRpPeriodInRClks: std_logic_vector(kRClksPerRpPeriodBitsMax-1 downto 0);
|
||||
signal rRptHighTimeInRClks: std_logic_vector(kRClksPerRpPeriodBitsMax-1 downto 0);
|
||||
signal rRptPeriodInRClks: std_logic_vector(kRClksPerRpPeriodBitsMax-1 downto 0);
|
||||
signal rRpTransferBool: boolean;
|
||||
signal sLoadSpCounts: std_logic;
|
||||
signal sLoadSptCounts: std_logic;
|
||||
signal sPpsClkCrossDelayVal: std_logic_vector(3 downto 0);
|
||||
signal sPpsPulseAsyncReset: boolean;
|
||||
signal sSpHighTimeInSClks: std_logic_vector(kSClksPerSpPeriodBitsMax-1 downto 0);
|
||||
signal sSpPeriodInSClks: std_logic_vector(kSClksPerSpPeriodBitsMax-1 downto 0);
|
||||
signal sSptHighTimeInSClks: std_logic_vector(kSClksPerSpPeriodBitsMax-1 downto 0);
|
||||
signal sSptPeriodInSClks: std_logic_vector(kSClksPerSpPeriodBitsMax-1 downto 0);
|
||||
signal sSpTransferBool: boolean;
|
||||
--vhook_sigend
|
||||
|
||||
signal rPpsPulseAsyncReset_ms, rPpsPulseAsyncReset,
|
||||
sPpsPulseOut_ms, sPpsPulseOut : std_logic := '0';
|
||||
|
||||
function to_StdLogic(b : boolean) return std_ulogic is
|
||||
begin
|
||||
if b then
|
||||
return '1';
|
||||
else
|
||||
return '0';
|
||||
end if;
|
||||
end to_StdLogic;
|
||||
|
||||
function to_Boolean (s : std_ulogic) return boolean is
|
||||
begin
|
||||
return (To_X01(s)='1');
|
||||
end to_Boolean;
|
||||
|
||||
attribute ASYNC_REG : string;
|
||||
attribute ASYNC_REG of rPpsPulseAsyncReset_ms : signal is "true";
|
||||
attribute ASYNC_REG of rPpsPulseAsyncReset : signal is "true";
|
||||
attribute ASYNC_REG of sPpsPulseOut_ms : signal is "true";
|
||||
attribute ASYNC_REG of sPpsPulseOut : signal is "true";
|
||||
|
||||
begin
|
||||
|
||||
-- Cross the PPS from the no-reset domain into the aTdcReset domain since there is a
|
||||
-- reset crossing going into the TdcWrapper (reset by aTdcReset)! No clock domain
|
||||
-- crossing here, so crossing a single-cycle pulse is safe.
|
||||
DoubleSyncToAsyncReset : process (aTdcReset, RefClk)
|
||||
begin
|
||||
if to_boolean(aTdcReset) then
|
||||
rPpsPulseAsyncReset_ms <= '0';
|
||||
rPpsPulseAsyncReset <= '0';
|
||||
elsif rising_edge(RefClk) then
|
||||
rPpsPulseAsyncReset_ms <= rPpsPulse;
|
||||
rPpsPulseAsyncReset <= rPpsPulseAsyncReset_ms;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- In a similar fashion, cross the output PPS trigger from the async aTdcReset domain
|
||||
-- to the no-reset of the rest of the design. The odds of this signal triggering a
|
||||
-- failure are astronomically low (since it only pulses one clock cycle per second),
|
||||
-- but two flops is worth the assurance it won't mess something else up downstream.
|
||||
-- Note this double-sync mainly protects against the reset assertion case, since in the
|
||||
-- de-assertion case sPpsPulseAsyncReset should be zero and not transition for a long
|
||||
-- time afterwards. Again no clock crossing here, so crossing a single-cycle pulse
|
||||
-- is safe.
|
||||
DoubleSyncToNoReset : process (SampleClk)
|
||||
begin
|
||||
if rising_edge(SampleClk) then
|
||||
sPpsPulseOut_ms <= to_stdlogic(sPpsPulseAsyncReset);
|
||||
sPpsPulseOut <= sPpsPulseOut_ms;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
sPpsPulse <= sPpsPulseOut;
|
||||
|
||||
|
||||
rRpTransfer <= to_stdlogic(rRpTransferBool);
|
||||
sSpTransfer <= to_stdlogic(sSpTransferBool);
|
||||
|
||||
--vhook_e TdcTop
|
||||
--vhook_a aReset to_boolean(aTdcReset)
|
||||
--vhook_a rResetTdc to_boolean(rResetTdc)
|
||||
--vhook_a rEnableTdc to_boolean(rEnableTdc)
|
||||
--vhook_a rReRunEnable to_boolean(rReRunEnable)
|
||||
--vhook_a rPpsPulse to_boolean(rPpsPulseAsyncReset)
|
||||
--vhook_a rLoadRePulseCounts to_boolean(rLoadRePulseCounts)
|
||||
--vhook_a rLoadRpCounts to_boolean(rLoadRpCounts)
|
||||
--vhook_a rLoadRptCounts to_boolean(rLoadRptCounts)
|
||||
--vhook_a sLoadSpCounts to_boolean(sLoadSpCounts)
|
||||
--vhook_a sLoadSptCounts to_boolean(sLoadSptCounts)
|
||||
--vhook_a rEnablePpsCrossing to_boolean(rEnablePpsCrossing)
|
||||
--vhook_a rPulserEnableDelayVal unsigned(rPulserEnableDelayVal)
|
||||
--vhook_a sPpsClkCrossDelayVal unsigned(sPpsClkCrossDelayVal)
|
||||
--vhook_a rRpTransfer rRpTransferBool
|
||||
--vhook_a sSpTransfer sSpTransferBool
|
||||
--vhook_a sPpsPulse sPpsPulseAsyncReset
|
||||
--vhook_p {^rR(.*)In(.*)Clks} unsigned(rR$1In$2Clks)
|
||||
--vhook_p {^sS(.*)In(.*)Clks} unsigned(sS$1In$2Clks)
|
||||
TdcTopx: entity work.TdcTop (struct)
|
||||
generic map (
|
||||
kRClksPerRePulsePeriodBitsMax => kRClksPerRePulsePeriodBitsMax, --integer range 3:32 :=24
|
||||
kRClksPerRpPeriodBitsMax => kRClksPerRpPeriodBitsMax, --integer range 3:16 :=16
|
||||
kSClksPerSpPeriodBitsMax => kSClksPerSpPeriodBitsMax, --integer range 3:16 :=16
|
||||
kPulsePeriodCntSize => kPulsePeriodCntSize, --integer:=13
|
||||
kFreqRefPeriodsToCheckSize => kFreqRefPeriodsToCheckSize, --integer:=17
|
||||
kSyncPeriodsToStampSize => kSyncPeriodsToStampSize) --integer:=10
|
||||
port map (
|
||||
aReset => to_boolean(aTdcReset), --in boolean
|
||||
RefClk => RefClk, --in std_logic
|
||||
SampleClk => SampleClk, --in std_logic
|
||||
MeasClk => MeasClk, --in std_logic
|
||||
rResetTdc => to_boolean(rResetTdc), --in boolean
|
||||
rResetTdcDone => rResetTdcDone, --out boolean
|
||||
rEnableTdc => to_boolean(rEnableTdc), --in boolean
|
||||
rReRunEnable => to_boolean(rReRunEnable), --in boolean
|
||||
rPpsPulse => to_boolean(rPpsPulseAsyncReset), --in boolean
|
||||
rPpsPulseCaptured => rPpsPulseCaptured, --out boolean
|
||||
rPulserEnableDelayVal => unsigned(rPulserEnableDelayVal), --in unsigned(3:0)
|
||||
rEnablePpsCrossing => to_boolean(rEnablePpsCrossing), --in boolean
|
||||
sPpsClkCrossDelayVal => unsigned(sPpsClkCrossDelayVal), --in unsigned(3:0)
|
||||
sPpsPulse => sPpsPulseAsyncReset, --out boolean
|
||||
mRpOffset => mRpOffset, --out unsigned(kPulsePeriodCntSize+ kSyncPeriodsToStampSize+ kFreqRefPeriodsToCheckSize-1:0)
|
||||
mSpOffset => mSpOffset, --out unsigned(kPulsePeriodCntSize+ kSyncPeriodsToStampSize+ kFreqRefPeriodsToCheckSize-1:0)
|
||||
mOffsetsDone => mOffsetsDone, --out boolean
|
||||
mOffsetsValid => mOffsetsValid, --out boolean
|
||||
rLoadRePulseCounts => to_boolean(rLoadRePulseCounts), --in boolean
|
||||
rRePulsePeriodInRClks => unsigned(rRePulsePeriodInRClks), --in unsigned(kRClksPerRePulsePeriodBitsMax-1:0)
|
||||
rRePulseHighTimeInRClks => unsigned(rRePulseHighTimeInRClks), --in unsigned(kRClksPerRePulsePeriodBitsMax-1:0)
|
||||
rLoadRpCounts => to_boolean(rLoadRpCounts), --in boolean
|
||||
rRpPeriodInRClks => unsigned(rRpPeriodInRClks), --in unsigned(kRClksPerRpPeriodBitsMax-1:0)
|
||||
rRpHighTimeInRClks => unsigned(rRpHighTimeInRClks), --in unsigned(kRClksPerRpPeriodBitsMax-1:0)
|
||||
rLoadRptCounts => to_boolean(rLoadRptCounts), --in boolean
|
||||
rRptPeriodInRClks => unsigned(rRptPeriodInRClks), --in unsigned(kRClksPerRpPeriodBitsMax-1:0)
|
||||
rRptHighTimeInRClks => unsigned(rRptHighTimeInRClks), --in unsigned(kRClksPerRpPeriodBitsMax-1:0)
|
||||
sLoadSpCounts => to_boolean(sLoadSpCounts), --in boolean
|
||||
sSpPeriodInSClks => unsigned(sSpPeriodInSClks), --in unsigned(kSClksPerSpPeriodBitsMax-1:0)
|
||||
sSpHighTimeInSClks => unsigned(sSpHighTimeInSClks), --in unsigned(kSClksPerSpPeriodBitsMax-1:0)
|
||||
sLoadSptCounts => to_boolean(sLoadSptCounts), --in boolean
|
||||
sSptPeriodInSClks => unsigned(sSptPeriodInSClks), --in unsigned(kSClksPerSpPeriodBitsMax-1:0)
|
||||
sSptHighTimeInSClks => unsigned(sSptHighTimeInSClks), --in unsigned(kSClksPerSpPeriodBitsMax-1:0)
|
||||
rRpTransfer => rRpTransferBool, --out boolean
|
||||
sSpTransfer => sSpTransferBool, --out boolean
|
||||
rGatedPulseToPin => rGatedPulseToPin, --inout std_logic
|
||||
sGatedPulseToPin => sGatedPulseToPin); --inout std_logic
|
||||
|
||||
-- Expand/compress the RegPort for moving through the netlist boundary.
|
||||
bSyncRegPortOut <= Unflatten(bSyncRegPortOutFlat);
|
||||
bSyncRegPortInFlat <= Flatten(bSyncRegPortIn);
|
||||
|
||||
--vhook SyncRegsIfc
|
||||
--vhook_# Tying this low is safe because the sync reset is used inside SyncRegsIfc.
|
||||
--vhook_a aBusReset '0'
|
||||
--vhook_a bRegPortInFlat bSyncRegPortInFlat
|
||||
--vhook_a bRegPortOutFlat bSyncRegPortOutFlat
|
||||
--vhook_a rResetTdcDone to_stdlogic(rResetTdcDone)
|
||||
--vhook_a rPpsPulseCaptured to_stdlogic(rPpsPulseCaptured)
|
||||
--vhook_a mOffsetsDone to_stdlogic(mOffsetsDone)
|
||||
--vhook_a mOffsetsValid to_stdlogic(mOffsetsValid)
|
||||
--vhook_a mRpOffset std_logic_vector(mRpOffset)
|
||||
--vhook_a mSpOffset std_logic_vector(mSpOffset)
|
||||
SyncRegsIfcx: SyncRegsIfc
|
||||
port map (
|
||||
aBusReset => '0', --in std_logic
|
||||
bBusReset => bBusReset, --in std_logic
|
||||
BusClk => BusClk, --in std_logic
|
||||
aTdcReset => aTdcReset, --out std_logic
|
||||
bRegPortInFlat => bSyncRegPortInFlat, --in std_logic_vector(49:0)
|
||||
bRegPortOutFlat => bSyncRegPortOutFlat, --out std_logic_vector(33:0)
|
||||
RefClk => RefClk, --in std_logic
|
||||
rResetTdc => rResetTdc, --out std_logic
|
||||
rResetTdcDone => to_stdlogic(rResetTdcDone), --in std_logic
|
||||
rEnableTdc => rEnableTdc, --out std_logic
|
||||
rReRunEnable => rReRunEnable, --out std_logic
|
||||
rEnablePpsCrossing => rEnablePpsCrossing, --out std_logic
|
||||
rPpsPulseCaptured => to_stdlogic(rPpsPulseCaptured), --in std_logic
|
||||
rPulserEnableDelayVal => rPulserEnableDelayVal, --out std_logic_vector(3:0)
|
||||
SampleClk => SampleClk, --in std_logic
|
||||
sPpsClkCrossDelayVal => sPpsClkCrossDelayVal, --out std_logic_vector(3:0)
|
||||
MeasClk => MeasClk, --in std_logic
|
||||
mRpOffset => std_logic_vector(mRpOffset), --in std_logic_vector(39:0)
|
||||
mSpOffset => std_logic_vector(mSpOffset), --in std_logic_vector(39:0)
|
||||
mOffsetsDone => to_stdlogic(mOffsetsDone), --in std_logic
|
||||
mOffsetsValid => to_stdlogic(mOffsetsValid), --in std_logic
|
||||
rLoadRePulseCounts => rLoadRePulseCounts, --out std_logic
|
||||
rRePulsePeriodInRClks => rRePulsePeriodInRClks, --out std_logic_vector(23:0)
|
||||
rRePulseHighTimeInRClks => rRePulseHighTimeInRClks, --out std_logic_vector(23:0)
|
||||
rLoadRpCounts => rLoadRpCounts, --out std_logic
|
||||
rRpPeriodInRClks => rRpPeriodInRClks, --out std_logic_vector(15:0)
|
||||
rRpHighTimeInRClks => rRpHighTimeInRClks, --out std_logic_vector(15:0)
|
||||
rLoadRptCounts => rLoadRptCounts, --out std_logic
|
||||
rRptPeriodInRClks => rRptPeriodInRClks, --out std_logic_vector(15:0)
|
||||
rRptHighTimeInRClks => rRptHighTimeInRClks, --out std_logic_vector(15:0)
|
||||
sLoadSpCounts => sLoadSpCounts, --out std_logic
|
||||
sSpPeriodInSClks => sSpPeriodInSClks, --out std_logic_vector(15:0)
|
||||
sSpHighTimeInSClks => sSpHighTimeInSClks, --out std_logic_vector(15:0)
|
||||
sLoadSptCounts => sLoadSptCounts, --out std_logic
|
||||
sSptPeriodInSClks => sSptPeriodInSClks, --out std_logic_vector(15:0)
|
||||
sSptHighTimeInSClks => sSptHighTimeInSClks); --out std_logic_vector(15:0)
|
||||
|
||||
|
||||
end struct;
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Testbench for TdcWrapper
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
--synopsys translate_off
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.PkgRegs.all;
|
||||
|
||||
entity tb_TdcWrapper is end tb_TdcWrapper;
|
||||
|
||||
architecture test of tb_TdcWrapper is
|
||||
|
||||
--vhook_sigstart
|
||||
signal bBusReset: std_logic;
|
||||
signal bSyncRegPortIn: RegPortIn_t;
|
||||
signal bSyncRegPortOut: RegPortOut_t;
|
||||
signal BusClk: std_logic := '0';
|
||||
signal MeasClk: std_logic := '0';
|
||||
signal RefClk: std_logic := '0';
|
||||
signal rGatedPulseToPin: std_logic;
|
||||
signal rPpsPulse: std_logic;
|
||||
signal rRpTransfer: std_logic;
|
||||
signal SampleClk: std_logic := '0';
|
||||
signal sGatedPulseToPin: std_logic;
|
||||
signal sPpsPulse: std_logic;
|
||||
signal sSpTransfer: std_logic;
|
||||
--vhook_sigend
|
||||
|
||||
begin
|
||||
|
||||
--vhook_e TdcWrapper dutx
|
||||
dutx: entity work.TdcWrapper (struct)
|
||||
port map (
|
||||
BusClk => BusClk, --in std_logic
|
||||
bBusReset => bBusReset, --in std_logic
|
||||
RefClk => RefClk, --in std_logic
|
||||
SampleClk => SampleClk, --in std_logic
|
||||
MeasClk => MeasClk, --in std_logic
|
||||
bSyncRegPortOut => bSyncRegPortOut, --out RegPortOut_t
|
||||
bSyncRegPortIn => bSyncRegPortIn, --in RegPortIn_t
|
||||
rPpsPulse => rPpsPulse, --in std_logic
|
||||
sPpsPulse => sPpsPulse, --out std_logic
|
||||
rRpTransfer => rRpTransfer, --out std_logic
|
||||
sSpTransfer => sSpTransfer, --out std_logic
|
||||
rGatedPulseToPin => rGatedPulseToPin, --inout std_logic
|
||||
sGatedPulseToPin => sGatedPulseToPin); --inout std_logic
|
||||
|
||||
main: process
|
||||
|
||||
begin
|
||||
report "TdcWrapper Test is EMPTY! (but that's ok in this case)" severity note;
|
||||
--vhook_nowarn tb_TdcWrapper.test.*
|
||||
wait;
|
||||
end process;
|
||||
|
||||
end test;
|
||||
--synopsys translate_on
|
||||
@@ -0,0 +1,34 @@
|
||||
#
|
||||
# Copyright 2017 Ettus Research LLC
|
||||
#
|
||||
|
||||
##################################################
|
||||
# DB IFC Sources
|
||||
##################################################
|
||||
MAGNESIUM_DB_SRCS = $(abspath $(addprefix $(BASE_DIR)/n3xx/dboards/mg/db_ifc/, \
|
||||
DbCore.vhd \
|
||||
DaughterboardRegs.vhd \
|
||||
ClockingRegs.vhd \
|
||||
PkgMgPersonality.vhd \
|
||||
PkgDaughterboardRegMap.vhd \
|
||||
PkgClockingRegMap.vhd \
|
||||
PkgJesdConfig.vhd \
|
||||
RadioClocking.vhd \
|
||||
Jesd204bXcvrCore.edf \
|
||||
))
|
||||
|
||||
MAGNESIUM_TOP_SRCS = $(abspath $(addprefix $(BASE_DIR)/n3xx/dboards/mg/, \
|
||||
n3xx.v \
|
||||
))
|
||||
|
||||
MAGNESIUM_DB_TIMING_XDC = $(abspath $(addprefix $(BASE_DIR)/n3xx/dboards/mg/, \
|
||||
db_timing.xdc \
|
||||
))
|
||||
|
||||
MAGNESIUM_DB0_XDC = $(abspath $(addprefix $(BASE_DIR)/n3xx/dboards/mg/, \
|
||||
db0_pins.xdc \
|
||||
))
|
||||
|
||||
MAGNESIUM_DB1_XDC = $(abspath $(addprefix $(BASE_DIR)/n3xx/dboards/mg/, \
|
||||
db1_pins.xdc \
|
||||
))
|
||||
@@ -0,0 +1,22 @@
|
||||
#
|
||||
# Copyright 2018 Ettus Research, a National Instruments Company
|
||||
#
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
SRCS=TopCpld.qpf TopCpld.qsf Timing.sdc PkgMgCpld.vhd PkgSetup.vhd TopCpld.vhd
|
||||
|
||||
all: output_files/TopCpld.svf
|
||||
|
||||
cpld-magnesium-revc.svf: output_files/TopCpld.pof
|
||||
quartus_cpf --convert --frequency 10.0MHz --voltage 3.3 --operation p $? $@
|
||||
|
||||
output_files/TopCpld.pof: $(SRCS)
|
||||
quartus_map TopCpld
|
||||
quartus_fit TopCpld
|
||||
quartus_asm TopCpld
|
||||
quartus_sta TopCpld
|
||||
|
||||
clean:
|
||||
rm -rf db incremental_db output_files simulation cpld-magnesium-revc.svf
|
||||
|
||||
@@ -0,0 +1,424 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- File: PkgMgCpld.vhd
|
||||
-- Author: Autogenerated by XmlParse
|
||||
-- Original Project: --
|
||||
-- Date: --
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
-- Copyright 2016-2017 Ettus Research, A National Instruments Company
|
||||
-- SPDX-License-Identifier: GPL-3.0
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Purpose:
|
||||
-- The constants in this file are autogenerated by XmlParse and should
|
||||
-- be used by testbench code to access specific register fields.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
package PkgMgCpld is
|
||||
|
||||
--===============================================================================
|
||||
-- A numerically ordered list of registers and their VHDL source files
|
||||
--===============================================================================
|
||||
|
||||
-- SignatureReg : 0x0 (TopCpld.vhd)
|
||||
-- MinorRevReg : 0x1 (TopCpld.vhd)
|
||||
-- MajorRevReg : 0x2 (TopCpld.vhd)
|
||||
-- BuildCodeLSB : 0x3 (TopCpld.vhd)
|
||||
-- BuildCodeMSB : 0x4 (TopCpld.vhd)
|
||||
-- Scratch : 0x5 (TopCpld.vhd)
|
||||
-- CpldControl : 0x10 (TopCpld.vhd)
|
||||
-- LmkControl : 0x11 (TopCpld.vhd)
|
||||
-- LoStatus : 0x12 (TopCpld.vhd)
|
||||
-- MykonosControl : 0x13 (TopCpld.vhd)
|
||||
-- PlScratch : 0x40 (TopCpld.vhd)
|
||||
-- PlCpldControl : 0x41 (TopCpld.vhd)
|
||||
-- TxCh1_Idle : 0x50 (TopCpld.vhd)
|
||||
-- RxCh1_0_Idle : 0x51 (TopCpld.vhd)
|
||||
-- RxCh1_1_Idle : 0x52 (TopCpld.vhd)
|
||||
-- TxCh1_TxOn : 0x53 (TopCpld.vhd)
|
||||
-- RxCh1_0_RxOn : 0x54 (TopCpld.vhd)
|
||||
-- RxCh1_1_RxOn : 0x55 (TopCpld.vhd)
|
||||
-- TxCh2_Idle : 0x60 (TopCpld.vhd)
|
||||
-- RxCh2_0_Idle : 0x61 (TopCpld.vhd)
|
||||
-- RxCh2_1_Idle : 0x62 (TopCpld.vhd)
|
||||
-- TxCh2_TxOn : 0x63 (TopCpld.vhd)
|
||||
-- RxCh2_0_RxOn : 0x64 (TopCpld.vhd)
|
||||
-- RxCh2_1_RxOn : 0x65 (TopCpld.vhd)
|
||||
|
||||
--===============================================================================
|
||||
-- RegTypes
|
||||
--===============================================================================
|
||||
|
||||
--===============================================================================
|
||||
-- Register Group PsSpi_CpldRegisters
|
||||
--===============================================================================
|
||||
|
||||
-- SignatureReg Register (from TopCpld.vhd)
|
||||
constant kSignatureReg : integer := 16#0#; -- Register Offset
|
||||
constant kSignatureRegSize: integer := 16; -- register width in bits
|
||||
constant kSignatureRegMask : std_logic_vector(15 downto 0) := X"ffff";
|
||||
constant kProductSignatureSize : integer := 16; --SignatureReg:ProductSignature
|
||||
constant kProductSignatureMsb : integer := 15; --SignatureReg:ProductSignature
|
||||
constant kProductSignature : integer := 0; --SignatureReg:ProductSignature
|
||||
|
||||
-- MinorRevReg Register (from TopCpld.vhd)
|
||||
constant kMinorRevReg : integer := 16#1#; -- Register Offset
|
||||
constant kMinorRevRegSize: integer := 16; -- register width in bits
|
||||
constant kMinorRevRegMask : std_logic_vector(15 downto 0) := X"ffff";
|
||||
constant kCpldMinorRevisionSize : integer := 16; --MinorRevReg:CpldMinorRevision
|
||||
constant kCpldMinorRevisionMsb : integer := 15; --MinorRevReg:CpldMinorRevision
|
||||
constant kCpldMinorRevision : integer := 0; --MinorRevReg:CpldMinorRevision
|
||||
|
||||
-- MajorRevReg Register (from TopCpld.vhd)
|
||||
constant kMajorRevReg : integer := 16#2#; -- Register Offset
|
||||
constant kMajorRevRegSize: integer := 16; -- register width in bits
|
||||
constant kMajorRevRegMask : std_logic_vector(15 downto 0) := X"ffff";
|
||||
constant kCpldMajorRevisionSize : integer := 16; --MajorRevReg:CpldMajorRevision
|
||||
constant kCpldMajorRevisionMsb : integer := 15; --MajorRevReg:CpldMajorRevision
|
||||
constant kCpldMajorRevision : integer := 0; --MajorRevReg:CpldMajorRevision
|
||||
|
||||
-- BuildCodeLSB Register (from TopCpld.vhd)
|
||||
constant kBuildCodeLSB : integer := 16#3#; -- Register Offset
|
||||
constant kBuildCodeLSBSize: integer := 16; -- register width in bits
|
||||
constant kBuildCodeLSBMask : std_logic_vector(15 downto 0) := X"ffff";
|
||||
constant kBuildCodeHHSize : integer := 8; --BuildCodeLSB:BuildCodeHH
|
||||
constant kBuildCodeHHMsb : integer := 7; --BuildCodeLSB:BuildCodeHH
|
||||
constant kBuildCodeHH : integer := 0; --BuildCodeLSB:BuildCodeHH
|
||||
constant kBuildCodeDDSize : integer := 8; --BuildCodeLSB:BuildCodeDD
|
||||
constant kBuildCodeDDMsb : integer := 15; --BuildCodeLSB:BuildCodeDD
|
||||
constant kBuildCodeDD : integer := 8; --BuildCodeLSB:BuildCodeDD
|
||||
|
||||
-- BuildCodeMSB Register (from TopCpld.vhd)
|
||||
constant kBuildCodeMSB : integer := 16#4#; -- Register Offset
|
||||
constant kBuildCodeMSBSize: integer := 16; -- register width in bits
|
||||
constant kBuildCodeMSBMask : std_logic_vector(15 downto 0) := X"ffff";
|
||||
constant kBuildCodeMMSize : integer := 8; --BuildCodeMSB:BuildCodeMM
|
||||
constant kBuildCodeMMMsb : integer := 7; --BuildCodeMSB:BuildCodeMM
|
||||
constant kBuildCodeMM : integer := 0; --BuildCodeMSB:BuildCodeMM
|
||||
constant kBuildCodeYYSize : integer := 8; --BuildCodeMSB:BuildCodeYY
|
||||
constant kBuildCodeYYMsb : integer := 15; --BuildCodeMSB:BuildCodeYY
|
||||
constant kBuildCodeYY : integer := 8; --BuildCodeMSB:BuildCodeYY
|
||||
|
||||
-- Scratch Register (from TopCpld.vhd)
|
||||
constant kScratch : integer := 16#5#; -- Register Offset
|
||||
constant kScratchSize: integer := 16; -- register width in bits
|
||||
constant kScratchMask : std_logic_vector(15 downto 0) := X"ffff";
|
||||
constant kScratchValSize : integer := 16; --Scratch:ScratchVal
|
||||
constant kScratchValMsb : integer := 15; --Scratch:ScratchVal
|
||||
constant kScratchVal : integer := 0; --Scratch:ScratchVal
|
||||
|
||||
-- CpldControl Register (from TopCpld.vhd)
|
||||
constant kCpldControl : integer := 16#10#; -- Register Offset
|
||||
constant kCpldControlSize: integer := 16; -- register width in bits
|
||||
constant kCpldControlMask : std_logic_vector(15 downto 0) := X"0001";
|
||||
constant kCpldResetSize : integer := 1; --CpldControl:CpldReset
|
||||
constant kCpldResetMsb : integer := 0; --CpldControl:CpldReset
|
||||
constant kCpldReset : integer := 0; --CpldControl:CpldReset
|
||||
|
||||
-- LmkControl Register (from TopCpld.vhd)
|
||||
constant kLmkControl : integer := 16#11#; -- Register Offset
|
||||
constant kLmkControlSize: integer := 16; -- register width in bits
|
||||
constant kLmkControlMask : std_logic_vector(15 downto 0) := X"0010";
|
||||
constant kVcxoControlSize : integer := 1; --LmkControl:VcxoControl
|
||||
constant kVcxoControlMsb : integer := 4; --LmkControl:VcxoControl
|
||||
constant kVcxoControl : integer := 4; --LmkControl:VcxoControl
|
||||
|
||||
-- LoStatus Register (from TopCpld.vhd)
|
||||
constant kLoStatus : integer := 16#12#; -- Register Offset
|
||||
constant kLoStatusSize: integer := 16; -- register width in bits
|
||||
constant kLoStatusMask : std_logic_vector(15 downto 0) := X"0011";
|
||||
constant kRxLoLockDetectSize : integer := 1; --LoStatus:RxLoLockDetect
|
||||
constant kRxLoLockDetectMsb : integer := 0; --LoStatus:RxLoLockDetect
|
||||
constant kRxLoLockDetect : integer := 0; --LoStatus:RxLoLockDetect
|
||||
constant kTxLoLockDetectSize : integer := 1; --LoStatus:TxLoLockDetect
|
||||
constant kTxLoLockDetectMsb : integer := 4; --LoStatus:TxLoLockDetect
|
||||
constant kTxLoLockDetect : integer := 4; --LoStatus:TxLoLockDetect
|
||||
|
||||
-- MykonosControl Register (from TopCpld.vhd)
|
||||
constant kMykonosControl : integer := 16#13#; -- Register Offset
|
||||
constant kMykonosControlSize: integer := 16; -- register width in bits
|
||||
constant kMykonosControlMask : std_logic_vector(15 downto 0) := X"0001";
|
||||
constant kMykonosResetSize : integer := 1; --MykonosControl:MykonosReset
|
||||
constant kMykonosResetMsb : integer := 0; --MykonosControl:MykonosReset
|
||||
constant kMykonosReset : integer := 0; --MykonosControl:MykonosReset
|
||||
|
||||
--===============================================================================
|
||||
-- Register Group PlSpi_FrontEndControl
|
||||
--===============================================================================
|
||||
|
||||
-- Enumerated type Rx1Switch1
|
||||
constant kRx1Switch1Size : integer := 4;
|
||||
constant kTxRxInput : integer := 0; -- Rx1Switch1:TxRxInput
|
||||
constant kRxLoCalInput : integer := 1; -- Rx1Switch1:RxLoCalInput
|
||||
constant kTrxSwitchOutput : integer := 2; -- Rx1Switch1:TrxSwitchOutput
|
||||
constant kRx2Input : integer := 3; -- Rx1Switch1:Rx2Input
|
||||
|
||||
-- Enumerated type Rx1Switch2
|
||||
constant kRx1Switch2Size : integer := 4;
|
||||
constant kShutdownSw2 : integer := 0; -- Rx1Switch2:ShutdownSw2
|
||||
constant kLowerFilterBankToSwitch3 : integer := 1; -- Rx1Switch2:LowerFilterBankToSwitch3
|
||||
constant kBypassPathToSwitch6 : integer := 2; -- Rx1Switch2:BypassPathToSwitch6
|
||||
constant kUpperFilterBankToSwitch4 : integer := 3; -- Rx1Switch2:UpperFilterBankToSwitch4
|
||||
|
||||
-- Enumerated type Rx1Switch3
|
||||
constant kRx1Switch3Size : integer := 7;
|
||||
constant kFilter2100x2850MHz : integer := 0; -- Rx1Switch3:Filter2100x2850MHz
|
||||
constant kFilter0490LpMHz : integer := 1; -- Rx1Switch3:Filter0490LpMHz
|
||||
constant kFilter1600x2250MHz : integer := 2; -- Rx1Switch3:Filter1600x2250MHz
|
||||
constant kFilter0440x0530MHz : integer := 4; -- Rx1Switch3:Filter0440x0530MHz
|
||||
constant kFilter0650x1000MHz : integer := 5; -- Rx1Switch3:Filter0650x1000MHz
|
||||
constant kFilter1100x1575MHz : integer := 6; -- Rx1Switch3:Filter1100x1575MHz
|
||||
constant kShutdownSw3 : integer := 7; -- Rx1Switch3:ShutdownSw3
|
||||
|
||||
-- Enumerated type Rx1Switch4
|
||||
constant kRx1Switch4Size : integer := 3;
|
||||
constant kFilter2100x2850MHzFrom : integer := 1; -- Rx1Switch4:Filter2100x2850MHzFrom
|
||||
constant kFilter1600x2250MHzFrom : integer := 2; -- Rx1Switch4:Filter1600x2250MHzFrom
|
||||
constant kFilter2700HpMHz : integer := 4; -- Rx1Switch4:Filter2700HpMHz
|
||||
|
||||
-- Enumerated type Rx1Switch5
|
||||
constant kRx1Switch5Size : integer := 4;
|
||||
constant kFilter0440x0530MHzFrom : integer := 1; -- Rx1Switch5:Filter0440x0530MHzFrom
|
||||
constant kFilter1100x1575MHzFrom : integer := 2; -- Rx1Switch5:Filter1100x1575MHzFrom
|
||||
constant kFilter0490LpMHzFrom : integer := 4; -- Rx1Switch5:Filter0490LpMHzFrom
|
||||
constant kFilter0650x1000MHzFrom : integer := 8; -- Rx1Switch5:Filter0650x1000MHzFrom
|
||||
|
||||
-- Enumerated type Rx1Switch6
|
||||
constant kRx1Switch6Size : integer := 3;
|
||||
constant kLowerFilterBankFromSwitch5 : integer := 1; -- Rx1Switch6:LowerFilterBankFromSwitch5
|
||||
constant kUpperFilterBankFromSwitch4 : integer := 2; -- Rx1Switch6:UpperFilterBankFromSwitch4
|
||||
constant kBypassPathFromSwitch2 : integer := 4; -- Rx1Switch6:BypassPathFromSwitch2
|
||||
|
||||
-- Enumerated type TrxSwitch
|
||||
constant kTrxSwitchSize : integer := 4;
|
||||
constant kFromLowerFilterBankTxSw1 : integer := 0; -- TrxSwitch:FromLowerFilterBankTxSw1
|
||||
constant kFromTxUpperFilterBankLp6400MHz : integer := 1; -- TrxSwitch:FromTxUpperFilterBankLp6400MHz
|
||||
constant kRxChannelPath : integer := 2; -- TrxSwitch:RxChannelPath
|
||||
constant kBypassPathToTxSw3 : integer := 3; -- TrxSwitch:BypassPathToTxSw3
|
||||
|
||||
-- Enumerated type TxSwitch1
|
||||
constant kTxSwitch1Size : integer := 4;
|
||||
constant kShutdownTxSw1 : integer := 0; -- TxSwitch1:ShutdownTxSw1
|
||||
constant kFromTxFilterLp1700MHz : integer := 1; -- TxSwitch1:FromTxFilterLp1700MHz
|
||||
constant kFromTxFilterLp3400MHz : integer := 2; -- TxSwitch1:FromTxFilterLp3400MHz
|
||||
constant kFromTxFilterLp0800MHz : integer := 3; -- TxSwitch1:FromTxFilterLp0800MHz
|
||||
|
||||
-- Enumerated type TxSwitch2
|
||||
constant kTxSwitch2Size : integer := 4;
|
||||
constant kToTxFilterLp3400MHz : integer := 1; -- TxSwitch2:ToTxFilterLp3400MHz
|
||||
constant kToTxFilterLp1700MHz : integer := 2; -- TxSwitch2:ToTxFilterLp1700MHz
|
||||
constant kToTxFilterLp0800MHz : integer := 4; -- TxSwitch2:ToTxFilterLp0800MHz
|
||||
constant kToTxFilterLp6400MHz : integer := 8; -- TxSwitch2:ToTxFilterLp6400MHz
|
||||
|
||||
-- Enumerated type TxSwitch3
|
||||
constant kTxSwitch3Size : integer := 2;
|
||||
constant kToTxFilterBanks : integer := 0; -- TxSwitch3:ToTxFilterBanks
|
||||
constant kBypassPathToTrxSw : integer := 1; -- TxSwitch3:BypassPathToTrxSw
|
||||
|
||||
-- PlScratch Register (from TopCpld.vhd)
|
||||
constant kPlScratch : integer := 16#40#; -- Register Offset
|
||||
constant kPlScratchSize: integer := 16; -- register width in bits
|
||||
constant kPlScratchMask : std_logic_vector(15 downto 0) := X"ffff";
|
||||
constant kPlScratchValSize : integer := 16; --PlScratch:PlScratchVal
|
||||
constant kPlScratchValMsb : integer := 15; --PlScratch:PlScratchVal
|
||||
constant kPlScratchVal : integer := 0; --PlScratch:PlScratchVal
|
||||
|
||||
-- PlCpldControl Register (from TopCpld.vhd)
|
||||
constant kPlCpldControl : integer := 16#41#; -- Register Offset
|
||||
constant kPlCpldControlSize: integer := 16; -- register width in bits
|
||||
constant kPlCpldControlMask : std_logic_vector(15 downto 0) := X"0001";
|
||||
constant kPlCpldResetSize : integer := 1; --PlCpldControl:PlCpldReset
|
||||
constant kPlCpldResetMsb : integer := 0; --PlCpldControl:PlCpldReset
|
||||
constant kPlCpldReset : integer := 0; --PlCpldControl:PlCpldReset
|
||||
|
||||
-- TxCh1_Idle Register (from TopCpld.vhd)
|
||||
constant kTxCh1_Idle : integer := 16#50#; -- Register Offset
|
||||
constant kTxCh1_IdleSize: integer := 16; -- register width in bits
|
||||
constant kTxCh1_IdleMask : std_logic_vector(15 downto 0) := X"7fff";
|
||||
constant kCh1TxSw1Size : integer := 2; --TxCh1_Idle:Ch1TxSw1
|
||||
constant kCh1TxSw1Msb : integer := 1; --TxCh1_Idle:Ch1TxSw1
|
||||
constant kCh1TxSw1 : integer := 0; --TxCh1_Idle:Ch1TxSw1
|
||||
constant kCh1TxSw2Size : integer := 4; --TxCh1_Idle:Ch1TxSw2
|
||||
constant kCh1TxSw2Msb : integer := 5; --TxCh1_Idle:Ch1TxSw2
|
||||
constant kCh1TxSw2 : integer := 2; --TxCh1_Idle:Ch1TxSw2
|
||||
constant kCh1TxSw3Size : integer := 1; --TxCh1_Idle:Ch1TxSw3
|
||||
constant kCh1TxSw3Msb : integer := 6; --TxCh1_Idle:Ch1TxSw3
|
||||
constant kCh1TxSw3 : integer := 6; --TxCh1_Idle:Ch1TxSw3
|
||||
constant kCh1TxLowbandMixerPathSelectSize : integer := 1; --TxCh1_Idle:Ch1TxLowbandMixerPathSelect
|
||||
constant kCh1TxLowbandMixerPathSelectMsb : integer := 7; --TxCh1_Idle:Ch1TxLowbandMixerPathSelect
|
||||
constant kCh1TxLowbandMixerPathSelect : integer := 7; --TxCh1_Idle:Ch1TxLowbandMixerPathSelect
|
||||
constant kCh1TxMixerEnSize : integer := 1; --TxCh1_Idle:Ch1TxMixerEn
|
||||
constant kCh1TxMixerEnMsb : integer := 8; --TxCh1_Idle:Ch1TxMixerEn
|
||||
constant kCh1TxMixerEn : integer := 8; --TxCh1_Idle:Ch1TxMixerEn
|
||||
constant kCh1TxAmpEnSize : integer := 1; --TxCh1_Idle:Ch1TxAmpEn
|
||||
constant kCh1TxAmpEnMsb : integer := 9; --TxCh1_Idle:Ch1TxAmpEn
|
||||
constant kCh1TxAmpEn : integer := 9; --TxCh1_Idle:Ch1TxAmpEn
|
||||
constant kCh1TxPaEnSize : integer := 1; --TxCh1_Idle:Ch1TxPaEn
|
||||
constant kCh1TxPaEnMsb : integer := 10; --TxCh1_Idle:Ch1TxPaEn
|
||||
constant kCh1TxPaEn : integer := 10; --TxCh1_Idle:Ch1TxPaEn
|
||||
constant kCh1SwTrxSize : integer := 2; --TxCh1_Idle:Ch1SwTrx
|
||||
constant kCh1SwTrxMsb : integer := 12; --TxCh1_Idle:Ch1SwTrx
|
||||
constant kCh1SwTrx : integer := 11; --TxCh1_Idle:Ch1SwTrx
|
||||
constant kCh1TxLedSize : integer := 1; --TxCh1_Idle:Ch1TxLed
|
||||
constant kCh1TxLedMsb : integer := 13; --TxCh1_Idle:Ch1TxLed
|
||||
constant kCh1TxLed : integer := 13; --TxCh1_Idle:Ch1TxLed
|
||||
constant kCh1MykEnTxSize : integer := 1; --TxCh1_Idle:Ch1MykEnTx
|
||||
constant kCh1MykEnTxMsb : integer := 14; --TxCh1_Idle:Ch1MykEnTx
|
||||
constant kCh1MykEnTx : integer := 14; --TxCh1_Idle:Ch1MykEnTx
|
||||
|
||||
-- RxCh1_0_Idle Register (from TopCpld.vhd)
|
||||
constant kRxCh1_0_Idle : integer := 16#51#; -- Register Offset
|
||||
constant kRxCh1_0_IdleSize: integer := 16; -- register width in bits
|
||||
constant kRxCh1_0_IdleMask : std_logic_vector(15 downto 0) := X"3fff";
|
||||
constant kCh1RxSw1Size : integer := 2; --RxCh1_0_Idle:Ch1RxSw1
|
||||
constant kCh1RxSw1Msb : integer := 1; --RxCh1_0_Idle:Ch1RxSw1
|
||||
constant kCh1RxSw1 : integer := 0; --RxCh1_0_Idle:Ch1RxSw1
|
||||
constant kCh1RxSw2Size : integer := 2; --RxCh1_0_Idle:Ch1RxSw2
|
||||
constant kCh1RxSw2Msb : integer := 3; --RxCh1_0_Idle:Ch1RxSw2
|
||||
constant kCh1RxSw2 : integer := 2; --RxCh1_0_Idle:Ch1RxSw2
|
||||
constant kCh1RxSw3Size : integer := 3; --RxCh1_0_Idle:Ch1RxSw3
|
||||
constant kCh1RxSw3Msb : integer := 6; --RxCh1_0_Idle:Ch1RxSw3
|
||||
constant kCh1RxSw3 : integer := 4; --RxCh1_0_Idle:Ch1RxSw3
|
||||
constant kCh1RxSw4Size : integer := 3; --RxCh1_0_Idle:Ch1RxSw4
|
||||
constant kCh1RxSw4Msb : integer := 9; --RxCh1_0_Idle:Ch1RxSw4
|
||||
constant kCh1RxSw4 : integer := 7; --RxCh1_0_Idle:Ch1RxSw4
|
||||
constant kCh1RxSw5Size : integer := 4; --RxCh1_0_Idle:Ch1RxSw5
|
||||
constant kCh1RxSw5Msb : integer := 13; --RxCh1_0_Idle:Ch1RxSw5
|
||||
constant kCh1RxSw5 : integer := 10; --RxCh1_0_Idle:Ch1RxSw5
|
||||
|
||||
-- RxCh1_1_Idle Register (from TopCpld.vhd)
|
||||
constant kRxCh1_1_Idle : integer := 16#52#; -- Register Offset
|
||||
constant kRxCh1_1_IdleSize: integer := 16; -- register width in bits
|
||||
constant kRxCh1_1_IdleMask : std_logic_vector(15 downto 0) := X"07ff";
|
||||
constant kCh1RxSw6Size : integer := 3; --RxCh1_1_Idle:Ch1RxSw6
|
||||
constant kCh1RxSw6Msb : integer := 2; --RxCh1_1_Idle:Ch1RxSw6
|
||||
constant kCh1RxSw6 : integer := 0; --RxCh1_1_Idle:Ch1RxSw6
|
||||
constant kCh1RxLowbandMixerPathSelectSize : integer := 1; --RxCh1_1_Idle:Ch1RxLowbandMixerPathSelect
|
||||
constant kCh1RxLowbandMixerPathSelectMsb : integer := 3; --RxCh1_1_Idle:Ch1RxLowbandMixerPathSelect
|
||||
constant kCh1RxLowbandMixerPathSelect : integer := 3; --RxCh1_1_Idle:Ch1RxLowbandMixerPathSelect
|
||||
constant kCh1RxMixerEnSize : integer := 1; --RxCh1_1_Idle:Ch1RxMixerEn
|
||||
constant kCh1RxMixerEnMsb : integer := 4; --RxCh1_1_Idle:Ch1RxMixerEn
|
||||
constant kCh1RxMixerEn : integer := 4; --RxCh1_1_Idle:Ch1RxMixerEn
|
||||
constant kCh1RxAmpEnSize : integer := 1; --RxCh1_1_Idle:Ch1RxAmpEn
|
||||
constant kCh1RxAmpEnMsb : integer := 5; --RxCh1_1_Idle:Ch1RxAmpEn
|
||||
constant kCh1RxAmpEn : integer := 5; --RxCh1_1_Idle:Ch1RxAmpEn
|
||||
constant kCh1RxLna1EnSize : integer := 1; --RxCh1_1_Idle:Ch1RxLna1En
|
||||
constant kCh1RxLna1EnMsb : integer := 6; --RxCh1_1_Idle:Ch1RxLna1En
|
||||
constant kCh1RxLna1En : integer := 6; --RxCh1_1_Idle:Ch1RxLna1En
|
||||
constant kCh1RxLna2EnSize : integer := 1; --RxCh1_1_Idle:Ch1RxLna2En
|
||||
constant kCh1RxLna2EnMsb : integer := 7; --RxCh1_1_Idle:Ch1RxLna2En
|
||||
constant kCh1RxLna2En : integer := 7; --RxCh1_1_Idle:Ch1RxLna2En
|
||||
constant kCh1Rx2LedSize : integer := 1; --RxCh1_1_Idle:Ch1Rx2Led
|
||||
constant kCh1Rx2LedMsb : integer := 8; --RxCh1_1_Idle:Ch1Rx2Led
|
||||
constant kCh1Rx2Led : integer := 8; --RxCh1_1_Idle:Ch1Rx2Led
|
||||
constant kCh1RxLedSize : integer := 1; --RxCh1_1_Idle:Ch1RxLed
|
||||
constant kCh1RxLedMsb : integer := 9; --RxCh1_1_Idle:Ch1RxLed
|
||||
constant kCh1RxLed : integer := 9; --RxCh1_1_Idle:Ch1RxLed
|
||||
constant kCh1MykEnRxSize : integer := 1; --RxCh1_1_Idle:Ch1MykEnRx
|
||||
constant kCh1MykEnRxMsb : integer := 10; --RxCh1_1_Idle:Ch1MykEnRx
|
||||
constant kCh1MykEnRx : integer := 10; --RxCh1_1_Idle:Ch1MykEnRx
|
||||
|
||||
-- TxCh1_TxOn Register (from TopCpld.vhd)
|
||||
constant kTxCh1_TxOn : integer := 16#53#; -- Register Offset
|
||||
constant kTxCh1_TxOnSize: integer := 16; -- register width in bits
|
||||
constant kTxCh1_TxOnMask : std_logic_vector(15 downto 0) := X"0000";
|
||||
|
||||
-- RxCh1_0_RxOn Register (from TopCpld.vhd)
|
||||
constant kRxCh1_0_RxOn : integer := 16#54#; -- Register Offset
|
||||
constant kRxCh1_0_RxOnSize: integer := 16; -- register width in bits
|
||||
constant kRxCh1_0_RxOnMask : std_logic_vector(15 downto 0) := X"0000";
|
||||
|
||||
-- RxCh1_1_RxOn Register (from TopCpld.vhd)
|
||||
constant kRxCh1_1_RxOn : integer := 16#55#; -- Register Offset
|
||||
constant kRxCh1_1_RxOnSize: integer := 16; -- register width in bits
|
||||
constant kRxCh1_1_RxOnMask : std_logic_vector(15 downto 0) := X"0000";
|
||||
|
||||
-- TxCh2_Idle Register (from TopCpld.vhd)
|
||||
constant kTxCh2_Idle : integer := 16#60#; -- Register Offset
|
||||
constant kTxCh2_IdleSize: integer := 16; -- register width in bits
|
||||
constant kTxCh2_IdleMask : std_logic_vector(15 downto 0) := X"0000";
|
||||
|
||||
-- RxCh2_0_Idle Register (from TopCpld.vhd)
|
||||
constant kRxCh2_0_Idle : integer := 16#61#; -- Register Offset
|
||||
constant kRxCh2_0_IdleSize: integer := 16; -- register width in bits
|
||||
constant kRxCh2_0_IdleMask : std_logic_vector(15 downto 0) := X"0000";
|
||||
|
||||
-- RxCh2_1_Idle Register (from TopCpld.vhd)
|
||||
constant kRxCh2_1_Idle : integer := 16#62#; -- Register Offset
|
||||
constant kRxCh2_1_IdleSize: integer := 16; -- register width in bits
|
||||
constant kRxCh2_1_IdleMask : std_logic_vector(15 downto 0) := X"0000";
|
||||
|
||||
-- TxCh2_TxOn Register (from TopCpld.vhd)
|
||||
constant kTxCh2_TxOn : integer := 16#63#; -- Register Offset
|
||||
constant kTxCh2_TxOnSize: integer := 16; -- register width in bits
|
||||
constant kTxCh2_TxOnMask : std_logic_vector(15 downto 0) := X"0000";
|
||||
|
||||
-- RxCh2_0_RxOn Register (from TopCpld.vhd)
|
||||
constant kRxCh2_0_RxOn : integer := 16#64#; -- Register Offset
|
||||
constant kRxCh2_0_RxOnSize: integer := 16; -- register width in bits
|
||||
constant kRxCh2_0_RxOnMask : std_logic_vector(15 downto 0) := X"0000";
|
||||
|
||||
-- RxCh2_1_RxOn Register (from TopCpld.vhd)
|
||||
constant kRxCh2_1_RxOn : integer := 16#65#; -- Register Offset
|
||||
constant kRxCh2_1_RxOnSize: integer := 16; -- register width in bits
|
||||
constant kRxCh2_1_RxOnMask : std_logic_vector(15 downto 0) := X"0000";
|
||||
|
||||
end package;
|
||||
|
||||
package body PkgMgCpld is
|
||||
|
||||
-- function kSignatureRegRec not implemented because PkgXReg in this project does not support XReg2_t.
|
||||
|
||||
-- function kMinorRevRegRec not implemented because PkgXReg in this project does not support XReg2_t.
|
||||
|
||||
-- function kMajorRevRegRec not implemented because PkgXReg in this project does not support XReg2_t.
|
||||
|
||||
-- function kBuildCodeLSBRec not implemented because PkgXReg in this project does not support XReg2_t.
|
||||
|
||||
-- function kBuildCodeMSBRec not implemented because PkgXReg in this project does not support XReg2_t.
|
||||
|
||||
-- function kScratchRec not implemented because PkgXReg in this project does not support XReg2_t.
|
||||
|
||||
-- function kCpldControlRec not implemented because PkgXReg in this project does not support XReg2_t.
|
||||
|
||||
-- function kLmkControlRec not implemented because PkgXReg in this project does not support XReg2_t.
|
||||
|
||||
-- function kLoStatusRec not implemented because PkgXReg in this project does not support XReg2_t.
|
||||
|
||||
-- function kMykonosControlRec not implemented because PkgXReg in this project does not support XReg2_t.
|
||||
|
||||
-- function kPlScratchRec not implemented because PkgXReg in this project does not support XReg2_t.
|
||||
|
||||
-- function kPlCpldControlRec not implemented because PkgXReg in this project does not support XReg2_t.
|
||||
|
||||
-- function kTxCh1_IdleRec not implemented because PkgXReg in this project does not support XReg2_t.
|
||||
|
||||
-- function kRxCh1_0_IdleRec not implemented because PkgXReg in this project does not support XReg2_t.
|
||||
|
||||
-- function kRxCh1_1_IdleRec not implemented because PkgXReg in this project does not support XReg2_t.
|
||||
|
||||
-- function kTxCh1_TxOnRec not implemented because PkgXReg in this project does not support XReg2_t.
|
||||
|
||||
-- function kRxCh1_0_RxOnRec not implemented because PkgXReg in this project does not support XReg2_t.
|
||||
|
||||
-- function kRxCh1_1_RxOnRec not implemented because PkgXReg in this project does not support XReg2_t.
|
||||
|
||||
-- function kTxCh2_IdleRec not implemented because PkgXReg in this project does not support XReg2_t.
|
||||
|
||||
-- function kRxCh2_0_IdleRec not implemented because PkgXReg in this project does not support XReg2_t.
|
||||
|
||||
-- function kRxCh2_1_IdleRec not implemented because PkgXReg in this project does not support XReg2_t.
|
||||
|
||||
-- function kTxCh2_TxOnRec not implemented because PkgXReg in this project does not support XReg2_t.
|
||||
|
||||
-- function kRxCh2_0_RxOnRec not implemented because PkgXReg in this project does not support XReg2_t.
|
||||
|
||||
-- function kRxCh2_1_RxOnRec not implemented because PkgXReg in this project does not support XReg2_t.
|
||||
|
||||
end package body;
|
||||
@@ -0,0 +1,259 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- File: PkgSetup.vhd
|
||||
-- Author: Daniel Jepson
|
||||
-- Original Project: N310
|
||||
-- Date: 22 September 2017
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
-- Copyright 2016-2017 Ettus Research, A National Instruments Company
|
||||
-- SPDX-License-Identifier: GPL-3.0
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Purpose:
|
||||
--
|
||||
-- Default values for front end config and CPLD constants.
|
||||
--
|
||||
-- Contains the revision constants that must be bumped when the CPLD is updated.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.PkgMgCpld.all;
|
||||
|
||||
package PkgSetup is
|
||||
|
||||
|
||||
constant kRdWtWidth : integer := 1;
|
||||
constant kAddrWidth : integer := 7;
|
||||
constant kDataWidth : integer := 16;
|
||||
constant kTotalWidth : integer := kRdWtWidth + kAddrWidth + kDataWidth;
|
||||
|
||||
subtype InterfaceData_t is std_logic_vector(kDataWidth-1 downto 0);
|
||||
|
||||
constant kSignature : InterfaceData_t := x"CAFE";
|
||||
|
||||
|
||||
-- UPDATE THESE REVISIONS when making changes to the CPLD -----------------------------
|
||||
-- ------------------------------------------------------------------------------------
|
||||
constant kMinorRev : InterfaceData_t := std_logic_vector(to_unsigned(0,kDataWidth));
|
||||
constant kMajorRev : InterfaceData_t := std_logic_vector(to_unsigned(5,kDataWidth));
|
||||
-- Currently just the timestamp of the build time/date: yymmddhh
|
||||
constant kBuildCode : std_logic_vector(31 downto 0) := X"18010408";
|
||||
|
||||
|
||||
function kTxChDefault return InterfaceData_t;
|
||||
function kTxChDefaultRun return InterfaceData_t;
|
||||
function kRxChDefault0 return InterfaceData_t;
|
||||
function kRxChDefault1 return InterfaceData_t;
|
||||
function kRxChDefault0Run return InterfaceData_t;
|
||||
function kRxChDefault1Run return InterfaceData_t;
|
||||
|
||||
function Tx2Switch2Mod(kCh1Val : std_logic_vector) return std_logic_vector;
|
||||
function Tx2TrxMod (kCh1Val : std_logic_vector) return std_logic_vector;
|
||||
|
||||
function Rx2Switch1Mod(kCh1Val : std_logic_vector) return std_logic_vector;
|
||||
function Rx2Switch2Mod(kCh1Val : std_logic_vector) return std_logic_vector;
|
||||
function Rx2Switch3Mod(kCh1Val : std_logic_vector) return std_logic_vector;
|
||||
function Rx2Switch4Mod(kCh1Val : std_logic_vector) return std_logic_vector;
|
||||
function Rx2Switch5Mod(kCh1Val : std_logic_vector) return std_logic_vector;
|
||||
function Rx2Switch6Mod(kCh1Val : std_logic_vector) return std_logic_vector;
|
||||
|
||||
|
||||
end package;
|
||||
|
||||
package body PkgSetup is
|
||||
|
||||
function kTxChDefault return InterfaceData_t is
|
||||
variable RetVal : InterfaceData_t := (others => '0');
|
||||
begin
|
||||
RetVal(kCh1SwTrxMsb downto kCh1SwTrx) := std_logic_vector(to_unsigned(kFromLowerFilterBankTxSw1, kCh1SwTrxSize));
|
||||
RetVal(kCh1TxSw1Msb downto kCh1TxSw1) := std_logic_vector(to_unsigned(kShutdownTxSw1, kCh1TxSw1Size));
|
||||
RetVal(kCh1TxSw2Msb downto kCh1TxSw2) := std_logic_vector(to_unsigned(kToTxFilterLp3400MHz, kCh1TxSw2Size));
|
||||
RetVal(kCh1TxSw3 downto kCh1TxSw3) := std_logic_vector(to_unsigned(kToTxFilterBanks, kCh1TxSw3Size));
|
||||
RetVal(kCh1TxLowbandMixerPathSelect) := '0';
|
||||
RetVal(kCh1TxMixerEn) := '0';
|
||||
RetVal(kCh1TxAmpEn) := '0';
|
||||
RetVal(kCh1TxPaEn) := '0';
|
||||
RetVal(kCh1TxLed) := '0';
|
||||
RetVal(kCh1MykEnTx) := '1';
|
||||
return RetVal;
|
||||
end kTxChDefault;
|
||||
|
||||
function kTxChDefaultRun return InterfaceData_t is
|
||||
variable RetVal : InterfaceData_t := (others => '0');
|
||||
begin
|
||||
RetVal(kCh1SwTrxMsb downto kCh1SwTrx) := std_logic_vector(to_unsigned(kFromLowerFilterBankTxSw1, kCh1SwTrxSize));
|
||||
RetVal(kCh1TxSw1Msb downto kCh1TxSw1) := std_logic_vector(to_unsigned(kFromTxFilterLp3400MHz, kCh1TxSw1Size));
|
||||
RetVal(kCh1TxSw2Msb downto kCh1TxSw2) := std_logic_vector(to_unsigned(kToTxFilterLp3400MHz, kCh1TxSw2Size));
|
||||
RetVal(kCh1TxSw3 downto kCh1TxSw3) := std_logic_vector(to_unsigned(kToTxFilterBanks, kCh1TxSw3Size));
|
||||
RetVal(kCh1TxLowbandMixerPathSelect) := '0';
|
||||
RetVal(kCh1TxMixerEn) := '0';
|
||||
RetVal(kCh1TxAmpEn) := '1';
|
||||
RetVal(kCh1TxPaEn) := '1';
|
||||
RetVal(kCh1TxLed) := '1';
|
||||
RetVal(kCh1MykEnTx) := '1';
|
||||
return RetVal;
|
||||
end kTxChDefaultRun;
|
||||
|
||||
|
||||
|
||||
|
||||
function kRxChDefault0 return InterfaceData_t is
|
||||
variable RetVal : InterfaceData_t := (others => '0');
|
||||
begin
|
||||
RetVal(kCh1RxSw1Msb downto kCh1RxSw1) := std_logic_vector(to_unsigned(kRx2Input, kCh1RxSw1Size));
|
||||
RetVal(kCh1RxSw2Msb downto kCh1RxSw2) := std_logic_vector(to_unsigned(kShutdownSw2, kCh1RxSw2Size));
|
||||
RetVal(kCh1RxSw3Msb downto kCh1RxSw3) := std_logic_vector(to_unsigned(kShutdownSw3, kCh1RxSw3Size));
|
||||
RetVal(kCh1RxSw4Msb downto kCh1RxSw4) := std_logic_vector(to_unsigned(kFilter2100x2850MHzFrom, kCh1RxSw4Size));
|
||||
RetVal(kCh1RxSw5Msb downto kCh1RxSw5) := std_logic_vector(to_unsigned(kFilter0490LpMHzFrom, kCh1RxSw5Size));
|
||||
return RetVal;
|
||||
end kRxChDefault0;
|
||||
|
||||
function kRxChDefault1 return InterfaceData_t is
|
||||
variable RetVal : InterfaceData_t := (others => '0');
|
||||
begin
|
||||
RetVal(kCh1RxSw6Msb downto kCh1RxSw6) := std_logic_vector(to_unsigned(kUpperFilterBankFromSwitch4, kCh1RxSw6Size));
|
||||
RetVal(kCh1RxLowbandMixerPathSelect) := '0';
|
||||
RetVal(kCh1RxMixerEn) := '0';
|
||||
RetVal(kCh1RxAmpEn) := '0';
|
||||
RetVal(kCh1RxLna1En) := '0';
|
||||
RetVal(kCh1RxLna2En) := '0';
|
||||
RetVal(kCh1Rx2Led) := '0';
|
||||
RetVal(kCh1RxLed) := '0';
|
||||
RetVal(kCh1MykEnRx) := '1';
|
||||
return RetVal;
|
||||
end kRxChDefault1;
|
||||
|
||||
function kRxChDefault0Run return InterfaceData_t is
|
||||
variable RetVal : InterfaceData_t := (others => '0');
|
||||
begin
|
||||
RetVal(kCh1RxSw1Msb downto kCh1RxSw1) := std_logic_vector(to_unsigned(kRx2Input, kCh1RxSw1Size));
|
||||
RetVal(kCh1RxSw2Msb downto kCh1RxSw2) := std_logic_vector(to_unsigned(kLowerFilterBankToSwitch3, kCh1RxSw2Size));
|
||||
RetVal(kCh1RxSw3Msb downto kCh1RxSw3) := std_logic_vector(to_unsigned(kFilter2100x2850MHz, kCh1RxSw3Size));
|
||||
RetVal(kCh1RxSw4Msb downto kCh1RxSw4) := std_logic_vector(to_unsigned(kFilter2100x2850MHzFrom, kCh1RxSw4Size));
|
||||
RetVal(kCh1RxSw5Msb downto kCh1RxSw5) := std_logic_vector(to_unsigned(kFilter0490LpMHzFrom, kCh1RxSw5Size));
|
||||
return RetVal;
|
||||
end kRxChDefault0Run;
|
||||
|
||||
function kRxChDefault1Run return InterfaceData_t is
|
||||
variable RetVal : InterfaceData_t := (others => '0');
|
||||
begin
|
||||
RetVal(kCh1RxSw6Msb downto kCh1RxSw6) := std_logic_vector(to_unsigned(kUpperFilterBankFromSwitch4, kCh1RxSw6Size));
|
||||
RetVal(kCh1RxLowbandMixerPathSelect) := '0';
|
||||
RetVal(kCh1RxMixerEn) := '0';
|
||||
RetVal(kCh1RxAmpEn) := '1';
|
||||
RetVal(kCh1RxLna1En) := '1';
|
||||
RetVal(kCh1RxLna2En) := '1';
|
||||
RetVal(kCh1Rx2Led) := '1'; -- turn on a LED for grins
|
||||
RetVal(kCh1RxLed) := '0';
|
||||
RetVal(kCh1MykEnRx) := '1';
|
||||
return RetVal;
|
||||
end kRxChDefault1Run;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function Tx2Switch2Mod(kCh1Val : std_logic_vector) return std_logic_vector is
|
||||
variable RetVal : std_logic_vector(kCh1Val'range) := (others => '0');
|
||||
begin
|
||||
-- Encoding for this switch is one-hot, so we just flip around the bits here.
|
||||
RetVal(kCh1Val'low + 0) := kCh1Val(kCh1Val'low + 0);
|
||||
RetVal(kCh1Val'low + 3) := kCh1Val(kCh1Val'low + 1);
|
||||
RetVal(kCh1Val'low + 1) := kCh1Val(kCh1Val'low + 2);
|
||||
RetVal(kCh1Val'low + 2) := kCh1Val(kCh1Val'low + 3);
|
||||
return RetVal;
|
||||
end Tx2Switch2Mod;
|
||||
|
||||
function Tx2TrxMod(kCh1Val : std_logic_vector) return std_logic_vector is
|
||||
variable RetVal : std_logic_vector(kCh1Val'range) := (others => '0');
|
||||
begin
|
||||
if kCh1Val = "00" then RetVal := "00";
|
||||
elsif kCh1Val = "01" then RetVal := "10";
|
||||
elsif kCh1Val = "10" then RetVal := "01";
|
||||
elsif kCh1Val = "11" then RetVal := "11";
|
||||
else RetVal := "00"; end if;
|
||||
return RetVal;
|
||||
end Tx2TrxMod;
|
||||
|
||||
|
||||
|
||||
function Rx2Switch1Mod(kCh1Val : std_logic_vector) return std_logic_vector is
|
||||
variable RetVal : std_logic_vector(kCh1Val'range) := (others => '0');
|
||||
begin
|
||||
-- Encoding for this switch is binary, so we need to mux.
|
||||
if kCh1Val = "00" then RetVal := "01";
|
||||
elsif kCh1Val = "01" then RetVal := "00";
|
||||
elsif kCh1Val = "10" then RetVal := "11";
|
||||
elsif kCh1Val = "11" then RetVal := "10";
|
||||
else RetVal := "00"; end if;
|
||||
return RetVal;
|
||||
end Rx2Switch1Mod;
|
||||
|
||||
function Rx2Switch2Mod(kCh1Val : std_logic_vector) return std_logic_vector is
|
||||
variable RetVal : std_logic_vector(kCh1Val'range) := (others => '0');
|
||||
begin
|
||||
-- Encoding for this switch is binary, so we need to mux.
|
||||
if kCh1Val = "00" then RetVal := "00";
|
||||
elsif kCh1Val = "01" then RetVal := "11";
|
||||
elsif kCh1Val = "10" then RetVal := "10";
|
||||
elsif kCh1Val = "11" then RetVal := "01";
|
||||
else RetVal := "00"; end if;
|
||||
return RetVal;
|
||||
end Rx2Switch2Mod;
|
||||
|
||||
function Rx2Switch3Mod(kCh1Val : std_logic_vector) return std_logic_vector is
|
||||
variable RetVal : std_logic_vector(kCh1Val'range) := (others => '0');
|
||||
begin
|
||||
-- Encoding for this switch is binary, so we need to mux.
|
||||
if kCh1Val = "000" then RetVal := "100";
|
||||
elsif kCh1Val = "001" then RetVal := "101";
|
||||
elsif kCh1Val = "010" then RetVal := "110";
|
||||
elsif kCh1Val = "011" then RetVal := "011";
|
||||
elsif kCh1Val = "100" then RetVal := "001";
|
||||
elsif kCh1Val = "101" then RetVal := "000";
|
||||
elsif kCh1Val = "110" then RetVal := "010";
|
||||
elsif kCh1Val = "111" then RetVal := "111";
|
||||
else RetVal := "000"; end if;
|
||||
return RetVal;
|
||||
end Rx2Switch3Mod;
|
||||
|
||||
function Rx2Switch4Mod(kCh1Val : std_logic_vector) return std_logic_vector is
|
||||
variable RetVal : std_logic_vector(kCh1Val'range) := (others => '0');
|
||||
begin
|
||||
-- Encoding for this switch is one-hot, so we just flip around the bits here.
|
||||
RetVal(kCh1Val'low + 2) := kCh1Val(kCh1Val'low + 0);
|
||||
RetVal(kCh1Val'low + 1) := kCh1Val(kCh1Val'low + 1);
|
||||
RetVal(kCh1Val'low + 0) := kCh1Val(kCh1Val'low + 2);
|
||||
return RetVal;
|
||||
end Rx2Switch4Mod;
|
||||
|
||||
function Rx2Switch5Mod(kCh1Val : std_logic_vector) return std_logic_vector is
|
||||
variable RetVal : std_logic_vector(kCh1Val'range) := (others => '0');
|
||||
begin
|
||||
-- Encoding for this switch is one-hot, so we just flip around the bits here.
|
||||
RetVal(kCh1Val'low + 1) := kCh1Val(kCh1Val'low + 0);
|
||||
RetVal(kCh1Val'low + 0) := kCh1Val(kCh1Val'low + 1);
|
||||
RetVal(kCh1Val'low + 3) := kCh1Val(kCh1Val'low + 2);
|
||||
RetVal(kCh1Val'low + 2) := kCh1Val(kCh1Val'low + 3);
|
||||
return RetVal;
|
||||
end Rx2Switch5Mod;
|
||||
|
||||
function Rx2Switch6Mod(kCh1Val : std_logic_vector) return std_logic_vector is
|
||||
variable RetVal : std_logic_vector(kCh1Val'range) := (others => '0');
|
||||
begin
|
||||
-- Encoding for this switch is one-hot, so we just flip around the bits here.
|
||||
RetVal(kCh1Val'low + 2) := kCh1Val(kCh1Val'low + 0);
|
||||
RetVal(kCh1Val'low + 1) := kCh1Val(kCh1Val'low + 1);
|
||||
RetVal(kCh1Val'low + 0) := kCh1Val(kCh1Val'low + 2);
|
||||
return RetVal;
|
||||
end Rx2Switch6Mod;
|
||||
|
||||
|
||||
end package body;
|
||||
@@ -0,0 +1,160 @@
|
||||
#
|
||||
# Copyright 2017 Ettus Research, A National Instruments Company
|
||||
# SPDX-License-Identifier: LGPL-3.0
|
||||
#
|
||||
|
||||
# All the magic numbers come from the "/n3xx/dboards/mg/doc/mg_timing.xlsx" timing
|
||||
# analysis spreadsheet. Analysis should be re-performed every time a board rev occurs
|
||||
# that affects the CPLD interfaces.
|
||||
|
||||
## PS Slave Constraints #################################################################
|
||||
# - PsClk Rate
|
||||
# - PsClk to SDI
|
||||
# - PsClk to LE (sync and async paths)
|
||||
# - PsClk to SDO
|
||||
|
||||
# Maximum 4 MHz clock rate! This is heavily limited by the read data turnaround time...
|
||||
# and could be up to 20 MHz if only performing writes.
|
||||
create_clock -name PsClk -period 250 [get_ports {PsSpiSck}]
|
||||
|
||||
# SDI is both registered in the CPLD and used as a direct passthrough. First constrain
|
||||
# the input delay on the local paths inside the CPLD. Passthrough constraints
|
||||
# are handled elsewhere.
|
||||
|
||||
set PsSdiInputDelayMax 22.303
|
||||
set PsSdiInputDelayMin -19.019
|
||||
|
||||
# SDI is driven from the PS on the falling edge of the Clk. Worst-case data-clock skew
|
||||
# is around +/-20ns due to FPGA routing delays and board buffering. Complete timing
|
||||
# analysis is performed and recorded elsewhere.
|
||||
set_input_delay -clock PsClk -max $PsSdiInputDelayMax [get_ports sPsSpiSdi] -clock_fall
|
||||
set_input_delay -clock PsClk -min $PsSdiInputDelayMin [get_ports sPsSpiSdi] -clock_fall
|
||||
|
||||
# For the CPLD Cs_n, the latch enable is used both as an asynchronous reset and
|
||||
# synchronously to latch data. First, constrain the overall input delay for sync use.
|
||||
# Technically, Cs_n is asserted and de-asserted many nanoseconds before the clock arrives
|
||||
# but we still constrain it identically to the SDI in case something goes amiss.
|
||||
set_input_delay -clock PsClk -max $PsSdiInputDelayMax [get_ports sPsSpiLe] -clock_fall
|
||||
set_input_delay -clock PsClk -min $PsSdiInputDelayMin [get_ports sPsSpiLe] -clock_fall
|
||||
# Then set a false path only on the async reset flops.
|
||||
set_false_path -from [get_ports {sPsSpiLe}] -to [get_pins sPsMosiIndex[*]|*]
|
||||
set_false_path -from [get_ports {sPsSpiLe}] -to [get_pins sPsMisoIndex[*]|*]
|
||||
|
||||
# Constrain MISO as snugly as possible through the CPLD without making the tools work
|
||||
# too hard. At a 200 ns period, this sets the clock-to-out for the CPLD at [10, 65]ns.
|
||||
# Math for Max = T_clk/2 - 60 = 250/2 - 60 = 65 ns.
|
||||
set PsSdoOutputDelayMax 60
|
||||
set PsSdoOutputDelayMin -10
|
||||
|
||||
set_output_delay -clock PsClk -max $PsSdoOutputDelayMax [get_ports sPsSpiSdo]
|
||||
set_output_delay -clock PsClk -min $PsSdoOutputDelayMin [get_ports sPsSpiSdo]
|
||||
|
||||
|
||||
|
||||
## PL Slave Constraints #################################################################
|
||||
# - PlClk Rate
|
||||
# - PlClk to SDI
|
||||
# - PlClk to LE (sync and async paths)
|
||||
# - PlClk to SDO
|
||||
|
||||
# Maximum 5 MHz clock rate!
|
||||
create_clock -name PlClk -period 200 [get_ports {PlSpiSck}]
|
||||
|
||||
# SDI is both registered in the CPLD and used as a direct passthrough. First constrain
|
||||
# the input delay on the local paths inside the CPLD. Passthrough constraints
|
||||
# are handled elsewhere.
|
||||
|
||||
set PlSdiInputDelayMax 10.445
|
||||
set PlSdiInputDelayMin -10.378
|
||||
|
||||
# SDI is driven from the FPGA on the falling edge of the Clk. Worst-case data-clock skew
|
||||
# is around +/-10ns. Complete timing analysis is performed and recorded elsewhere.
|
||||
set_input_delay -clock PlClk -max $PlSdiInputDelayMax [get_ports lPlSpiSdi] -clock_fall
|
||||
set_input_delay -clock PlClk -min $PlSdiInputDelayMin [get_ports lPlSpiSdi] -clock_fall
|
||||
|
||||
# For the CPLD Cs_n, the latch enable is used both as an asynchronous reset and
|
||||
# synchronously to latch data. First, constrain the overall input delay for sync use.
|
||||
# Technically, Cs_n is asserted and de-asserted many nanoseconds before the clock arrives
|
||||
# but we still constrain it identically to the SDI in case something goes amiss.
|
||||
set_input_delay -clock PlClk -max $PlSdiInputDelayMax [get_ports lPlSpiLe] -clock_fall
|
||||
set_input_delay -clock PlClk -min $PlSdiInputDelayMin [get_ports lPlSpiLe] -clock_fall
|
||||
# Then set a false path only on the async reset flops.
|
||||
set_false_path -from [get_ports {lPlSpiLe}] -to [get_pins {lPlMosiIndex[*]|*}]
|
||||
set_false_path -from [get_ports {lPlSpiLe}] -to [get_pins {lPlMisoIndex[*]|*}]
|
||||
|
||||
# Constrain MISO as snugly as possible through the CPLD without making the tools work
|
||||
# too hard. At a 200 ns period, this sets the clock-to-out for the CPLD at [10, 65]ns.
|
||||
# Math for Max = T_clk/2 - 35 = 200/2 - 35 = 65 ns.
|
||||
set PlSdoOutputDelayMax 35
|
||||
set PlSdoOutputDelayMin -10
|
||||
|
||||
set_output_delay -clock PlClk -max $PlSdoOutputDelayMax [get_ports lPlSpiSdo]
|
||||
set_output_delay -clock PlClk -min $PlSdoOutputDelayMin [get_ports lPlSpiSdo]
|
||||
|
||||
|
||||
|
||||
## Passthrough Constraints ##############################################################
|
||||
# - LMK SYNC
|
||||
# - PlClk/PsClk passthrough
|
||||
# - SDI passthrough for both
|
||||
# - SDO return mux passthrough for both
|
||||
# - Cs_n passthrough for both
|
||||
|
||||
# LMK Sync Passthrough: constrain min and max delays for output
|
||||
set_max_delay -from [get_ports {aPlSpiAddr[2]}] -to [get_ports {aLmkSync}] 17
|
||||
set_min_delay -from [get_ports {aPlSpiAddr[2]}] -to [get_ports {aLmkSync}] 2
|
||||
|
||||
# SPI Passthroughs: constrain min and max delays for outputs and inputs.
|
||||
# Since the SDI ports have input delays pre-defined above, we have to remove those from
|
||||
# the delay analysis here by adding the input delay to the constraint.
|
||||
# Similarly, for the SDO pins add the output delay to the constraint.
|
||||
set SpiMaxDelay 25
|
||||
set SpiMinDelay 5
|
||||
|
||||
# PS
|
||||
set_max_delay -to [get_ports {aDacDin aLmkSpiSdio}] [expr $PsSdiInputDelayMax + $SpiMaxDelay]
|
||||
set_min_delay -to [get_ports {aDacDin aLmkSpiSdio}] [expr $PsSdiInputDelayMin + $SpiMinDelay]
|
||||
set_max_delay -to [get_ports {aDacSync_n aLmkSpiCs_n}] $SpiMaxDelay
|
||||
set_min_delay -to [get_ports {aDacSync_n aLmkSpiCs_n}] $SpiMinDelay
|
||||
set_max_delay -to [get_ports {aDacSck aLmkSpiSck}] $SpiMaxDelay
|
||||
set_min_delay -to [get_ports {aDacSck aLmkSpiSck}] $SpiMinDelay
|
||||
set_max_delay -from [get_ports {aLmkClkinSel*}] [expr $SpiMaxDelay + $PsSdoOutputDelayMax]
|
||||
set_min_delay -from [get_ports {aLmkClkinSel*}] [expr $SpiMinDelay + $PsSdoOutputDelayMin]
|
||||
|
||||
# PL
|
||||
set_max_delay -to [get_ports {aRxLoDin aTxLoDin}] [expr $PlSdiInputDelayMax + $SpiMaxDelay]
|
||||
set_min_delay -to [get_ports {aRxLoDin aTxLoDin}] [expr $PlSdiInputDelayMin + $SpiMinDelay]
|
||||
set_max_delay -to [get_ports {aRxLoCs_n aTxLoCs_n}] $SpiMaxDelay
|
||||
set_min_delay -to [get_ports {aRxLoCs_n aTxLoCs_n}] $SpiMinDelay
|
||||
set_max_delay -to [get_ports {aRxLoSck aTxLoSck}] $SpiMaxDelay
|
||||
set_min_delay -to [get_ports {aRxLoSck aTxLoSck}] $SpiMinDelay
|
||||
set_max_delay -from [get_ports {aTxLoMuxOut aRxLoMuxOut}] [expr $SpiMaxDelay + $PlSdoOutputDelayMax]
|
||||
set_min_delay -from [get_ports {aTxLoMuxOut aRxLoMuxOut}] [expr $SpiMinDelay + $PlSdoOutputDelayMin]
|
||||
|
||||
|
||||
|
||||
## Async Inputs #########################################################################
|
||||
# aLmkStatus2 aRxLoLockDetect aTxLoLockDetect
|
||||
set_false_path -from [get_ports {aRxLoLockDetect}]
|
||||
set_false_path -from [get_ports {aTxLoLockDetect}]
|
||||
|
||||
|
||||
|
||||
## Async Outputs ########################################################################
|
||||
# aMkReset_n aVcxoCtrl
|
||||
set_false_path -to [get_ports {aMkReset_n}]
|
||||
set_false_path -to [get_ports {aVcxoCtrl}]
|
||||
|
||||
|
||||
|
||||
## Sync Front End Outputs ###############################################################
|
||||
# All we need to do here is constrain for maximum path delay from the aAtr(Rx|Tx)(1|2)
|
||||
# control bits toggling to the outputs for aCh1* and aCh2* toggling. Just in case the
|
||||
# user attempts to write the ATR while it's in use, we also constrain from the flops
|
||||
# to the pins... which covers all paths... so just to -to option is needed.
|
||||
set_max_delay -to [get_ports {aCh1* aCh2* aMk*x*En}] 40
|
||||
set_min_delay -to [get_ports {aCh1* aCh2* aMk*x*En}] 5
|
||||
|
||||
# We don't care about the LED timing whatsoever. Let's not have them clogging up our
|
||||
# precious timing paths.
|
||||
set_false_path -to [get_ports {aCh*Led*}]
|
||||
@@ -0,0 +1,31 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Copyright (C) 2017 Intel Corporation. All rights reserved.
|
||||
# Your use of Intel Corporation's design tools, logic functions
|
||||
# and other software and tools, and its AMPP partner logic
|
||||
# functions, and any output files from any of the foregoing
|
||||
# (including device programming or simulation files), and any
|
||||
# associated documentation or information are expressly subject
|
||||
# to the terms and conditions of the Intel Program License
|
||||
# Subscription Agreement, the Intel Quartus Prime License Agreement,
|
||||
# the Intel MegaCore Function License Agreement, or other
|
||||
# applicable license agreement, including, without limitation,
|
||||
# that your use is for the sole purpose of programming logic
|
||||
# devices manufactured by Intel and sold by Intel or its
|
||||
# authorized distributors. Please refer to the applicable
|
||||
# agreement for further details.
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Quartus Prime
|
||||
# Version 16.1.2 Build 203 01/18/2017 SJ Standard Edition
|
||||
# Date created = 14:51:27 February 24, 2017
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
|
||||
QUARTUS_VERSION = "16.1"
|
||||
DATE = "14:51:27 February 24, 2017"
|
||||
|
||||
# Revisions
|
||||
|
||||
PROJECT_REVISION = "TopCpld"
|
||||
@@ -0,0 +1,313 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Copyright (C) 2017 Intel Corporation. All rights reserved.
|
||||
# Your use of Intel Corporation's design tools, logic functions
|
||||
# and other software and tools, and its AMPP partner logic
|
||||
# functions, and any output files from any of the foregoing
|
||||
# (including device programming or simulation files), and any
|
||||
# associated documentation or information are expressly subject
|
||||
# to the terms and conditions of the Intel Program License
|
||||
# Subscription Agreement, the Intel Quartus Prime License Agreement,
|
||||
# the Intel MegaCore Function License Agreement, or other
|
||||
# applicable license agreement, including, without limitation,
|
||||
# that your use is for the sole purpose of programming logic
|
||||
# devices manufactured by Intel and sold by Intel or its
|
||||
# authorized distributors. Please refer to the applicable
|
||||
# agreement for further details.
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Quartus Prime
|
||||
# Version 16.1.2 Build 203 01/18/2017 SJ Standard Edition
|
||||
# Date created = 14:51:27 February 24, 2017
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Notes:
|
||||
#
|
||||
# 1) The default values for assignments are stored in the file:
|
||||
# TopCpld_assignment_defaults.qdf
|
||||
# If this file doesn't exist, see file:
|
||||
# assignment_defaults.qdf
|
||||
#
|
||||
# 2) Altera recommends that you do not modify this file. This
|
||||
# file is updated automatically by the Quartus Prime software
|
||||
# and any changes you make may be lost or overwritten.
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
|
||||
|
||||
set_global_assignment -name FAMILY "MAX V"
|
||||
set_global_assignment -name DEVICE 5M570ZF256I5
|
||||
set_global_assignment -name ORIGINAL_QUARTUS_VERSION 16.1.2
|
||||
set_global_assignment -name PROJECT_CREATION_TIME_DATE "14:51:27 FEBRUARY 24, 2017"
|
||||
set_global_assignment -name LAST_QUARTUS_VERSION "16.1.2 Lite Edition"
|
||||
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
|
||||
set_global_assignment -name MIN_CORE_JUNCTION_TEMP "-40"
|
||||
set_global_assignment -name MAX_CORE_JUNCTION_TEMP 125
|
||||
set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR "-1"
|
||||
set_global_assignment -name SDC_FILE Timing.sdc
|
||||
set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "NO HEAT SINK WITH STILL AIR"
|
||||
set_global_assignment -name AUTO_RESTART_CONFIGURATION OFF
|
||||
set_global_assignment -name ENABLE_OCT_DONE OFF
|
||||
set_global_assignment -name ENABLE_CONFIGURATION_PINS OFF
|
||||
set_global_assignment -name ENABLE_BOOT_SEL_PIN OFF
|
||||
set_global_assignment -name STRATIXV_CONFIGURATION_SCHEME "PASSIVE SERIAL"
|
||||
set_global_assignment -name USE_CONFIGURATION_DEVICE ON
|
||||
set_global_assignment -name GENERATE_SVF_FILE ON
|
||||
set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS OFF
|
||||
set_global_assignment -name RESERVE_ALL_UNUSED_PINS "AS INPUT TRI-STATED"
|
||||
|
||||
set_location_assignment PIN_C3 -to aCh2RxSw4[0]
|
||||
set_location_assignment PIN_C2 -to aCh2TxPaEn
|
||||
set_location_assignment PIN_D3 -to aCh2RxSw6[0]
|
||||
set_location_assignment PIN_D1 -to aCh2RxSw4[1]
|
||||
set_location_assignment PIN_D2 -to aCh2TxSw3
|
||||
set_location_assignment PIN_E1 -to aCh2RxSw4[2]
|
||||
set_location_assignment PIN_E4 -to aCh2RxSw7[1]
|
||||
set_location_assignment PIN_F2 -to aCh2RxSw6[1]
|
||||
set_location_assignment PIN_E3 -to aCh2RxSw7[0]
|
||||
set_location_assignment PIN_F1 -to aCh2RxSw5[0]
|
||||
set_location_assignment PIN_E2 -to aCh2RxSw5[1]
|
||||
set_location_assignment PIN_G2 -to aCh2RxSw5[3]
|
||||
set_location_assignment PIN_F3 -to aCh2TxSw4[0]
|
||||
set_location_assignment PIN_G1 -to aCh2RxSw6[2]
|
||||
set_location_assignment PIN_G3 -to aCh2TxSw4[1]
|
||||
set_location_assignment PIN_H2 -to aCh2TxAmpEn
|
||||
set_location_assignment PIN_H1 -to aCh2RxSw5[2]
|
||||
set_location_assignment PIN_J1 -to aCh2TxMixerEn
|
||||
set_location_assignment PIN_H5 -to aLoSpiSync
|
||||
set_location_assignment PIN_J2 -to aCh2RxMixerEn
|
||||
#set_location_assignment PIN_L3 -to aLmkSpiSdio
|
||||
set_location_assignment PIN_K1 -to aCh2TxSw5[1]
|
||||
set_location_assignment PIN_K2 -to aCh2TxSw5[0]
|
||||
set_location_assignment PIN_M2 -to aLmkSpiSdio
|
||||
set_location_assignment PIN_L1 -to aCh2RxSw8[0]
|
||||
set_location_assignment PIN_M3 -to lPlSpiSdi
|
||||
set_location_assignment PIN_L2 -to aCh2RxSw8[1]
|
||||
set_location_assignment PIN_M1 -to aCh2RxAmpEn
|
||||
set_location_assignment PIN_N2 -to aLmkSpiSck
|
||||
set_location_assignment PIN_N1 -to aLmkSpiCs_n
|
||||
set_location_assignment PIN_N3 -to PlSpiSck
|
||||
# set_location_assignment PIN_P2 -to lPlSpiLe
|
||||
set_location_assignment PIN_R3 -to aMkReset_n
|
||||
set_location_assignment PIN_R1 -to lPlSpiLe
|
||||
set_location_assignment PIN_T2 -to aLmkSync
|
||||
set_location_assignment PIN_R4 -to aVcxoCtrl
|
||||
set_location_assignment PIN_T4 -to aDacDin
|
||||
set_location_assignment PIN_T5 -to aDacSync_n
|
||||
set_location_assignment PIN_R6 -to aPlSpiAddr[2]
|
||||
set_location_assignment PIN_R5 -to aDacSck
|
||||
set_location_assignment PIN_T6 -to aPlSpiAddr[1]
|
||||
set_location_assignment PIN_R7 -to aLmkClkinSel[0]
|
||||
set_location_assignment PIN_T7 -to lPlSpiSdo
|
||||
set_location_assignment PIN_P8 -to sPsSpiLe
|
||||
set_location_assignment PIN_R8 -to aPsSpiAddr[1]
|
||||
set_location_assignment PIN_P9 -to aPlSpiAddr[0]
|
||||
set_location_assignment PIN_T8 -to PsSpiSck
|
||||
set_location_assignment PIN_T9 -to aPsSpiAddr[0]
|
||||
set_location_assignment PIN_R9 -to sPsSpiSdi
|
||||
set_location_assignment PIN_P10 -to aAtrRx1
|
||||
set_location_assignment PIN_T10 -to sPsSpiSdo
|
||||
set_location_assignment PIN_P11 -to aAtrTx2
|
||||
set_location_assignment PIN_R10 -to aRxLoLockDetect
|
||||
set_location_assignment PIN_R12 -to aRxLoSck
|
||||
set_location_assignment PIN_T11 -to aTxLoLockDetect
|
||||
set_location_assignment PIN_P12 -to aAtrRx2
|
||||
set_location_assignment PIN_R11 -to aRxLoDin
|
||||
set_location_assignment PIN_T12 -to aRxLoCs_n
|
||||
set_location_assignment PIN_R13 -to aTxLoDin
|
||||
set_location_assignment PIN_T13 -to aRxLoMuxOut
|
||||
set_location_assignment PIN_P13 -to aAtrTx1
|
||||
set_location_assignment PIN_T15 -to aTxLoSck
|
||||
set_location_assignment PIN_R14 -to aTxLoCs_n
|
||||
set_location_assignment PIN_R16 -to aTxLoMuxOut
|
||||
set_location_assignment PIN_P14 -to aMkTx1En
|
||||
set_location_assignment PIN_N15 -to aMkRx2En
|
||||
set_location_assignment PIN_P15 -to aMkRx1En
|
||||
set_location_assignment PIN_N16 -to aMkTx2En
|
||||
set_location_assignment PIN_K15 -to aCh1TxSw5[1]
|
||||
set_location_assignment PIN_L14 -to aCh1RxMixerEn
|
||||
set_location_assignment PIN_K16 -to aCh1TxMixerEn
|
||||
set_location_assignment PIN_K14 -to aCh1RxSw8[0]
|
||||
set_location_assignment PIN_J15 -to aCh1TxAmpEn
|
||||
set_location_assignment PIN_J14 -to aCh1RxSw8[1]
|
||||
set_location_assignment PIN_J16 -to aCh1TxSw5[0]
|
||||
set_location_assignment PIN_H14 -to aCh1RxAmpEn
|
||||
set_location_assignment PIN_H16 -to aCh1TxSw4[0]
|
||||
set_location_assignment PIN_G14 -to aCh1TxSw4[1]
|
||||
set_location_assignment PIN_H15 -to aCh1RxSw5[1]
|
||||
set_location_assignment PIN_F14 -to aCh1RxSw7[1]
|
||||
set_location_assignment PIN_G16 -to aCh1RxSw5[0]
|
||||
set_location_assignment PIN_G15 -to aCh1RxSw4[0]
|
||||
set_location_assignment PIN_E14 -to aCh1RxSw6[1]
|
||||
set_location_assignment PIN_F16 -to aCh1RxSw2[1]
|
||||
set_location_assignment PIN_E13 -to aCh1RxSw7[0]
|
||||
set_location_assignment PIN_F15 -to aCh1RxSw2[0]
|
||||
set_location_assignment PIN_D14 -to aCh1RxSw6[2]
|
||||
set_location_assignment PIN_E16 -to aCh1RxSw6[0]
|
||||
set_location_assignment PIN_E15 -to aCh1TxSw3
|
||||
set_location_assignment PIN_C15 -to aCh1RxSw5[2]
|
||||
set_location_assignment PIN_D16 -to aCh1TxPaEn
|
||||
set_location_assignment PIN_C14 -to aCh1RxSw4[1]
|
||||
set_location_assignment PIN_D15 -to aCh1RxSw5[3]
|
||||
set_location_assignment PIN_B14 -to aCh1TxSw2[3]
|
||||
set_location_assignment PIN_B16 -to aCh1RxLna2En
|
||||
set_location_assignment PIN_C13 -to aCh1RxSw4[2]
|
||||
set_location_assignment PIN_A15 -to aCh1TxSw2[2]
|
||||
set_location_assignment PIN_B13 -to aCh1TxSw2[1]
|
||||
set_location_assignment PIN_A13 -to aCh1TxSw2[0]
|
||||
set_location_assignment PIN_C12 -to aCh1RxSw1[0]
|
||||
set_location_assignment PIN_B12 -to aCh1TxSw1[0]
|
||||
set_location_assignment PIN_D12 -to aCh1RxSw1[1]
|
||||
set_location_assignment PIN_A12 -to aCh1TxSw1[1]
|
||||
set_location_assignment PIN_C11 -to aCh1LedTx
|
||||
set_location_assignment PIN_B11 -to aCh1RxLna1En
|
||||
set_location_assignment PIN_D11 -to aCh2RxSw1[1]
|
||||
set_location_assignment PIN_A11 -to aCh1RxSw3[2]
|
||||
set_location_assignment PIN_C10 -to aCh1LedRx
|
||||
set_location_assignment PIN_B10 -to aCh1RxSw3[1]
|
||||
set_location_assignment PIN_C9 -to aCh1LedRx2
|
||||
set_location_assignment PIN_A10 -to aCh1RxSw3[0]
|
||||
set_location_assignment PIN_C8 -to aCh2LedRx2
|
||||
set_location_assignment PIN_B9 -to aCh1SwTrx[1]
|
||||
set_location_assignment PIN_A9 -to aCh1SwTrx[0]
|
||||
set_location_assignment PIN_A8 -to aCh2SwTrx[0]
|
||||
set_location_assignment PIN_C7 -to aCh2RxSw3[0]
|
||||
set_location_assignment PIN_B8 -to aCh2SwTrx[1]
|
||||
set_location_assignment PIN_C6 -to aCh2LedRx
|
||||
set_location_assignment PIN_A7 -to aCh2RxSw3[1]
|
||||
set_location_assignment PIN_B5 -to aCh2TxSw1[0]
|
||||
set_location_assignment PIN_C5 -to aCh2RxSw1[0]
|
||||
set_location_assignment PIN_A6 -to aCh2TxSw1[1]
|
||||
set_location_assignment PIN_D5 -to aCh2LedTx
|
||||
set_location_assignment PIN_B6 -to aCh2RxSw3[2]
|
||||
set_location_assignment PIN_B4 -to aCh2RxLna2En
|
||||
set_location_assignment PIN_A5 -to aCh2RxLna1En
|
||||
set_location_assignment PIN_C4 -to aCh2RxSw2[0]
|
||||
set_location_assignment PIN_A4 -to aCh2TxSw2[1]
|
||||
set_location_assignment PIN_D4 -to aCh2RxSw2[1]
|
||||
set_location_assignment PIN_A2 -to aCh2TxSw2[3]
|
||||
set_location_assignment PIN_B3 -to aCh2TxSw2[0]
|
||||
set_location_assignment PIN_B1 -to aCh2TxSw2[2]
|
||||
|
||||
set_global_assignment -name DEVICE_FILTER_PACKAGE FBGA
|
||||
set_global_assignment -name DEVICE_FILTER_PIN_COUNT 256
|
||||
set_global_assignment -name GENERATE_JAM_FILE ON
|
||||
set_global_assignment -name GENERATE_JBC_FILE ON
|
||||
set_global_assignment -name RESERVE_ALL_UNUSED_PINS_NO_OUTPUT_GND "AS INPUT TRI-STATED"
|
||||
set_global_assignment -name OPTIMIZATION_MODE "HIGH PERFORMANCE EFFORT"
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw4[0]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2TxPaEn
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw6[0]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw4[1]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2TxSw3
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw7[1]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw4[2]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw6[1]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw7[0]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw5[0]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw5[1]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2TxSw4[0]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw5[3]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw6[2]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2TxSw4[1]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2TxAmpEn
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw5[2]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2TxMixerEn
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxMixerEn
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2TxSw5[1]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2TxSw5[0]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aLmkSpiSdio
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw8[0]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw8[1]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxAmpEn
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aLmkSpiSck
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aLmkSpiCs_n
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aMkReset_n
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aLmkSync
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aVcxoCtrl
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aDacDin
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aDacSync_n
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aDacSck
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to lPlSpiSdo
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to sPsSpiSdo
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aRxLoSck
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aRxLoDin
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aRxLoCs_n
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aTxLoDin
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aTxLoSck
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aTxLoCs_n
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aMkTx1En
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aMkRx2En
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aMkRx1En
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aMkTx2En
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxMixerEn
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1TxSw5[1]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1TxMixerEn
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw8[0]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1TxAmpEn
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw8[1]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1TxSw5[0]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxAmpEn
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1TxSw4[0]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1TxSw4[1]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw5[1]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw7[1]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw4[0]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw5[0]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw6[1]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw2[1]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw7[0]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw2[0]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw6[2]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw6[0]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1TxSw3
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw5[2]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1TxPaEn
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw4[1]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw5[3]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1TxSw2[3]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw4[2]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxLna2En
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1TxSw2[2]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1TxSw2[1]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1TxSw2[0]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw1[0]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1TxSw1[0]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw1[1]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1TxSw1[1]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1LedTx
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxLna1En
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw1[1]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw3[2]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1LedRx
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw3[1]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1LedRx2
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1RxSw3[0]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2LedRx2
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1SwTrx[1]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh1SwTrx[0]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2SwTrx[0]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw3[0]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2SwTrx[1]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2LedRx
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw3[1]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2TxSw1[0]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw1[0]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2TxSw1[1]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2LedTx
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw3[2]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxLna2En
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxLna1En
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2TxSw2[1]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw2[0]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2RxSw2[1]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2TxSw2[0]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2TxSw2[3]
|
||||
set_instance_assignment -name CURRENT_STRENGTH_NEW 8MA -to aCh2TxSw2[2]
|
||||
set_global_assignment -name SEED 11
|
||||
set_global_assignment -name VHDL_FILE PkgMgCpld.vhd
|
||||
set_global_assignment -name VHDL_FILE PkgSetup.vhd
|
||||
set_global_assignment -name VHDL_FILE TopCpld.vhd
|
||||
set_global_assignment -name TOP_LEVEL_ENTITY TopCpld
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,156 @@
|
||||
#
|
||||
# Copyright 2017 Ettus Research, A National Instruments Company
|
||||
# SPDX-License-Identifier: LGPL-3.0
|
||||
#
|
||||
# Daughterboard Pin Definitions for the N310.
|
||||
#
|
||||
|
||||
## TDC : ################################################################################
|
||||
## Bank 10, 2.5V (DB A)
|
||||
#########################################################################################
|
||||
|
||||
set_property PACKAGE_PIN AB15 [get_ports {UNUSED_PIN_TDCA_0}]
|
||||
set_property PACKAGE_PIN AB14 [get_ports {UNUSED_PIN_TDCA_1}]
|
||||
set_property PACKAGE_PIN AB16 [get_ports {UNUSED_PIN_TDCA_2}]
|
||||
set_property PACKAGE_PIN AB17 [get_ports {UNUSED_PIN_TDCA_3}]
|
||||
set_property IOSTANDARD LVCMOS25 [get_ports {UNUSED_PIN_TDCA_*}]
|
||||
set_property IOB TRUE [get_ports {UNUSED_PIN_TDCA_*}]
|
||||
|
||||
## USRP IO A : ##########################################################################
|
||||
## Banks 10/33
|
||||
#########################################################################################
|
||||
|
||||
## HP GPIO, Bank 33, 1.8V
|
||||
|
||||
set_property PACKAGE_PIN G1 [get_ports {DBA_CPLD_PS_SPI_LE}]
|
||||
set_property PACKAGE_PIN H2 [get_ports {DBA_CPLD_PS_SPI_SCLK}]
|
||||
set_property PACKAGE_PIN D1 [get_ports {DBA_CH1_TX_DSA_DATA[5]}]
|
||||
# set_property PACKAGE_PIN E1 [get_ports {nc}]
|
||||
set_property PACKAGE_PIN H1 [get_ports {DBA_CPLD_PS_SPI_ADDR[0]}]
|
||||
set_property PACKAGE_PIN J1 [get_ports {DBA_CPLD_PS_SPI_ADDR[1]}]
|
||||
set_property PACKAGE_PIN A5 [get_ports {DBA_CH1_TX_DSA_DATA[3]}]
|
||||
set_property PACKAGE_PIN A4 [get_ports {DBA_CH1_TX_DSA_DATA[4]}]
|
||||
set_property PACKAGE_PIN F5 [get_ports {DBA_CPLD_PS_SPI_SDO}]
|
||||
set_property PACKAGE_PIN E5 [get_ports {DBA_CPLD_PS_SPI_SDI}]
|
||||
set_property PACKAGE_PIN E3 [get_ports {DBA_CH1_RX_DSA_DATA[0]}]
|
||||
set_property PACKAGE_PIN E2 [get_ports {DBA_CH1_RX_DSA_DATA[1]}]
|
||||
set_property PACKAGE_PIN A3 [get_ports {DBA_CH1_TX_DSA_DATA[2]}]
|
||||
set_property PACKAGE_PIN A2 [get_ports {DBA_CH1_TX_DSA_DATA[1]}]
|
||||
set_property PACKAGE_PIN K1 [get_ports {DBA_ATR_RX_1}]
|
||||
set_property PACKAGE_PIN L1 [get_ports {DBA_ATR_TX_2}]
|
||||
set_property PACKAGE_PIN C4 [get_ports {DBA_CH1_TX_DSA_DATA[0]}]
|
||||
set_property PACKAGE_PIN C3 [get_ports {DBA_CH1_RX_DSA_DATA[5]}]
|
||||
set_property PACKAGE_PIN F4 [get_ports {DBA_ATR_TX_1}]
|
||||
set_property PACKAGE_PIN F3 [get_ports {DBA_ATR_RX_2}]
|
||||
# set_property PACKAGE_PIN B1 [get_ports {nc}]
|
||||
set_property PACKAGE_PIN B2 [get_ports {DBA_CH1_RX_DSA_DATA[3]}]
|
||||
set_property PACKAGE_PIN C1 [get_ports {DBA_CH1_RX_DSA_DATA[4]}]
|
||||
set_property PACKAGE_PIN C2 [get_ports {DBA_CH1_RX_DSA_DATA[2]}]
|
||||
|
||||
## HR GPIO, Bank 10, 2.5V
|
||||
|
||||
set_property PACKAGE_PIN AG12 [get_ports {DBA_MYK_SYNC_IN_n}]
|
||||
set_property PACKAGE_PIN AH12 [get_ports {DBA_CPLD_PL_SPI_ADDR[0]}]
|
||||
set_property PACKAGE_PIN AJ13 [get_ports {DBA_MYK_SPI_SDO}]
|
||||
set_property PACKAGE_PIN AJ14 [get_ports {DBA_MYK_SPI_SDIO}]
|
||||
set_property PACKAGE_PIN AG15 [get_ports {DBA_CPLD_PL_SPI_ADDR[1]}]
|
||||
set_property PACKAGE_PIN AF15 [get_ports {DBA_CH2_TX_DSA_DATA[5]}]
|
||||
set_property PACKAGE_PIN AH13 [get_ports {DBA_CPLD_JTAG_TDI}]
|
||||
set_property PACKAGE_PIN AH14 [get_ports {DBA_CPLD_JTAG_TDO}]
|
||||
set_property PACKAGE_PIN AK15 [get_ports {DBA_MYK_GPIO_1}]
|
||||
set_property PACKAGE_PIN AJ15 [get_ports {DBA_MYK_GPIO_4}]
|
||||
set_property PACKAGE_PIN AH16 [get_ports {DBA_CH2_TX_DSA_DATA[4]}]
|
||||
set_property PACKAGE_PIN AH17 [get_ports {DBA_CH2_TX_DSA_DATA[3]}]
|
||||
set_property PACKAGE_PIN AE12 [get_ports {DBA_MYK_SYNC_OUT_n}]
|
||||
set_property PACKAGE_PIN AF12 [get_ports {DBA_CPLD_PL_SPI_SDO}]
|
||||
set_property PACKAGE_PIN AK12 [get_ports {DBA_MYK_GPIO_13}]
|
||||
set_property PACKAGE_PIN AK13 [get_ports {DBA_MYK_GPIO_0}]
|
||||
set_property PACKAGE_PIN AK16 [get_ports {DBA_MYK_INTRQ}]
|
||||
set_property PACKAGE_PIN AJ16 [get_ports {DBA_CH2_TX_DSA_DATA[2]}]
|
||||
set_property PACKAGE_PIN AH18 [get_ports {DBA_CH2_TX_DSA_DATA[0]}]
|
||||
set_property PACKAGE_PIN AJ18 [get_ports {DBA_CH2_TX_DSA_DATA[1]}]
|
||||
set_property PACKAGE_PIN AF14 [get_ports {DBA_FPGA_CLK_P}]
|
||||
set_property PACKAGE_PIN AG14 [get_ports {DBA_FPGA_CLK_N}]
|
||||
set_property PACKAGE_PIN AG17 [get_ports {DBA_FPGA_SYSREF_P}]
|
||||
set_property PACKAGE_PIN AG16 [get_ports {DBA_FPGA_SYSREF_N}]
|
||||
set_property PACKAGE_PIN AD15 [get_ports {DBA_CH2_RX_DSA_DATA[3]}]
|
||||
set_property PACKAGE_PIN AD16 [get_ports {DBA_CH2_RX_DSA_DATA[5]}]
|
||||
set_property PACKAGE_PIN AE13 [get_ports {DBA_CPLD_JTAG_TMS}]
|
||||
set_property PACKAGE_PIN AF13 [get_ports {DBA_CPLD_JTAG_TCK}]
|
||||
set_property PACKAGE_PIN AE15 [get_ports {DBA_MYK_GPIO_15}]
|
||||
set_property PACKAGE_PIN AE16 [get_ports {DBA_MYK_SPI_CS_n}]
|
||||
set_property PACKAGE_PIN AF17 [get_ports {DBA_CH2_RX_DSA_DATA[1]}]
|
||||
set_property PACKAGE_PIN AF18 [get_ports {DBA_CH2_RX_DSA_DATA[2]}]
|
||||
set_property PACKAGE_PIN AC16 [get_ports {DBA_CPLD_PL_SPI_LE}]
|
||||
set_property PACKAGE_PIN AC17 [get_ports {DBA_CPLD_PL_SPI_SDI}]
|
||||
set_property PACKAGE_PIN AD13 [get_ports {DBA_MYK_GPIO_12}]
|
||||
set_property PACKAGE_PIN AD14 [get_ports {DBA_MYK_GPIO_14}]
|
||||
set_property PACKAGE_PIN AE17 [get_ports {DBA_MYK_SPI_SCLK}]
|
||||
set_property PACKAGE_PIN AE18 [get_ports {DBA_MYK_GPIO_3}]
|
||||
set_property PACKAGE_PIN AB12 [get_ports {DBA_CH2_RX_DSA_DATA[0]}]
|
||||
set_property PACKAGE_PIN AC12 [get_ports {DBA_CH2_RX_DSA_DATA[4]}]
|
||||
set_property PACKAGE_PIN AC13 [get_ports {DBA_CPLD_PL_SPI_ADDR[2]}]
|
||||
set_property PACKAGE_PIN AC14 [get_ports {DBA_CPLD_PL_SPI_SCLK}]
|
||||
|
||||
# set_property PACKAGE_PIN AB25 [get_ports {DBA_SWITCHER_CLOCK}]
|
||||
# set_property IOSTANDARD LVCMOS33 [get_ports {DBA_SWITCHER_CLOCK}]
|
||||
# set_property DRIVE 4 [get_ports {DBA_SWITCHER_CLOCK}]
|
||||
# set_property SLEW SLOW [get_ports {DBA_SWITCHER_CLOCK}]
|
||||
|
||||
# During SI measurements with default drive strength, many of the FPGA-driven lines to
|
||||
# the DB were showing high over/undershoot. Therefore for single-ended lines to the DBs
|
||||
# we are decreasing the drive strength to the minimum value (4mA) and explicitly
|
||||
# declaring the (default) slew rate as SLOW.
|
||||
|
||||
set UsrpIoAHpPinsSe [get_ports {DBA_CPLD_PS_* \
|
||||
DBA_CH1_* \
|
||||
DBA_ATR*}]
|
||||
set_property IOSTANDARD LVCMOS18 $UsrpIoAHpPinsSe
|
||||
set_property DRIVE 4 $UsrpIoAHpPinsSe
|
||||
set_property SLEW SLOW $UsrpIoAHpPinsSe
|
||||
|
||||
set UsrpIoAHrPinsSe [get_ports {DBA_MYK_SPI_* \
|
||||
DBA_MYK_INTRQ \
|
||||
DBA_MYK_SYNC* \
|
||||
DBA_MYK_GPIO* \
|
||||
DBA_CPLD_PL_* \
|
||||
DBA_CPLD_JTAG_* \
|
||||
DBA_CH2*}]
|
||||
set_property IOSTANDARD LVCMOS25 $UsrpIoAHrPinsSe
|
||||
set_property DRIVE 4 $UsrpIoAHrPinsSe
|
||||
set_property SLEW SLOW $UsrpIoAHrPinsSe
|
||||
|
||||
set UsrpIoAHrPinsDiff [get_ports {DBA_FPGA_CLK_* \
|
||||
DBA_FPGA_SYSREF_*}]
|
||||
set_property IOSTANDARD LVDS_25 $UsrpIoAHrPinsDiff
|
||||
set_property DIFF_TERM TRUE $UsrpIoAHrPinsDiff
|
||||
|
||||
# Do not allow the DSA lines to float... give them a weak pull if undriven.
|
||||
set_property PULLUP TRUE [get_ports {DBA_CH*_*X_DSA_DATA[*]}]
|
||||
|
||||
|
||||
### MGTs, Bank 112
|
||||
|
||||
set_property PACKAGE_PIN N8 [get_ports {USRPIO_A_MGTCLK_P}]
|
||||
set_property PACKAGE_PIN N7 [get_ports {USRPIO_A_MGTCLK_N}]
|
||||
|
||||
# This mapping uses the TX pins as the "master" and mimics RX off of them so Vivado
|
||||
# places the transceivers in the correct places. The mixup in lanes is accounted for
|
||||
# in the Mykonos lane crossbar settings.
|
||||
set_property PACKAGE_PIN V6 [get_ports {USRPIO_A_RX_P[0]}]
|
||||
set_property PACKAGE_PIN V5 [get_ports {USRPIO_A_RX_N[0]}]
|
||||
set_property PACKAGE_PIN U4 [get_ports {USRPIO_A_RX_P[1]}]
|
||||
set_property PACKAGE_PIN U3 [get_ports {USRPIO_A_RX_N[1]}]
|
||||
set_property PACKAGE_PIN T6 [get_ports {USRPIO_A_RX_P[2]}]
|
||||
set_property PACKAGE_PIN T5 [get_ports {USRPIO_A_RX_N[2]}]
|
||||
set_property PACKAGE_PIN P6 [get_ports {USRPIO_A_RX_P[3]}]
|
||||
set_property PACKAGE_PIN P5 [get_ports {USRPIO_A_RX_N[3]}]
|
||||
|
||||
set_property PACKAGE_PIN T2 [get_ports {USRPIO_A_TX_P[0]}]
|
||||
set_property PACKAGE_PIN T1 [get_ports {USRPIO_A_TX_N[0]}]
|
||||
set_property PACKAGE_PIN R4 [get_ports {USRPIO_A_TX_P[1]}]
|
||||
set_property PACKAGE_PIN R3 [get_ports {USRPIO_A_TX_N[1]}]
|
||||
set_property PACKAGE_PIN P2 [get_ports {USRPIO_A_TX_P[2]}]
|
||||
set_property PACKAGE_PIN P1 [get_ports {USRPIO_A_TX_N[2]}]
|
||||
set_property PACKAGE_PIN N4 [get_ports {USRPIO_A_TX_P[3]}]
|
||||
set_property PACKAGE_PIN N3 [get_ports {USRPIO_A_TX_N[3]}]
|
||||
@@ -0,0 +1,156 @@
|
||||
#
|
||||
# Copyright 2017 Ettus Research, A National Instruments Company
|
||||
# SPDX-License-Identifier: LGPL-3.0
|
||||
#
|
||||
# Daughterboard Pin Definitions for the N310.
|
||||
#
|
||||
|
||||
## TDC : ################################################################################
|
||||
## Bank 11, 2.5V (DB B)
|
||||
#########################################################################################
|
||||
|
||||
set_property PACKAGE_PIN W21 [get_ports {UNUSED_PIN_TDCB_0}]
|
||||
set_property PACKAGE_PIN Y21 [get_ports {UNUSED_PIN_TDCB_1}]
|
||||
set_property PACKAGE_PIN Y22 [get_ports {UNUSED_PIN_TDCB_2}]
|
||||
set_property PACKAGE_PIN Y23 [get_ports {UNUSED_PIN_TDCB_3}]
|
||||
set_property IOSTANDARD LVCMOS25 [get_ports {UNUSED_PIN_TDCB_*}]
|
||||
set_property IOB TRUE [get_ports {UNUSED_PIN_TDCB_*}]
|
||||
|
||||
### USRP IO B : #########################################################################
|
||||
## Bank 11/33
|
||||
#########################################################################################
|
||||
|
||||
## HP GPIO, Bank 33, 1.8V
|
||||
|
||||
set_property PACKAGE_PIN J4 [get_ports {DBB_CPLD_PS_SPI_LE}]
|
||||
set_property PACKAGE_PIN J3 [get_ports {DBB_CPLD_PS_SPI_SCLK}]
|
||||
set_property PACKAGE_PIN D4 [get_ports {DBB_CH1_TX_DSA_DATA[5]}]
|
||||
# set_property PACKAGE_PIN D3 [get_ports {nc}]
|
||||
set_property PACKAGE_PIN K2 [get_ports {DBB_CPLD_PS_SPI_ADDR[0]}]
|
||||
set_property PACKAGE_PIN K3 [get_ports {DBB_CPLD_PS_SPI_ADDR[1]}]
|
||||
set_property PACKAGE_PIN B5 [get_ports {DBB_CH1_TX_DSA_DATA[3]}]
|
||||
set_property PACKAGE_PIN B4 [get_ports {DBB_CH1_TX_DSA_DATA[4]}]
|
||||
set_property PACKAGE_PIN G5 [get_ports {DBB_CPLD_PS_SPI_SDO}]
|
||||
set_property PACKAGE_PIN G4 [get_ports {DBB_CPLD_PS_SPI_SDI}]
|
||||
set_property PACKAGE_PIN J5 [get_ports {DBB_CH1_RX_DSA_DATA[0]}]
|
||||
set_property PACKAGE_PIN K5 [get_ports {DBB_CH1_RX_DSA_DATA[1]}]
|
||||
set_property PACKAGE_PIN D5 [get_ports {DBB_CH1_TX_DSA_DATA[2]}]
|
||||
set_property PACKAGE_PIN E6 [get_ports {DBB_CH1_TX_DSA_DATA[1]}]
|
||||
set_property PACKAGE_PIN L3 [get_ports {DBB_ATR_RX_1}]
|
||||
set_property PACKAGE_PIN L2 [get_ports {DBB_ATR_TX_2}]
|
||||
set_property PACKAGE_PIN G6 [get_ports {DBB_CH1_TX_DSA_DATA[0]}]
|
||||
set_property PACKAGE_PIN H6 [get_ports {DBB_CH1_RX_DSA_DATA[5]}]
|
||||
set_property PACKAGE_PIN H4 [get_ports {DBB_ATR_TX_1}]
|
||||
set_property PACKAGE_PIN H3 [get_ports {DBB_ATR_RX_2}]
|
||||
# set_property PACKAGE_PIN F2 [get_ports {nc}]
|
||||
set_property PACKAGE_PIN G2 [get_ports {DBB_CH1_RX_DSA_DATA[3]}]
|
||||
set_property PACKAGE_PIN J6 [get_ports {DBB_CH1_RX_DSA_DATA[4]}]
|
||||
set_property PACKAGE_PIN K6 [get_ports {DBB_CH1_RX_DSA_DATA[2]}]
|
||||
|
||||
## HR GPIO, Bank 10, 2.5V
|
||||
|
||||
set_property PACKAGE_PIN AK17 [get_ports {DBB_MYK_SYNC_IN_n}]
|
||||
set_property PACKAGE_PIN AK18 [get_ports {DBB_CPLD_PL_SPI_ADDR[0]}]
|
||||
set_property PACKAGE_PIN AK21 [get_ports {DBB_MYK_SPI_SDO}]
|
||||
set_property PACKAGE_PIN AJ21 [get_ports {DBB_MYK_SPI_SDIO}]
|
||||
set_property PACKAGE_PIN AF19 [get_ports {DBB_CPLD_PL_SPI_ADDR[1]}]
|
||||
set_property PACKAGE_PIN AG19 [get_ports {DBB_CH2_TX_DSA_DATA[5]}]
|
||||
set_property PACKAGE_PIN AH19 [get_ports {DBB_CPLD_JTAG_TDI}]
|
||||
set_property PACKAGE_PIN AJ19 [get_ports {DBB_CPLD_JTAG_TDO}]
|
||||
set_property PACKAGE_PIN AK22 [get_ports {DBB_MYK_GPIO_1}]
|
||||
set_property PACKAGE_PIN AK23 [get_ports {DBB_MYK_GPIO_4}]
|
||||
set_property PACKAGE_PIN AF20 [get_ports {DBB_CH2_TX_DSA_DATA[4]}]
|
||||
set_property PACKAGE_PIN AG20 [get_ports {DBB_CH2_TX_DSA_DATA[3]}]
|
||||
set_property PACKAGE_PIN AF23 [get_ports {DBB_MYK_SYNC_OUT_n}]
|
||||
set_property PACKAGE_PIN AF24 [get_ports {DBB_CPLD_PL_SPI_SDO}]
|
||||
set_property PACKAGE_PIN AK20 [get_ports {DBB_MYK_GPIO_13}]
|
||||
set_property PACKAGE_PIN AJ20 [get_ports {DBB_MYK_GPIO_0}]
|
||||
set_property PACKAGE_PIN AJ23 [get_ports {DBB_MYK_INTRQ}]
|
||||
set_property PACKAGE_PIN AJ24 [get_ports {DBB_CH2_TX_DSA_DATA[2]}]
|
||||
set_property PACKAGE_PIN AG24 [get_ports {DBB_CH2_TX_DSA_DATA[0]}]
|
||||
set_property PACKAGE_PIN AG25 [get_ports {DBB_CH2_TX_DSA_DATA[1]}]
|
||||
set_property PACKAGE_PIN AG21 [get_ports {DBB_FPGA_CLK_P}]
|
||||
set_property PACKAGE_PIN AH21 [get_ports {DBB_FPGA_CLK_N}]
|
||||
set_property PACKAGE_PIN AE22 [get_ports {DBB_FPGA_SYSREF_P}]
|
||||
set_property PACKAGE_PIN AF22 [get_ports {DBB_FPGA_SYSREF_N}]
|
||||
set_property PACKAGE_PIN AJ25 [get_ports {DBB_CH2_RX_DSA_DATA[3]}]
|
||||
set_property PACKAGE_PIN AK25 [get_ports {DBB_CH2_RX_DSA_DATA[5]}]
|
||||
set_property PACKAGE_PIN AB21 [get_ports {DBB_CPLD_JTAG_TMS}]
|
||||
set_property PACKAGE_PIN AB22 [get_ports {DBB_CPLD_JTAG_TCK}]
|
||||
set_property PACKAGE_PIN AD23 [get_ports {DBB_MYK_GPIO_15}]
|
||||
set_property PACKAGE_PIN AE23 [get_ports {DBB_MYK_SPI_CS_n}]
|
||||
set_property PACKAGE_PIN AB24 [get_ports {DBB_CH2_RX_DSA_DATA[1]}]
|
||||
set_property PACKAGE_PIN AA24 [get_ports {DBB_CH2_RX_DSA_DATA[2]}]
|
||||
set_property PACKAGE_PIN AG22 [get_ports {DBB_CPLD_PL_SPI_LE}]
|
||||
set_property PACKAGE_PIN AH22 [get_ports {DBB_CPLD_PL_SPI_SDI}]
|
||||
set_property PACKAGE_PIN AD21 [get_ports {DBB_MYK_GPIO_12}]
|
||||
set_property PACKAGE_PIN AE21 [get_ports {DBB_MYK_GPIO_14}]
|
||||
set_property PACKAGE_PIN AC22 [get_ports {DBB_MYK_SPI_SCLK}]
|
||||
set_property PACKAGE_PIN AC23 [get_ports {DBB_MYK_GPIO_3}]
|
||||
set_property PACKAGE_PIN AC24 [get_ports {DBB_CH2_RX_DSA_DATA[0]}]
|
||||
set_property PACKAGE_PIN AD24 [get_ports {DBB_CH2_RX_DSA_DATA[4]}]
|
||||
set_property PACKAGE_PIN AH23 [get_ports {DBB_CPLD_PL_SPI_ADDR[2]}]
|
||||
set_property PACKAGE_PIN AH24 [get_ports {DBB_CPLD_PL_SPI_SCLK}]
|
||||
|
||||
# set_property PACKAGE_PIN AA25 [get_ports DBB_SWITCHER_CLOCK]
|
||||
# set_property IOSTANDARD LVCMOS33 [get_ports DBB_SWITCHER_CLOCK]
|
||||
# set_property DRIVE 4 [get_ports DBB_SWITCHER_CLOCK]
|
||||
# set_property SLEW SLOW [get_ports DBB_SWITCHER_CLOCK]
|
||||
|
||||
# During SI measurements with default drive strength, many of the FPGA-driven lines to
|
||||
# the DB were showing high over/undershoot. Therefore for single-ended lines to the DBs
|
||||
# we are decreasing the drive strength to the minimum value (4mA) and explicitly
|
||||
# declaring the (default) slew rate as SLOW.
|
||||
|
||||
set UsrpIoBHpPinsSe [get_ports {DBB_CPLD_PS_* \
|
||||
DBB_CH1_* \
|
||||
DBB_ATR*}]
|
||||
set_property IOSTANDARD LVCMOS18 $UsrpIoBHpPinsSe
|
||||
set_property DRIVE 4 $UsrpIoBHpPinsSe
|
||||
set_property SLEW SLOW $UsrpIoBHpPinsSe
|
||||
|
||||
set UsrpIoBHrPinsSe [get_ports {DBB_MYK_SPI_* \
|
||||
DBB_MYK_INTRQ \
|
||||
DBB_MYK_SYNC* \
|
||||
DBB_MYK_GPIO* \
|
||||
DBB_CPLD_PL_* \
|
||||
DBB_CPLD_JTAG_* \
|
||||
DBB_CH2*}]
|
||||
set_property IOSTANDARD LVCMOS25 $UsrpIoBHrPinsSe
|
||||
set_property DRIVE 4 $UsrpIoBHrPinsSe
|
||||
set_property SLEW SLOW $UsrpIoBHrPinsSe
|
||||
|
||||
set UsrpIoBHrPinsDiff [get_ports {DBB_FPGA_CLK_* \
|
||||
DBB_FPGA_SYSREF_*}]
|
||||
set_property IOSTANDARD LVDS_25 $UsrpIoBHrPinsDiff
|
||||
set_property DIFF_TERM TRUE $UsrpIoBHrPinsDiff
|
||||
|
||||
# Do not allow the DSA lines to float... give them a weak pull if undriven.
|
||||
set_property PULLUP TRUE [get_ports {DBB_CH*_*X_DSA_DATA[*]}]
|
||||
|
||||
|
||||
### MGTs, Bank 112
|
||||
|
||||
set_property PACKAGE_PIN W8 [get_ports {USRPIO_B_MGTCLK_P}]
|
||||
set_property PACKAGE_PIN W7 [get_ports {USRPIO_B_MGTCLK_N}]
|
||||
|
||||
# This mapping uses the TX pins as the "master" and mimics RX off of them so Vivado
|
||||
# places the transceivers in the correct places. The mixup in lanes is accounted for
|
||||
# in the Mykonos lane crossbar settings.
|
||||
set_property PACKAGE_PIN AC4 [get_ports {USRPIO_B_RX_P[0]}]
|
||||
set_property PACKAGE_PIN AC3 [get_ports {USRPIO_B_RX_N[0]}]
|
||||
set_property PACKAGE_PIN AB6 [get_ports {USRPIO_B_RX_P[1]}]
|
||||
set_property PACKAGE_PIN AB5 [get_ports {USRPIO_B_RX_N[1]}]
|
||||
set_property PACKAGE_PIN Y6 [get_ports {USRPIO_B_RX_P[2]}]
|
||||
set_property PACKAGE_PIN Y5 [get_ports {USRPIO_B_RX_N[2]}]
|
||||
set_property PACKAGE_PIN AA4 [get_ports {USRPIO_B_RX_P[3]}]
|
||||
set_property PACKAGE_PIN AA3 [get_ports {USRPIO_B_RX_N[3]}]
|
||||
|
||||
set_property PACKAGE_PIN AB2 [get_ports {USRPIO_B_TX_P[0]}]
|
||||
set_property PACKAGE_PIN AB1 [get_ports {USRPIO_B_TX_N[0]}]
|
||||
set_property PACKAGE_PIN Y2 [get_ports {USRPIO_B_TX_P[1]}]
|
||||
set_property PACKAGE_PIN Y1 [get_ports {USRPIO_B_TX_N[1]}]
|
||||
set_property PACKAGE_PIN W4 [get_ports {USRPIO_B_TX_P[2]}]
|
||||
set_property PACKAGE_PIN W3 [get_ports {USRPIO_B_TX_N[2]}]
|
||||
set_property PACKAGE_PIN V2 [get_ports {USRPIO_B_TX_P[3]}]
|
||||
set_property PACKAGE_PIN V1 [get_ports {USRPIO_B_TX_N[3]}]
|
||||
@@ -0,0 +1,345 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- File: ClockingRegs.vhd
|
||||
-- Author: Daniel Jepson
|
||||
-- Original Project: N310
|
||||
-- Date: 17 March 2016
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
-- Copyright 2016-2018 Ettus Research, A National Instruments Company
|
||||
-- SPDX-License-Identifier: LGPL-3.0
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Purpose:
|
||||
--
|
||||
-- Register access to the control/status bits and interfaces for the
|
||||
-- RadioClocking module.
|
||||
--
|
||||
-- XML register definition is included below the module.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
library work;
|
||||
use work.PkgClockingRegMap.all;
|
||||
use work.PkgRegs.all;
|
||||
|
||||
|
||||
entity ClockingRegs is
|
||||
port(
|
||||
-- Async reset. Can be tied low if desired.
|
||||
aReset : in boolean;
|
||||
-- Sync reset... used in the same places as the async one.
|
||||
bReset : in boolean;
|
||||
-- Register Bus Clock -- this module connects the BusClk to PsClk, so it's limited
|
||||
-- to 200 MHz!
|
||||
BusClk : in std_logic;
|
||||
|
||||
bRegPortOut : out RegPortOut_t;
|
||||
bRegPortIn : in RegPortIn_t;
|
||||
|
||||
-- Phase shift interface to the RadioClkMmcm.
|
||||
-- There is a reset crossing here between the MMCM reset and aReset. The outgoing
|
||||
-- crossing is safe because (a) the enable signal driven to the MMCM is a strobe-only
|
||||
-- signal and (b) this interface should only be used when the MMCM is not in reset
|
||||
-- (SW waits for the MMCM to be out of reset and locked before using this interface).
|
||||
-- The only input signal, pPsDone, is double-synced in this file before being used.
|
||||
-- This is OK (even though it is a strobe signal) because there is only a reset
|
||||
-- crossing and not a clock domain crossing.
|
||||
pPsInc : out std_logic;
|
||||
pPsEn : out std_logic;
|
||||
pPsDone : in std_logic;
|
||||
|
||||
-- PsClk is driven directly by BusClk, so p = b in the logic below!
|
||||
PsClk : out std_logic;
|
||||
|
||||
-- Sync reset strobes from the register bus to the RadioClkMmcm.
|
||||
bRadioClkMmcmReset : out std_logic;
|
||||
-- Status of RadioClk MMCM lock to register bus.
|
||||
aRadioClksValid : in std_logic;
|
||||
|
||||
bRadioClk1xEnabled : out std_logic;
|
||||
bRadioClk2xEnabled : out std_logic;
|
||||
bRadioClk3xEnabled : out std_logic;
|
||||
|
||||
bJesdRefClkPresent : in std_logic
|
||||
);
|
||||
end ClockingRegs;
|
||||
|
||||
|
||||
architecture RTL of ClockingRegs is
|
||||
|
||||
--vhook_sigstart
|
||||
--vhook_sigend
|
||||
|
||||
signal bRadioClkMmcmResetInt : std_logic := '1';
|
||||
|
||||
signal bRegPortOutLcl : RegPortOut_t := kRegPortOutZero;
|
||||
|
||||
signal bPsDone,
|
||||
bPsEn,
|
||||
bPsInc,
|
||||
pPsDoneDs_ms,
|
||||
pPsDoneDs : std_logic := '0';
|
||||
|
||||
signal bRadioClk1xEnabledInt,
|
||||
bRadioClk2xEnabledInt,
|
||||
bRadioClk3xEnabledInt,
|
||||
bRadioClksValid_ms,
|
||||
bRadioClksValid : std_logic := '0';
|
||||
|
||||
attribute ASYNC_REG : string;
|
||||
attribute ASYNC_REG of bRadioClksValid_ms : signal is "true";
|
||||
attribute ASYNC_REG of bRadioClksValid : signal is "true";
|
||||
attribute ASYNC_REG of pPsDoneDs_ms : signal is "true";
|
||||
attribute ASYNC_REG of pPsDoneDs : signal is "true";
|
||||
|
||||
begin
|
||||
|
||||
-- Locals to outputs.
|
||||
PsClk <= BusClk;
|
||||
pPsInc <= bPsInc;
|
||||
pPsEn <= bPsEn;
|
||||
|
||||
bRadioClkMmcmReset <= bRadioClkMmcmResetInt;
|
||||
|
||||
bRadioClk1xEnabled <= bRadioClk1xEnabledInt;
|
||||
bRadioClk2xEnabled <= bRadioClk2xEnabledInt;
|
||||
bRadioClk3xEnabled <= bRadioClk3xEnabledInt;
|
||||
|
||||
|
||||
-- Write Registers : ------------------------------------------------------------------
|
||||
-- ------------------------------------------------------------------------------------
|
||||
WriteRegisters: process(aReset, BusClk)
|
||||
begin
|
||||
if aReset then
|
||||
bRadioClkMmcmResetInt <= '1';
|
||||
bPsInc <= '0';
|
||||
bPsEn <= '0';
|
||||
bRadioClk1xEnabledInt <= '0';
|
||||
bRadioClk2xEnabledInt <= '0';
|
||||
bRadioClk3xEnabledInt <= '0';
|
||||
elsif rising_edge(BusClk) then
|
||||
|
||||
if bReset then
|
||||
bRadioClkMmcmResetInt <= '1';
|
||||
bPsInc <= '0';
|
||||
bPsEn <= '0';
|
||||
bRadioClk1xEnabledInt <= '0';
|
||||
bRadioClk2xEnabledInt <= '0';
|
||||
bRadioClk3xEnabledInt <= '0';
|
||||
else
|
||||
-- Clear strobe
|
||||
bPsEn <= '0';
|
||||
|
||||
if RegWrite(kPhaseShiftControl, bRegPortIn) then
|
||||
if bRegPortIn.Data(kPsInc) = '1' then
|
||||
bPsInc <= '1';
|
||||
bPsEn <= '1';
|
||||
elsif bRegPortIn.Data(kPsDec) = '1' then
|
||||
bPsInc <= '0';
|
||||
bPsEn <= '1';
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if RegWrite(kRadioClkMmcm, bRegPortIn) then
|
||||
-- Set/Clear pair
|
||||
if bRegPortIn.Data(kRadioClkMmcmResetSet) = '1' then
|
||||
bRadioClkMmcmResetInt <= '1';
|
||||
elsif bRegPortIn.Data(kRadioClkMmcmResetClear) = '1' then
|
||||
bRadioClkMmcmResetInt <= '0';
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if RegWrite(kRadioClkEnables, bRegPortIn) then
|
||||
bRadioClk1xEnabledInt <= bRegPortIn.Data(kRadioClk1xEnabled);
|
||||
bRadioClk2xEnabledInt <= bRegPortIn.Data(kRadioClk2xEnabled);
|
||||
bRadioClk3xEnabledInt <= bRegPortIn.Data(kRadioClk3xEnabled);
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end process WriteRegisters;
|
||||
|
||||
|
||||
DoubleSyncs : process (aReset, BusClk)
|
||||
begin
|
||||
if aReset then
|
||||
bRadioClksValid_ms <= '0';
|
||||
bRadioClksValid <= '0';
|
||||
pPsDoneDs_ms <= '0';
|
||||
pPsDoneDs <= '0';
|
||||
elsif rising_edge(BusClk) then
|
||||
-- No sync reset on double-syncs (however there are default assignments above)!
|
||||
bRadioClksValid_ms <= aRadioClksValid;
|
||||
bRadioClksValid <= bRadioClksValid_ms;
|
||||
pPsDoneDs_ms <= pPsDone;
|
||||
pPsDoneDs <= pPsDoneDs_ms;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
-- Read Registers : -------------------------------------------------------------------
|
||||
-- ------------------------------------------------------------------------------------
|
||||
ReadRegisters: process(aReset, BusClk)
|
||||
begin
|
||||
if aReset then
|
||||
bRegPortOutLcl <= kRegPortOutZero;
|
||||
bPsDone <= '0';
|
||||
elsif rising_edge(BusClk) then
|
||||
|
||||
if bReset then
|
||||
bRegPortOutLcl <= kRegPortOutZero;
|
||||
bPsDone <= '0';
|
||||
else
|
||||
-- Deassert strobes
|
||||
bRegPortOutLcl.Data <= kRegPortDataZero;
|
||||
|
||||
-- All of these transactions only take one clock cycle, so we do not have to
|
||||
-- de-assert the Ready signal (ever).
|
||||
bRegPortOutLcl.Ready <= true;
|
||||
|
||||
-- Process the returned data from the phase shifter in the MMCM. Note that even
|
||||
-- though the prefixes are different (p and b), we drive the PsClk from the BusClk
|
||||
-- so this "crossing" is actually safe. Whenever the Done signal asserts (pPsDone -
|
||||
-- pay attention to the prefix!) from the MMCM, we set a sticky bit to tell SW
|
||||
-- that the shift operation is complete.
|
||||
--
|
||||
-- However, if pPsDone asserts at the same time that SW tries to read the register,
|
||||
-- we should accurately report that the operation is indeed complete and then NOT
|
||||
-- store the sticky (since it has already been read by SW). If a read does not come
|
||||
-- through at the same time pPsDone is asserted, then we store the done state as a
|
||||
-- sticky, bPsDone, which is only cleared by a read to this register.
|
||||
if RegRead(kPhaseShiftControl, bRegPortIn) then
|
||||
-- The phase shift is always enabled for the feedback clock in RadioClocking.vhd
|
||||
bRegPortOutLcl.Data(kPsEnabledForFdbClk) <= '1';
|
||||
bRegPortOutLcl.Data(kPsDone) <= bPsDone or pPsDoneDs;
|
||||
bPsDone <= '0';
|
||||
elsif pPsDoneDs = '1' then
|
||||
bPsDone <= '1';
|
||||
end if;
|
||||
|
||||
if RegRead(kRadioClkMmcm, bRegPortIn) then
|
||||
bRegPortOutLcl.Data(kRadioClkMmcmLocked) <= bRadioClksValid;
|
||||
end if;
|
||||
|
||||
if RegRead(kRadioClkEnables, bRegPortIn) then
|
||||
bRegPortOutLcl.Data(kRadioClk1xEnabled) <= bRadioClk1xEnabledInt;
|
||||
bRegPortOutLcl.Data(kRadioClk2xEnabled) <= bRadioClk2xEnabledInt;
|
||||
bRegPortOutLcl.Data(kRadioClk3xEnabled) <= bRadioClk3xEnabledInt;
|
||||
end if;
|
||||
|
||||
if RegRead(kMgtRefClkStatus, bRegPortIn) then
|
||||
bRegPortOutLcl.Data(kJesdRefClkPresent) <= bJesdRefClkPresent;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end process ReadRegisters;
|
||||
|
||||
-- Local to output
|
||||
bRegPortOut <= bRegPortOutLcl;
|
||||
|
||||
|
||||
end RTL;
|
||||
|
||||
|
||||
--XmlParse xml_on
|
||||
--<regmap name="ClockingRegMap">
|
||||
-- <group name="ClockingRegs">
|
||||
--
|
||||
-- <register name="RadioClkMmcm" size="32" offset="0x20" attributes="Readable|Writable">
|
||||
-- <info>
|
||||
-- </info>
|
||||
-- <bitfield name="RadioClkMmcmLocked" range="4">
|
||||
-- <info>
|
||||
-- Reflects the locked status of the MMCM. '1' = locked. This bit is only valid
|
||||
-- when the MMCM reset is de-asserted. Read-only.
|
||||
-- </info>
|
||||
-- </bitfield>
|
||||
-- <bitfield name="RadioClkMmcmResetClear" range="1" attributes="Strobe">
|
||||
-- <info>
|
||||
-- Controls the reset to the Radio Clock MMCM. Strobe this bit to de-assert the
|
||||
-- reset to the MMCM. Default is reset asserted. Write-only.
|
||||
-- </info>
|
||||
-- </bitfield>
|
||||
-- <bitfield name="RadioClkMmcmResetSet" range="0" attributes="Strobe">
|
||||
-- <info>
|
||||
-- Controls the reset to the Radio Clock MMCM. Strobe this bit to assert the
|
||||
-- reset to the MMCM. Default is reset asserted. Write-only.
|
||||
-- </info>
|
||||
-- </bitfield>
|
||||
-- </register>
|
||||
--
|
||||
-- <register name="PhaseShiftControl" size="32" offset="0x24" attributes="Readable|Writable">
|
||||
-- <info>
|
||||
-- Phase Shift for RadioClkMmcm.
|
||||
-- </info>
|
||||
-- <bitfield name="PsDone" range="28">
|
||||
-- <info>
|
||||
-- This bit should set after a shift operation successfully completes.
|
||||
-- Reading this register will clear this bit. Read-only.
|
||||
-- </info>
|
||||
-- </bitfield>
|
||||
-- <bitfield name="PsInc" range="0" attributes="Strobe">
|
||||
-- <info>
|
||||
-- Strobe this bit to increment the phase. This bit is self-clearing and will
|
||||
-- always return '0' when read. If PsInc and PsDec are asserted together,
|
||||
-- the phase will increment.
|
||||
-- </info>
|
||||
-- </bitfield>
|
||||
-- <bitfield name="PsDec" range="4" attributes="Strobe">
|
||||
-- <info>
|
||||
-- Strobe this bit to decrement the phase. This bit is self-clearing and will
|
||||
-- always return '0' when read. If PsInc and PsDec are asserted together,
|
||||
-- the phase will increment.
|
||||
-- </info>
|
||||
-- </bitfield>
|
||||
-- <bitfield name="PsEnabledForFdbClk" range="16">
|
||||
-- <info>
|
||||
-- Read-only.
|
||||
-- </info>
|
||||
-- </bitfield>
|
||||
-- </register>
|
||||
--
|
||||
-- <register name="RadioClkEnables" size="32" offset="0x28" attributes="Readable|Writable">
|
||||
-- <info>
|
||||
-- </info>
|
||||
-- <bitfield name="RadioClk3xEnabled" range="8">
|
||||
-- <info>
|
||||
-- Set to '1' to enable the clock. Default disabled = '0'.
|
||||
-- Do so ONLY after the MMCM is out of reset and locked!
|
||||
-- </info>
|
||||
-- </bitfield>
|
||||
-- <bitfield name="RadioClk2xEnabled" range="4">
|
||||
-- <info>
|
||||
-- Set to '1' to enable the clock. Default disabled = '0'.
|
||||
-- Do so ONLY after the MMCM is out of reset and locked!
|
||||
-- </info>
|
||||
-- </bitfield>
|
||||
-- <bitfield name="RadioClk1xEnabled" range="0">
|
||||
-- <info>
|
||||
-- Set to '1' to enable the clock. Default disabled = '0'.
|
||||
-- Do so ONLY after the MMCM is out of reset and locked!
|
||||
-- </info>
|
||||
-- </bitfield>
|
||||
-- </register>
|
||||
--
|
||||
-- <register name="MgtRefClkStatus" size="32" offset="0x30" attributes="Readable">
|
||||
-- <info>
|
||||
-- </info>
|
||||
-- <bitfield name="JesdRefClkPresent" range="0">
|
||||
-- <info>
|
||||
-- Live indicator of the MGT Reference Clock toggling and within expected
|
||||
-- frequency limits. If this bit is de-asserted, then the JESD204b core will
|
||||
-- not function correctly!
|
||||
-- </info>
|
||||
-- </bitfield>
|
||||
-- </register>
|
||||
--
|
||||
-- </group>
|
||||
--
|
||||
--</regmap>
|
||||
--XmlParse xml_off
|
||||
@@ -0,0 +1,116 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- File: DaughterboardRegs.vhd
|
||||
-- Author: Daniel Jepson
|
||||
-- Original Project: N310
|
||||
-- Date: 27 April 2016
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
-- Copyright 2016-2018 Ettus Research, A National Instruments Company
|
||||
-- SPDX-License-Identifier: LGPL-3.0
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Purpose:
|
||||
--
|
||||
-- Register interface to the semi-static control lines for the Mg
|
||||
-- Daughterboard.
|
||||
--
|
||||
-- XML register definition is included below the module.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
library work;
|
||||
use work.PkgDaughterboardRegMap.all;
|
||||
use work.PkgRegs.all;
|
||||
|
||||
|
||||
entity DaughterboardRegs is
|
||||
port(
|
||||
-- Async reset. Can be tied low if desired.
|
||||
aReset : in boolean;
|
||||
-- Sync reset... used in the same places as the async one.
|
||||
bReset : in boolean;
|
||||
BusClk : in std_logic;
|
||||
|
||||
bRegPortOut : out RegPortOut_t;
|
||||
bRegPortIn : in RegPortIn_t;
|
||||
|
||||
-- Slot and DB ID values. These should be tied to constants!
|
||||
kDbId : in std_logic_vector(15 downto 0);
|
||||
kSlotId : in std_logic
|
||||
|
||||
);
|
||||
end DaughterboardRegs;
|
||||
|
||||
|
||||
architecture RTL of DaughterboardRegs is
|
||||
|
||||
--vhook_sigstart
|
||||
--vhook_sigend
|
||||
|
||||
signal bRegPortOutLcl : RegPortOut_t := kRegPortOutZero;
|
||||
|
||||
begin
|
||||
|
||||
|
||||
-- Read Registers : -------------------------------------------------------------------
|
||||
-- ------------------------------------------------------------------------------------
|
||||
ReadRegisters: process(aReset, BusClk)
|
||||
begin
|
||||
if aReset then
|
||||
bRegPortOutLcl <= kRegPortOutZero;
|
||||
elsif rising_edge(BusClk) then
|
||||
if bReset then
|
||||
bRegPortOutLcl <= kRegPortOutZero;
|
||||
else
|
||||
-- De-assert strobes
|
||||
bRegPortOutLcl.Data <= kRegPortDataZero;
|
||||
|
||||
-- All of these transactions only take one clock cycle, so we do not have to
|
||||
-- de-assert the Ready signal (ever).
|
||||
bRegPortOutLcl.Ready <= true;
|
||||
|
||||
if RegRead(kDaughterboardId, bRegPortIn) then
|
||||
bRegPortOutLcl.Data(kDbIdValMsb downto kDbIdVal) <= kDbId;
|
||||
bRegPortOutLcl.Data(kSlotIdVal) <= kSlotId;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end process ReadRegisters;
|
||||
|
||||
-- Local to output
|
||||
bRegPortOut <= bRegPortOutLcl;
|
||||
|
||||
|
||||
end RTL;
|
||||
|
||||
|
||||
--XmlParse xml_on
|
||||
--<regmap name="DaughterboardRegMap">
|
||||
-- <group name="StaticControl" order="1">
|
||||
--
|
||||
-- <register name="DaughterboardId" size="32" offset="0x30" attributes="Readable">
|
||||
-- <info>
|
||||
-- </info>
|
||||
-- <bitfield name="DbIdVal" range="15..0">
|
||||
-- <info>
|
||||
-- ID for the DB with which this file is designed to communicate. Matches the DB
|
||||
-- EEPROM ID.
|
||||
-- </info>
|
||||
-- </bitfield>
|
||||
-- <bitfield name="SlotIdVal" range="16">
|
||||
-- <info>
|
||||
-- ID for the Slot this module controls. Options are 0 and 1 for the N310 MB.
|
||||
-- </info>
|
||||
-- </bitfield>
|
||||
-- </register>
|
||||
--
|
||||
-- </group>
|
||||
--
|
||||
--
|
||||
--</regmap>
|
||||
--XmlParse xml_off
|
||||
@@ -0,0 +1,562 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- File: DbCore.vhd
|
||||
-- Author: Daniel Jepson
|
||||
-- Original Project: N310
|
||||
-- Date: 12 April 2017
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
-- Copyright 2017-2018 Ettus Research, A National Instruments Company
|
||||
-- SPDX-License-Identifier: LGPL-3.0
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Purpose:
|
||||
--
|
||||
-- Wrapper file for Daughterboard Control. This includes the semi-static control
|
||||
-- and status registers, clocking, synchronization, and JESD204B cores.
|
||||
--
|
||||
-- There is no version register for the plain-text files here.
|
||||
-- Version control for the Sync and JESD204B cores is internal to the netlists.
|
||||
--
|
||||
-- The resets for this core are almost entirely local and/or synchronous.
|
||||
-- bBusReset is a Synchronous reset on the BusClk domain that resets all of the
|
||||
-- registers connected to the RegPort, as well as any other stray registers
|
||||
-- connected to the BusClk. All other resets are local to the modules they touch.
|
||||
-- No other reset drives all modules universally.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.PkgMgPersonality.all;
|
||||
use work.PkgRegs.all;
|
||||
use work.PkgJesdConfig.all;
|
||||
|
||||
|
||||
entity DbCore is
|
||||
generic(
|
||||
-- Set to '1' to include the White Rabbit TDC.
|
||||
kInclWhiteRabbitTdc : std_logic := '0'
|
||||
);
|
||||
port(
|
||||
|
||||
-- Resets --
|
||||
-- Synchronous Reset for the BusClk domain (mainly for the RegPort)
|
||||
bBusReset : in std_logic;
|
||||
|
||||
-- Clocks --
|
||||
-- Register Bus Clock (any frequency)
|
||||
BusClk : in std_logic;
|
||||
-- Always-on at 40 MHz
|
||||
Clk40 : in std_logic;
|
||||
-- Super secret crazy awesome measurement clock at weird frequencies.
|
||||
MeasClk : in std_logic;
|
||||
-- FPGA Sample Clock from DB LMK
|
||||
FpgaClk_p : in std_logic;
|
||||
FpgaClk_n : in std_logic;
|
||||
|
||||
-- Sample Clock Sharing. The clocks generated in this module are exported out to the
|
||||
-- top level so they can be shared amongst daughterboards. Therefore they must be
|
||||
-- driven back into the SampleClk*x inputs at a higher level in order for this module
|
||||
-- to work correctly. There are a few isolated cases where SampleClk*xOut is used
|
||||
-- directly in this module, and those are documented below.
|
||||
SampleClk1xOut : out std_logic;
|
||||
SampleClk1x : in std_logic;
|
||||
SampleClk2xOut : out std_logic;
|
||||
SampleClk2x : in std_logic;
|
||||
|
||||
|
||||
-- Register Ports --
|
||||
--
|
||||
-- Only synchronous resets can be used for these ports!
|
||||
bRegPortInFlat : in std_logic_vector(49 downto 0);
|
||||
bRegPortOutFlat : out std_logic_vector(33 downto 0);
|
||||
|
||||
-- Slot ID value. This should be tied to a constant!
|
||||
kSlotId : in std_logic;
|
||||
|
||||
|
||||
-- SYSREF --
|
||||
--
|
||||
-- SYSREF direct from the LMK
|
||||
sSysRefFpgaLvds_p,
|
||||
sSysRefFpgaLvds_n : in std_logic;
|
||||
-- SYNC directly to the LMK
|
||||
aLmkSync : out std_logic;
|
||||
|
||||
|
||||
-- JESD Signals --
|
||||
--
|
||||
-- GTX Sample Clock Reference Input. Direct connect to FPGA pins.
|
||||
JesdRefClk_p,
|
||||
JesdRefClk_n : in std_logic;
|
||||
|
||||
-- ADC JESD PHY Interface. Direct connect to FPGA pins.
|
||||
aAdcRx_p,
|
||||
aAdcRx_n : in std_logic_vector(3 downto 0);
|
||||
aSyncAdcOut_n : out std_logic;
|
||||
|
||||
-- DAC JESD PHY Interface. Direct connect to FPGA pins.
|
||||
aDacTx_p,
|
||||
aDacTx_n : out std_logic_vector(3 downto 0);
|
||||
aSyncDacIn_n : in std_logic;
|
||||
|
||||
|
||||
-- Data Pipes to/from the DACs/ADCs --
|
||||
--
|
||||
-- - Data is presented as one sample per cycle.
|
||||
-- - sAdcDataValid asserts when ADC data is valid.
|
||||
-- - sDacReadyForInput asserts when DAC data is ready to be received.
|
||||
--
|
||||
-- Reset Crossings:
|
||||
-- The ADC data and valid outputs are synchronously cleared before the asynchronous
|
||||
-- reset is asserted--preventing any reset crossing issues here between the RX
|
||||
-- (internal to the core) reset and the no-reset domain of RFNoC.
|
||||
--
|
||||
-- The DAC samples should be zeros on reset de-assertion due to RFI being de-asserted
|
||||
-- in reset. If they are not zeros, then it is still OK because data is ignored until
|
||||
-- RFI is asserted. DAC RFI is double-synchronized to protect against the reset
|
||||
-- crossing. This is safe to do because it simply delays the output of RFI by two
|
||||
-- cycles on the assertion edge, and as long as reset is held for more than two
|
||||
-- cycles, the de-assertion edge of RFI should come long before the TX module is
|
||||
-- taken out of reset.
|
||||
sAdcDataValid : out std_logic;
|
||||
sAdcDataSamples0I : out std_logic_vector(15 downto 0);
|
||||
sAdcDataSamples0Q : out std_logic_vector(15 downto 0);
|
||||
sAdcDataSamples1I : out std_logic_vector(15 downto 0);
|
||||
sAdcDataSamples1Q : out std_logic_vector(15 downto 0);
|
||||
sDacReadyForInput : out std_logic;
|
||||
sDacDataSamples0I : in std_logic_vector(15 downto 0);
|
||||
sDacDataSamples0Q : in std_logic_vector(15 downto 0);
|
||||
sDacDataSamples1I : in std_logic_vector(15 downto 0);
|
||||
sDacDataSamples1Q : in std_logic_vector(15 downto 0);
|
||||
|
||||
|
||||
-- RefClk & Timing & Sync --
|
||||
RefClk : in std_logic;
|
||||
rPpsPulse : in std_logic;
|
||||
rGatedPulseToPin : inout std_logic; -- straight to pin
|
||||
sGatedPulseToPin : inout std_logic; -- straight to pin
|
||||
sPps : out std_logic;
|
||||
sPpsToIob : out std_logic;
|
||||
|
||||
-- White Rabbit Timing & Sync --
|
||||
WrRefClk : in std_logic;
|
||||
rWrPpsPulse : in std_logic;
|
||||
rWrGatedPulseToPin : inout std_logic; -- straight to pin
|
||||
sWrGatedPulseToPin : inout std_logic; -- straight to pin
|
||||
aPpsSfpSel : in std_logic_vector(1 downto 0);
|
||||
|
||||
|
||||
-- Debug for JESD
|
||||
sAdcSync : out std_logic;
|
||||
sDacSync : out std_logic;
|
||||
sSysRef : out std_logic;
|
||||
|
||||
-- Debug for Timing & Sync
|
||||
rRpTransfer : out std_logic;
|
||||
sSpTransfer : out std_logic;
|
||||
rWrRpTransfer : out std_logic;
|
||||
sWrSpTransfer : out std_logic
|
||||
);
|
||||
|
||||
end DbCore;
|
||||
|
||||
|
||||
architecture RTL of DbCore is
|
||||
|
||||
component Jesd204bXcvrCore
|
||||
port (
|
||||
bBusReset : in STD_LOGIC;
|
||||
BusClk : in STD_LOGIC;
|
||||
ReliableClk40 : in STD_LOGIC;
|
||||
FpgaClk1x : in STD_LOGIC;
|
||||
FpgaClk2x : in STD_LOGIC;
|
||||
bFpgaClksStable : in STD_LOGIC;
|
||||
bRegPortInFlat : in STD_LOGIC_VECTOR(49 downto 0);
|
||||
bRegPortOutFlat : out STD_LOGIC_VECTOR(33 downto 0);
|
||||
aLmkSync : out STD_LOGIC;
|
||||
cSysRefFpgaLvds_p : in STD_LOGIC;
|
||||
cSysRefFpgaLvds_n : in STD_LOGIC;
|
||||
fSysRef : out STD_LOGIC;
|
||||
CaptureSysRefClk : in STD_LOGIC;
|
||||
JesdRefClk_p : in STD_LOGIC;
|
||||
JesdRefClk_n : in STD_LOGIC;
|
||||
bJesdRefClkPresent : out STD_LOGIC;
|
||||
aAdcRx_p : in STD_LOGIC_VECTOR(3 downto 0);
|
||||
aAdcRx_n : in STD_LOGIC_VECTOR(3 downto 0);
|
||||
aSyncAdcOut_n : out STD_LOGIC;
|
||||
aDacTx_p : out STD_LOGIC_VECTOR(3 downto 0);
|
||||
aDacTx_n : out STD_LOGIC_VECTOR(3 downto 0);
|
||||
aSyncDacIn_n : in STD_LOGIC;
|
||||
fAdc0DataFlat : out STD_LOGIC_VECTOR(31 downto 0);
|
||||
fAdc1DataFlat : out STD_LOGIC_VECTOR(31 downto 0);
|
||||
fDac0DataFlat : in STD_LOGIC_VECTOR(31 downto 0);
|
||||
fDac1DataFlat : in STD_LOGIC_VECTOR(31 downto 0);
|
||||
fAdcDataValid : out STD_LOGIC;
|
||||
fDacReadyForInput : out STD_LOGIC;
|
||||
aDacSync : out STD_LOGIC;
|
||||
aAdcSync : out STD_LOGIC);
|
||||
end component;
|
||||
|
||||
function to_Boolean (s : std_ulogic) return boolean is
|
||||
begin
|
||||
return (To_X01(s)='1');
|
||||
end to_Boolean;
|
||||
|
||||
function to_StdLogic(b : boolean) return std_ulogic is
|
||||
begin
|
||||
if b then
|
||||
return '1';
|
||||
else
|
||||
return '0';
|
||||
end if;
|
||||
end to_StdLogic;
|
||||
|
||||
--vhook_sigstart
|
||||
signal aAdcSync: STD_LOGIC;
|
||||
signal aDacSync: STD_LOGIC;
|
||||
signal bClockingRegPortOut: RegPortOut_t;
|
||||
signal bDbRegPortOut: RegPortOut_t;
|
||||
signal bFpgaClksStable: STD_LOGIC;
|
||||
signal bJesdCoreRegPortInFlat: STD_LOGIC_VECTOR(49 downto 0);
|
||||
signal bJesdCoreRegPortOutFlat: STD_LOGIC_VECTOR(33 downto 0);
|
||||
signal bJesdRefClkPresent: STD_LOGIC;
|
||||
signal bRadioClk1xEnabled: std_logic;
|
||||
signal bRadioClk2xEnabled: std_logic;
|
||||
signal bRadioClk3xEnabled: std_logic;
|
||||
signal bRadioClkMmcmReset: std_logic;
|
||||
signal bRadioClksValid: std_logic;
|
||||
signal pPsDone: std_logic;
|
||||
signal pPsEn: std_logic;
|
||||
signal pPsInc: std_logic;
|
||||
signal PsClk: std_logic;
|
||||
signal sAdc0DataFlat: STD_LOGIC_VECTOR(31 downto 0);
|
||||
signal sAdc1DataFlat: STD_LOGIC_VECTOR(31 downto 0);
|
||||
signal SampleClk1xOutLcl: std_logic;
|
||||
signal sDac0DataFlat: STD_LOGIC_VECTOR(31 downto 0);
|
||||
signal sDac1DataFlat: STD_LOGIC_VECTOR(31 downto 0);
|
||||
signal sDacReadyForInputAsyncReset: STD_LOGIC;
|
||||
signal sRegPps: std_logic;
|
||||
signal sSysRefAsyncReset: STD_LOGIC;
|
||||
signal sWrPps: std_logic;
|
||||
--vhook_sigend
|
||||
|
||||
signal bJesdRegPortInGrp, bSyncRegPortIn, bWrSyncRegPortIn, bRegPortIn : RegPortIn_t;
|
||||
signal bJesdRegPortOut, bSyncRegPortOut, bWrSyncRegPortOut, bRegPortOut : RegPortOut_t;
|
||||
|
||||
signal sDacReadyForInput_ms, sDacReadyForInputLcl,
|
||||
sDacSync_ms, sDacSyncLcl,
|
||||
sAdcSync_ms, sAdcSyncLcl,
|
||||
sSysRef_ms, sSysRefLcl : std_logic := '0';
|
||||
|
||||
signal sAdc0Data, sAdc1Data : AdcData_t;
|
||||
signal sDac0Data, sDac1Data : DacData_t;
|
||||
|
||||
signal sPpsSfpSel_ms, sPpsSfpSel : std_logic_vector(1 downto 0) := (others => '0');
|
||||
signal sUseWrTdcPps : boolean := false;
|
||||
signal sPpsInt, sPpsMuxed : std_logic := '0';
|
||||
|
||||
attribute ASYNC_REG : string;
|
||||
attribute ASYNC_REG of sDacReadyForInput_ms : signal is "true";
|
||||
attribute ASYNC_REG of sDacReadyForInputLcl : signal is "true";
|
||||
attribute ASYNC_REG of sDacSync_ms : signal is "true";
|
||||
attribute ASYNC_REG of sDacSyncLcl : signal is "true";
|
||||
attribute ASYNC_REG of sAdcSync_ms : signal is "true";
|
||||
attribute ASYNC_REG of sAdcSyncLcl : signal is "true";
|
||||
attribute ASYNC_REG of sSysRef_ms : signal is "true";
|
||||
attribute ASYNC_REG of sSysRefLcl : signal is "true";
|
||||
attribute ASYNC_REG of sPpsSfpSel_ms : signal is "true";
|
||||
attribute ASYNC_REG of sPpsSfpSel : signal is "true";
|
||||
|
||||
begin
|
||||
|
||||
bRegPortOutFlat <= Flatten(bRegPortOut);
|
||||
bRegPortIn <= Unflatten(bRegPortInFlat);
|
||||
|
||||
|
||||
-- Combine return RegPorts.
|
||||
bRegPortOut <= bJesdRegPortOut
|
||||
+ bClockingRegPortOut
|
||||
+ bSyncRegPortOut + bWrSyncRegPortOut
|
||||
+ bDbRegPortOut;
|
||||
|
||||
|
||||
-- Clocking : -------------------------------------------------------------------------
|
||||
-- Automatically export the Sample Clocks and only use the incoming clocks in the
|
||||
-- remainder of the logic. For a single module, the clocks must be looped back
|
||||
-- in at a higher level!
|
||||
-- ------------------------------------------------------------------------------------
|
||||
|
||||
--vhook_e RadioClocking
|
||||
--vhook_a aReset false
|
||||
--vhook_a bReset to_boolean(bBusReset)
|
||||
--vhook_a RadioClk1x SampleClk1xOutLcl
|
||||
--vhook_a RadioClk2x SampleClk2xOut
|
||||
--vhook_a RadioClk3x open
|
||||
RadioClockingx: entity work.RadioClocking (rtl)
|
||||
port map (
|
||||
aReset => false, --in boolean
|
||||
bReset => to_boolean(bBusReset), --in boolean
|
||||
BusClk => BusClk, --in std_logic
|
||||
bRadioClkMmcmReset => bRadioClkMmcmReset, --in std_logic
|
||||
bRadioClksValid => bRadioClksValid, --out std_logic
|
||||
bRadioClk1xEnabled => bRadioClk1xEnabled, --in std_logic
|
||||
bRadioClk2xEnabled => bRadioClk2xEnabled, --in std_logic
|
||||
bRadioClk3xEnabled => bRadioClk3xEnabled, --in std_logic
|
||||
pPsInc => pPsInc, --in std_logic
|
||||
pPsEn => pPsEn, --in std_logic
|
||||
PsClk => PsClk, --in std_logic
|
||||
pPsDone => pPsDone, --out std_logic
|
||||
FpgaClk_n => FpgaClk_n, --in std_logic
|
||||
FpgaClk_p => FpgaClk_p, --in std_logic
|
||||
RadioClk1x => SampleClk1xOutLcl, --out std_logic
|
||||
RadioClk2x => SampleClk2xOut, --out std_logic
|
||||
RadioClk3x => open); --out std_logic
|
||||
|
||||
-- We need an internal copy of SampleClk1x for the TDC, since we don't want to try
|
||||
-- and align the other DB's clock accidentally.
|
||||
SampleClk1xOut <= SampleClk1xOutLcl;
|
||||
|
||||
--vhook_e ClockingRegs
|
||||
--vhook_a aReset false
|
||||
--vhook_a bReset to_boolean(bBusReset)
|
||||
--vhook_a bRegPortOut bClockingRegPortOut
|
||||
--vhook_a aRadioClksValid bRadioClksValid
|
||||
ClockingRegsx: entity work.ClockingRegs (RTL)
|
||||
port map (
|
||||
aReset => false, --in boolean
|
||||
bReset => to_boolean(bBusReset), --in boolean
|
||||
BusClk => BusClk, --in std_logic
|
||||
bRegPortOut => bClockingRegPortOut, --out RegPortOut_t
|
||||
bRegPortIn => bRegPortIn, --in RegPortIn_t
|
||||
pPsInc => pPsInc, --out std_logic
|
||||
pPsEn => pPsEn, --out std_logic
|
||||
pPsDone => pPsDone, --in std_logic
|
||||
PsClk => PsClk, --out std_logic
|
||||
bRadioClkMmcmReset => bRadioClkMmcmReset, --out std_logic
|
||||
aRadioClksValid => bRadioClksValid, --in std_logic
|
||||
bRadioClk1xEnabled => bRadioClk1xEnabled, --out std_logic
|
||||
bRadioClk2xEnabled => bRadioClk2xEnabled, --out std_logic
|
||||
bRadioClk3xEnabled => bRadioClk3xEnabled, --out std_logic
|
||||
bJesdRefClkPresent => bJesdRefClkPresent); --in std_logic
|
||||
|
||||
|
||||
|
||||
-- JESD204B : -------------------------------------------------------------------------
|
||||
-- ------------------------------------------------------------------------------------
|
||||
|
||||
bJesdRegPortInGrp <= Mask(RegPortIn => bRegPortIn,
|
||||
kRegisterOffset => kJesdRegGroupInDbRegs); -- 0x2000 to 0x3FFC
|
||||
|
||||
-- Expand/compress the RegPort for moving through the netlist boundary.
|
||||
bJesdRegPortOut <= Unflatten(bJesdCoreRegPortOutFlat);
|
||||
bJesdCoreRegPortInFlat <= Flatten(bJesdRegPortInGrp);
|
||||
|
||||
--vhook Jesd204bXcvrCore
|
||||
--vhook_a bRegPortInFlat bJesdCoreRegPortInFlat
|
||||
--vhook_a bRegPortOutFlat bJesdCoreRegPortOutFlat
|
||||
--vhook_a FpgaClk1x SampleClk1x
|
||||
--vhook_a FpgaClk2x SampleClk2x
|
||||
--vhook_a ReliableClk40 Clk40
|
||||
--vhook_a CaptureSysRefClk SampleClk1xOutLcl
|
||||
--vhook_a cSysRefFpgaLvds_p sSysRefFpgaLvds_p
|
||||
--vhook_a cSysRefFpgaLvds_n sSysRefFpgaLvds_n
|
||||
--vhook_a fSysRef sSysRefAsyncReset
|
||||
--vhook_a fDacReadyForInput sDacReadyForInputAsyncReset
|
||||
--vhook_a {^f(.*)} s$1
|
||||
Jesd204bXcvrCorex: Jesd204bXcvrCore
|
||||
port map (
|
||||
bBusReset => bBusReset, --in STD_LOGIC
|
||||
BusClk => BusClk, --in STD_LOGIC
|
||||
ReliableClk40 => Clk40, --in STD_LOGIC
|
||||
FpgaClk1x => SampleClk1x, --in STD_LOGIC
|
||||
FpgaClk2x => SampleClk2x, --in STD_LOGIC
|
||||
bFpgaClksStable => bFpgaClksStable, --in STD_LOGIC
|
||||
bRegPortInFlat => bJesdCoreRegPortInFlat, --in STD_LOGIC_VECTOR(49:0)
|
||||
bRegPortOutFlat => bJesdCoreRegPortOutFlat, --out STD_LOGIC_VECTOR(33:0)
|
||||
aLmkSync => aLmkSync, --out STD_LOGIC
|
||||
cSysRefFpgaLvds_p => sSysRefFpgaLvds_p, --in STD_LOGIC
|
||||
cSysRefFpgaLvds_n => sSysRefFpgaLvds_n, --in STD_LOGIC
|
||||
fSysRef => sSysRefAsyncReset, --out STD_LOGIC
|
||||
CaptureSysRefClk => SampleClk1xOutLcl, --in STD_LOGIC
|
||||
JesdRefClk_p => JesdRefClk_p, --in STD_LOGIC
|
||||
JesdRefClk_n => JesdRefClk_n, --in STD_LOGIC
|
||||
bJesdRefClkPresent => bJesdRefClkPresent, --out STD_LOGIC
|
||||
aAdcRx_p => aAdcRx_p, --in STD_LOGIC_VECTOR(3:0)
|
||||
aAdcRx_n => aAdcRx_n, --in STD_LOGIC_VECTOR(3:0)
|
||||
aSyncAdcOut_n => aSyncAdcOut_n, --out STD_LOGIC
|
||||
aDacTx_p => aDacTx_p, --out STD_LOGIC_VECTOR(3:0)
|
||||
aDacTx_n => aDacTx_n, --out STD_LOGIC_VECTOR(3:0)
|
||||
aSyncDacIn_n => aSyncDacIn_n, --in STD_LOGIC
|
||||
fAdc0DataFlat => sAdc0DataFlat, --out STD_LOGIC_VECTOR(31:0)
|
||||
fAdc1DataFlat => sAdc1DataFlat, --out STD_LOGIC_VECTOR(31:0)
|
||||
fDac0DataFlat => sDac0DataFlat, --in STD_LOGIC_VECTOR(31:0)
|
||||
fDac1DataFlat => sDac1DataFlat, --in STD_LOGIC_VECTOR(31:0)
|
||||
fAdcDataValid => sAdcDataValid, --out STD_LOGIC
|
||||
fDacReadyForInput => sDacReadyForInputAsyncReset, --out STD_LOGIC
|
||||
aDacSync => aDacSync, --out STD_LOGIC
|
||||
aAdcSync => aAdcSync); --out STD_LOGIC
|
||||
|
||||
JesdDoubleSyncToNoResetSampleClk : process (SampleClk1x)
|
||||
begin
|
||||
if rising_edge(SampleClk1x) then
|
||||
sDacReadyForInput_ms <= sDacReadyForInputAsyncReset;
|
||||
sDacReadyForInputLcl <= sDacReadyForInput_ms;
|
||||
-- No clock crossing here -- just reset, although the prefix declares otherwise...
|
||||
sDacSync_ms <= aDacSync;
|
||||
sDacSyncLcl <= sDacSync_ms;
|
||||
sAdcSync_ms <= aAdcSync;
|
||||
sAdcSyncLcl <= sAdcSync_ms;
|
||||
sSysRef_ms <= sSysRefAsyncReset;
|
||||
sSysRefLcl <= sSysRef_ms;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Locals to outputs.
|
||||
sDacReadyForInput <= sDacReadyForInputLcl;
|
||||
sDacSync <= sDacSyncLcl;
|
||||
sAdcSync <= sAdcSyncLcl;
|
||||
sSysRef <= sSysRefLcl;
|
||||
|
||||
-- Just combine the first two enables, since they're the ones that are used for JESD.
|
||||
-- No reset crossing here, since bFpgaClksStable is only received by a no-reset domain
|
||||
-- and the MGTs directly.
|
||||
bFpgaClksStable <= bRadioClksValid and bRadioClk1xEnabled and bRadioClk2xEnabled;
|
||||
|
||||
-- Compress/expand the flat data types from the netlist and route to top level.
|
||||
sAdc0Data <= Unflatten(sAdc0DataFlat);
|
||||
sAdc1Data <= Unflatten(sAdc1DataFlat);
|
||||
sDac0DataFlat <= Flatten(sDac0Data);
|
||||
sDac1DataFlat <= Flatten(sDac1Data);
|
||||
|
||||
sAdcDataSamples0I <= sAdc0Data.I;
|
||||
sAdcDataSamples0Q <= sAdc0Data.Q;
|
||||
sAdcDataSamples1I <= sAdc1Data.I;
|
||||
sAdcDataSamples1Q <= sAdc1Data.Q;
|
||||
|
||||
sDac0Data.I <= sDacDataSamples0I;
|
||||
sDac0Data.Q <= sDacDataSamples0Q;
|
||||
sDac1Data.I <= sDacDataSamples1I;
|
||||
sDac1Data.Q <= sDacDataSamples1Q;
|
||||
|
||||
|
||||
-- Timing and Sync : ------------------------------------------------------------------
|
||||
-- ------------------------------------------------------------------------------------
|
||||
|
||||
bSyncRegPortIn <= Mask(RegPortIn => bRegPortIn,
|
||||
kRegisterOffset => kTdc0OffsetsInEndpoint); -- 0x0200
|
||||
|
||||
--vhook_e TdcWrapper
|
||||
--vhook_# Use the local copy of the SampleClock, since we want the TDC to measure the
|
||||
--vhook_# clock offset for this daughterboard, not the global SampleClock.
|
||||
--vhook_a SampleClk SampleClk1xOutLcl
|
||||
--vhook_a sPpsPulse sRegPps
|
||||
TdcWrapperx: entity work.TdcWrapper (struct)
|
||||
port map (
|
||||
BusClk => BusClk, --in std_logic
|
||||
bBusReset => bBusReset, --in std_logic
|
||||
RefClk => RefClk, --in std_logic
|
||||
SampleClk => SampleClk1xOutLcl, --in std_logic
|
||||
MeasClk => MeasClk, --in std_logic
|
||||
bSyncRegPortOut => bSyncRegPortOut, --out RegPortOut_t
|
||||
bSyncRegPortIn => bSyncRegPortIn, --in RegPortIn_t
|
||||
rPpsPulse => rPpsPulse, --in std_logic
|
||||
sPpsPulse => sRegPps, --out std_logic
|
||||
rRpTransfer => rRpTransfer, --out std_logic
|
||||
sSpTransfer => sSpTransfer, --out std_logic
|
||||
rGatedPulseToPin => rGatedPulseToPin, --inout std_logic
|
||||
sGatedPulseToPin => sGatedPulseToPin); --inout std_logic
|
||||
|
||||
WrTdcGen: if kInclWhiteRabbitTdc = '1' generate
|
||||
bWrSyncRegPortIn <= Mask(RegPortIn => bRegPortIn,
|
||||
kRegisterOffset => kTdc1OffsetsInEndpoint); -- 0x0400
|
||||
|
||||
--vhook_e TdcWrapper WrTdcWrapperx
|
||||
--vhook_# Use the local copy of the SampleClock, since we want the TDC to measure the
|
||||
--vhook_# clock offset for this daughterboard, not the global SampleClock.
|
||||
--vhook_a bSyncRegPortIn bWrSyncRegPortIn
|
||||
--vhook_a bSyncRegPortOut bWrSyncRegPortOut
|
||||
--vhook_a SampleClk SampleClk1xOutLcl
|
||||
--vhook_a RefClk WrRefClk
|
||||
--vhook_a rPpsPulse rWrPpsPulse
|
||||
--vhook_a sPpsPulse sWrPps
|
||||
--vhook_a rRpTransfer rWrRpTransfer
|
||||
--vhook_a sSpTransfer sWrSpTransfer
|
||||
--vhook_a rGatedPulseToPin rWrGatedPulseToPin
|
||||
--vhook_a sGatedPulseToPin sWrGatedPulseToPin
|
||||
WrTdcWrapperx: entity work.TdcWrapper (struct)
|
||||
port map (
|
||||
BusClk => BusClk, --in std_logic
|
||||
bBusReset => bBusReset, --in std_logic
|
||||
RefClk => WrRefClk, --in std_logic
|
||||
SampleClk => SampleClk1xOutLcl, --in std_logic
|
||||
MeasClk => MeasClk, --in std_logic
|
||||
bSyncRegPortOut => bWrSyncRegPortOut, --out RegPortOut_t
|
||||
bSyncRegPortIn => bWrSyncRegPortIn, --in RegPortIn_t
|
||||
rPpsPulse => rWrPpsPulse, --in std_logic
|
||||
sPpsPulse => sWrPps, --out std_logic
|
||||
rRpTransfer => rWrRpTransfer, --out std_logic
|
||||
sSpTransfer => sWrSpTransfer, --out std_logic
|
||||
rGatedPulseToPin => rWrGatedPulseToPin, --inout std_logic
|
||||
sGatedPulseToPin => sWrGatedPulseToPin); --inout std_logic
|
||||
end generate WrTdcGen;
|
||||
|
||||
WrTdcNotGen: if kInclWhiteRabbitTdc = '0' generate
|
||||
bWrSyncRegPortOut <= kRegPortOutZero;
|
||||
sWrPps <= '0';
|
||||
rWrRpTransfer <= '0';
|
||||
sWrSpTransfer <= '0';
|
||||
rWrGatedPulseToPin <= '0';
|
||||
sWrGatedPulseToPin <= '0';
|
||||
end generate WrTdcNotGen;
|
||||
|
||||
-- Mux the output PPS based on the SFP selection bits. Encoding is one-hot, with zero
|
||||
-- also a valid state. Regardless of whether the user selects SFP0 or SFP1 as the time
|
||||
-- source, there is only one White Rabbit TDC, so '01' and '10' are equivalent.
|
||||
-- '00': Use the PPS output from the "regular" TDC.
|
||||
-- '01': Use the PPS output from the "white rabbit" TDC.
|
||||
-- '10': Use the PPS output from the "white rabbit" TDC.
|
||||
PpsOutputMux : process (SampleClk1xOutLcl)
|
||||
begin
|
||||
if rising_edge(SampleClk1xOutLcl) then
|
||||
-- Double-sync the control bits to the Sample Clock domain.
|
||||
sPpsSfpSel_ms <= aPpsSfpSel;
|
||||
sPpsSfpSel <= sPpsSfpSel_ms;
|
||||
|
||||
-- OR the control bits together to produce a single override enable for the WR TDC.
|
||||
sUseWrTdcPps <= to_boolean(sPpsSfpSel(0) or sPpsSfpSel(1));
|
||||
|
||||
-- Flop the outputs. One flop for the PPS output IOB, the other for use internally.
|
||||
sPpsInt <= sPpsMuxed;
|
||||
end if;
|
||||
end process PpsOutputMux;
|
||||
|
||||
sPpsMuxed <= sWrPps when sUseWrTdcPps else sRegPps;
|
||||
sPps <= sPpsInt;
|
||||
sPpsToIob <= sPpsMuxed; -- No added flop here since there's an IOB outside this module.
|
||||
|
||||
-- Daughterboard Control : ------------------------------------------------------------
|
||||
-- ------------------------------------------------------------------------------------
|
||||
|
||||
--vhook_e DaughterboardRegs
|
||||
--vhook_# Tying this low is safe because the sync reset is used inside DaughterboardRegs.
|
||||
--vhook_a aReset false
|
||||
--vhook_a bReset to_boolean(bBusReset)
|
||||
--vhook_a bRegPortOut bDbRegPortOut
|
||||
--vhook_a kDbId std_logic_vector(to_unsigned(16#150#,16))
|
||||
DaughterboardRegsx: entity work.DaughterboardRegs (RTL)
|
||||
port map (
|
||||
aReset => false, --in boolean
|
||||
bReset => to_boolean(bBusReset), --in boolean
|
||||
BusClk => BusClk, --in std_logic
|
||||
bRegPortOut => bDbRegPortOut, --out RegPortOut_t
|
||||
bRegPortIn => bRegPortIn, --in RegPortIn_t
|
||||
kDbId => std_logic_vector(to_unsigned(16#150#,16)), --in std_logic_vector(15:0)
|
||||
kSlotId => kSlotId); --in std_logic
|
||||
|
||||
|
||||
end RTL;
|
||||
Binary file not shown.
@@ -0,0 +1,56 @@
|
||||
-- Copyright 1986-2015 Xilinx, Inc. All Rights Reserved.
|
||||
-- --------------------------------------------------------------------------------
|
||||
-- Tool Version: Vivado v.2015.4.2 (win64) Build 1494164 Fri Feb 26 04:18:56 MST 2016
|
||||
-- Date : Wed Jan 10 10:53:33 2018
|
||||
-- Host : djepson-lt running 64-bit major release (build 9200)
|
||||
-- Command : write_vhdl -mode synth_stub -force -file ./Jesd204bXcvrCore_stub.vhd
|
||||
-- Design : Jesd204bXcvrCore
|
||||
-- Purpose : Stub declaration of top-level module interface
|
||||
-- Device : xc7z100ffg900-2
|
||||
-- --------------------------------------------------------------------------------
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
|
||||
entity Jesd204bXcvrCore is
|
||||
Port (
|
||||
bBusReset : in STD_LOGIC;
|
||||
BusClk : in STD_LOGIC;
|
||||
ReliableClk40 : in STD_LOGIC;
|
||||
FpgaClk1x : in STD_LOGIC;
|
||||
FpgaClk2x : in STD_LOGIC;
|
||||
bFpgaClksStable : in STD_LOGIC;
|
||||
bRegPortInFlat : in STD_LOGIC_VECTOR ( 49 downto 0 );
|
||||
bRegPortOutFlat : out STD_LOGIC_VECTOR ( 33 downto 0 );
|
||||
aLmkSync : out STD_LOGIC;
|
||||
cSysRefFpgaLvds_p : in STD_LOGIC;
|
||||
cSysRefFpgaLvds_n : in STD_LOGIC;
|
||||
fSysRef : out STD_LOGIC;
|
||||
CaptureSysRefClk : in STD_LOGIC;
|
||||
JesdRefClk_p : in STD_LOGIC;
|
||||
JesdRefClk_n : in STD_LOGIC;
|
||||
bJesdRefClkPresent : out STD_LOGIC;
|
||||
aAdcRx_p : in STD_LOGIC_VECTOR ( 3 downto 0 );
|
||||
aAdcRx_n : in STD_LOGIC_VECTOR ( 3 downto 0 );
|
||||
aSyncAdcOut_n : out STD_LOGIC;
|
||||
aDacTx_p : out STD_LOGIC_VECTOR ( 3 downto 0 );
|
||||
aDacTx_n : out STD_LOGIC_VECTOR ( 3 downto 0 );
|
||||
aSyncDacIn_n : in STD_LOGIC;
|
||||
fAdc0DataFlat : out STD_LOGIC_VECTOR ( 31 downto 0 );
|
||||
fAdc1DataFlat : out STD_LOGIC_VECTOR ( 31 downto 0 );
|
||||
fDac0DataFlat : in STD_LOGIC_VECTOR ( 31 downto 0 );
|
||||
fDac1DataFlat : in STD_LOGIC_VECTOR ( 31 downto 0 );
|
||||
fAdcDataValid : out STD_LOGIC;
|
||||
fDacReadyForInput : out STD_LOGIC;
|
||||
aDacSync : out STD_LOGIC;
|
||||
aAdcSync : out STD_LOGIC
|
||||
);
|
||||
|
||||
end Jesd204bXcvrCore;
|
||||
|
||||
architecture stub of Jesd204bXcvrCore is
|
||||
attribute syn_black_box : boolean;
|
||||
attribute black_box_pad_pin : string;
|
||||
attribute syn_black_box of stub : architecture is true;
|
||||
attribute black_box_pad_pin of stub : architecture is "bBusReset,BusClk,ReliableClk40,FpgaClk1x,FpgaClk2x,bFpgaClksStable,bRegPortInFlat[49:0],bRegPortOutFlat[33:0],aLmkSync,cSysRefFpgaLvds_p,cSysRefFpgaLvds_n,fSysRef,CaptureSysRefClk,JesdRefClk_p,JesdRefClk_n,bJesdRefClkPresent,aAdcRx_p[3:0],aAdcRx_n[3:0],aSyncAdcOut_n,aDacTx_p[3:0],aDacTx_n[3:0],aSyncDacIn_n,fAdc0DataFlat[31:0],fAdc1DataFlat[31:0],fDac0DataFlat[31:0],fDac1DataFlat[31:0],fAdcDataValid,fDacReadyForInput,aDacSync,aAdcSync";
|
||||
begin
|
||||
end;
|
||||
@@ -0,0 +1,107 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- File: PkgClockingRegMap.vhd
|
||||
-- Author: Autogenerated by XmlParse
|
||||
-- Original Project: --
|
||||
-- Date: --
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
-- Copyright 2017 Ettus Research, A National Instruments Company
|
||||
-- SPDX-License-Identifier: LGPL-3.0
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Purpose:
|
||||
-- The constants in this file are autogenerated by XmlParse and should
|
||||
-- be used by testbench code to access specific register fields.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
package PkgClockingRegMap is
|
||||
|
||||
--===============================================================================
|
||||
-- A numerically ordered list of registers and their VHDL source files
|
||||
--===============================================================================
|
||||
|
||||
-- RadioClkMmcm : 0x20 (ClockingRegs.vhd)
|
||||
-- PhaseShiftControl : 0x24 (ClockingRegs.vhd)
|
||||
-- RadioClkEnables : 0x28 (ClockingRegs.vhd)
|
||||
-- MgtRefClkStatus : 0x30 (ClockingRegs.vhd)
|
||||
|
||||
--===============================================================================
|
||||
-- RegTypes
|
||||
--===============================================================================
|
||||
|
||||
--===============================================================================
|
||||
-- Register Group ClockingRegs
|
||||
--===============================================================================
|
||||
|
||||
-- RadioClkMmcm Register (from ClockingRegs.vhd)
|
||||
constant kRadioClkMmcm : integer := 16#20#; -- Register Offset
|
||||
constant kRadioClkMmcmSize: integer := 32; -- register width in bits
|
||||
constant kRadioClkMmcmMask : std_logic_vector(31 downto 0) := X"00000013";
|
||||
constant kRadioClkMmcmResetSetSize : integer := 1; --RadioClkMmcm:RadioClkMmcmResetSet
|
||||
constant kRadioClkMmcmResetSetMsb : integer := 0; --RadioClkMmcm:RadioClkMmcmResetSet
|
||||
constant kRadioClkMmcmResetSet : integer := 0; --RadioClkMmcm:RadioClkMmcmResetSet
|
||||
constant kRadioClkMmcmResetClearSize : integer := 1; --RadioClkMmcm:RadioClkMmcmResetClear
|
||||
constant kRadioClkMmcmResetClearMsb : integer := 1; --RadioClkMmcm:RadioClkMmcmResetClear
|
||||
constant kRadioClkMmcmResetClear : integer := 1; --RadioClkMmcm:RadioClkMmcmResetClear
|
||||
constant kRadioClkMmcmLockedSize : integer := 1; --RadioClkMmcm:RadioClkMmcmLocked
|
||||
constant kRadioClkMmcmLockedMsb : integer := 4; --RadioClkMmcm:RadioClkMmcmLocked
|
||||
constant kRadioClkMmcmLocked : integer := 4; --RadioClkMmcm:RadioClkMmcmLocked
|
||||
|
||||
-- PhaseShiftControl Register (from ClockingRegs.vhd)
|
||||
constant kPhaseShiftControl : integer := 16#24#; -- Register Offset
|
||||
constant kPhaseShiftControlSize: integer := 32; -- register width in bits
|
||||
constant kPhaseShiftControlMask : std_logic_vector(31 downto 0) := X"10010011";
|
||||
constant kPsIncSize : integer := 1; --PhaseShiftControl:PsInc
|
||||
constant kPsIncMsb : integer := 0; --PhaseShiftControl:PsInc
|
||||
constant kPsInc : integer := 0; --PhaseShiftControl:PsInc
|
||||
constant kPsDecSize : integer := 1; --PhaseShiftControl:PsDec
|
||||
constant kPsDecMsb : integer := 4; --PhaseShiftControl:PsDec
|
||||
constant kPsDec : integer := 4; --PhaseShiftControl:PsDec
|
||||
constant kPsEnabledForFdbClkSize : integer := 1; --PhaseShiftControl:PsEnabledForFdbClk
|
||||
constant kPsEnabledForFdbClkMsb : integer := 16; --PhaseShiftControl:PsEnabledForFdbClk
|
||||
constant kPsEnabledForFdbClk : integer := 16; --PhaseShiftControl:PsEnabledForFdbClk
|
||||
constant kPsDoneSize : integer := 1; --PhaseShiftControl:PsDone
|
||||
constant kPsDoneMsb : integer := 28; --PhaseShiftControl:PsDone
|
||||
constant kPsDone : integer := 28; --PhaseShiftControl:PsDone
|
||||
|
||||
-- RadioClkEnables Register (from ClockingRegs.vhd)
|
||||
constant kRadioClkEnables : integer := 16#28#; -- Register Offset
|
||||
constant kRadioClkEnablesSize: integer := 32; -- register width in bits
|
||||
constant kRadioClkEnablesMask : std_logic_vector(31 downto 0) := X"00000111";
|
||||
constant kRadioClk1xEnabledSize : integer := 1; --RadioClkEnables:RadioClk1xEnabled
|
||||
constant kRadioClk1xEnabledMsb : integer := 0; --RadioClkEnables:RadioClk1xEnabled
|
||||
constant kRadioClk1xEnabled : integer := 0; --RadioClkEnables:RadioClk1xEnabled
|
||||
constant kRadioClk2xEnabledSize : integer := 1; --RadioClkEnables:RadioClk2xEnabled
|
||||
constant kRadioClk2xEnabledMsb : integer := 4; --RadioClkEnables:RadioClk2xEnabled
|
||||
constant kRadioClk2xEnabled : integer := 4; --RadioClkEnables:RadioClk2xEnabled
|
||||
constant kRadioClk3xEnabledSize : integer := 1; --RadioClkEnables:RadioClk3xEnabled
|
||||
constant kRadioClk3xEnabledMsb : integer := 8; --RadioClkEnables:RadioClk3xEnabled
|
||||
constant kRadioClk3xEnabled : integer := 8; --RadioClkEnables:RadioClk3xEnabled
|
||||
|
||||
-- MgtRefClkStatus Register (from ClockingRegs.vhd)
|
||||
constant kMgtRefClkStatus : integer := 16#30#; -- Register Offset
|
||||
constant kMgtRefClkStatusSize: integer := 32; -- register width in bits
|
||||
constant kMgtRefClkStatusMask : std_logic_vector(31 downto 0) := X"00000001";
|
||||
constant kJesdRefClkPresentSize : integer := 1; --MgtRefClkStatus:JesdRefClkPresent
|
||||
constant kJesdRefClkPresentMsb : integer := 0; --MgtRefClkStatus:JesdRefClkPresent
|
||||
constant kJesdRefClkPresent : integer := 0; --MgtRefClkStatus:JesdRefClkPresent
|
||||
|
||||
end package;
|
||||
|
||||
package body PkgClockingRegMap is
|
||||
|
||||
-- function kRadioClkMmcmRec not implemented because PkgXReg in this project does not support XReg2_t.
|
||||
|
||||
-- function kPhaseShiftControlRec not implemented because PkgXReg in this project does not support XReg2_t.
|
||||
|
||||
-- function kRadioClkEnablesRec not implemented because PkgXReg in this project does not support XReg2_t.
|
||||
|
||||
-- function kMgtRefClkStatusRec not implemented because PkgXReg in this project does not support XReg2_t.
|
||||
|
||||
end package body;
|
||||
@@ -0,0 +1,56 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- File: PkgDaughterboardRegMap.vhd
|
||||
-- Author: Autogenerated by XmlParse
|
||||
-- Original Project: --
|
||||
-- Date: --
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
-- Copyright 2017 Ettus Research, A National Instruments Company
|
||||
-- SPDX-License-Identifier: LGPL-3.0
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Purpose:
|
||||
-- The constants in this file are autogenerated by XmlParse and should
|
||||
-- be used by testbench code to access specific register fields.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
package PkgDaughterboardRegMap is
|
||||
|
||||
--===============================================================================
|
||||
-- A numerically ordered list of registers and their VHDL source files
|
||||
--===============================================================================
|
||||
|
||||
-- DaughterboardId : 0x630 (DaughterboardRegs.vhd)
|
||||
|
||||
--===============================================================================
|
||||
-- RegTypes
|
||||
--===============================================================================
|
||||
|
||||
--===============================================================================
|
||||
-- Register Group StaticControl
|
||||
--===============================================================================
|
||||
|
||||
-- DaughterboardId Register (from DaughterboardRegs.vhd)
|
||||
constant kDaughterboardId : integer := 16#630#; -- Register Offset
|
||||
constant kDaughterboardIdSize: integer := 32; -- register width in bits
|
||||
constant kDaughterboardIdMask : std_logic_vector(31 downto 0) := X"0001ffff";
|
||||
constant kDbIdValSize : integer := 16; --DaughterboardId:DbIdVal
|
||||
constant kDbIdValMsb : integer := 15; --DaughterboardId:DbIdVal
|
||||
constant kDbIdVal : integer := 0; --DaughterboardId:DbIdVal
|
||||
constant kSlotIdValSize : integer := 1; --DaughterboardId:SlotIdVal
|
||||
constant kSlotIdValMsb : integer := 16; --DaughterboardId:SlotIdVal
|
||||
constant kSlotIdVal : integer := 16; --DaughterboardId:SlotIdVal
|
||||
|
||||
end package;
|
||||
|
||||
package body PkgDaughterboardRegMap is
|
||||
|
||||
-- function kDaughterboardIdRec not implemented because PkgXReg in this project does not support XReg2_t.
|
||||
|
||||
end package body;
|
||||
@@ -0,0 +1,234 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- File: PkgJesdConfig.vhd
|
||||
-- Author: National Instruments
|
||||
-- Original Project: NI 5840
|
||||
-- Date: 11 March 2016
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
-- Copyright 2016-2018 Ettus Research, A National Instruments Company
|
||||
-- SPDX-License-Identifier: LGPL-3.0
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Purpose: JESD204B setup constants and functions. These constants are shared
|
||||
-- between RX and TX JESD cores.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.PkgRegs.all;
|
||||
|
||||
|
||||
package PkgJesdConfig is
|
||||
|
||||
-- "JESD" in ASCII - with the core number 0 or 1 on the LSb.
|
||||
constant kJesdSignature : std_logic_vector(31 downto 0) := x"4a455344";
|
||||
|
||||
-- Register endpoints
|
||||
constant kJesdDrpRegsInEndpoint : RegOffset_t := (kOffset => 16#0800#, -- 0x2800 to
|
||||
kWidth => 16#0800#); -- 0x2FFF
|
||||
|
||||
-- Selects the UsrClk2 for the transceivers. For 64-bit wide transceivers, the
|
||||
-- UsrClk = 2*UserClk2 frequency. For 32-bit wide transceivers, UsrClk = UserClk2
|
||||
-- frequency. This is a generalization, the clock ratio should be confirmed based on
|
||||
-- the transceiver configuration.
|
||||
-- The N310 transceivers use the single rate reference, hence = false.
|
||||
constant kDoubleRateUsrClk : boolean := false;
|
||||
|
||||
-- For the N310, all lanes are in one quad and we use the QPLL.
|
||||
constant kJesdUseQpll : boolean := true;
|
||||
|
||||
constant kAdcDataWidth : integer := 16; -- ADC data width in bits
|
||||
constant kDacDataWidth : integer := 16; -- DAC data width in bits
|
||||
constant kSamplesPerCycle : integer := 1; -- Number of samples per SampleClk1x
|
||||
|
||||
constant kGtxDrpAddrWidth : natural := 9;
|
||||
constant kQpllDrpAddrWidth : natural := 8;
|
||||
-- Max supported number of lanes
|
||||
constant kMaxNumLanes : natural := 4;
|
||||
-- Max supported number of quads (normally there is 1 quad per 4 lanes but disconnect
|
||||
-- the definitions to allow quad sharing)
|
||||
constant kMaxNumQuads : natural := 1;
|
||||
|
||||
|
||||
-- JESD shared setup - LMFS = 4421, HD = 0
|
||||
constant kNumLanes : natural := 4; -- L
|
||||
constant kNumConvs : positive := 4; -- M
|
||||
constant kOctetsPerFrame : natural := 2; -- F
|
||||
constant kDacJesdSamplesPerCycle : integer := 1; -- S
|
||||
constant kOctetsPerLane : natural := 2; -- MGT data is kOctetsPerLane*8 = 16 bits wide
|
||||
constant kNumQuads : natural := kNumLanes/4; -- 4 lanes per quad
|
||||
constant kHighDensity : boolean := false; -- HD
|
||||
constant kConvResBits : positive := kDacDataWidth-2; -- Converter resolution in bits
|
||||
constant kConvSampleBits : positive := kDacDataWidth; -- Sample Length in bits
|
||||
constant kInitLaneAlignCnt : positive := 4;
|
||||
constant kFramesPerMulti : natural := 20; -- K
|
||||
|
||||
-- In the N310 case we are one SPC, so this value is simply the number of frames
|
||||
-- (samples) per multiframe.
|
||||
constant kUserClksPerMulti : integer := kFramesPerMulti;
|
||||
|
||||
|
||||
type NaturalVector is array ( natural range <>) of natural;
|
||||
|
||||
-- The PCB connections are as follows:
|
||||
--
|
||||
-- Transceiver MGT Channel ADC Lane DAC Lane
|
||||
-- *********** *********** ******** ********
|
||||
-- GT0: X0Y8 0 0 0
|
||||
-- GT1: X0Y9 1 1 1
|
||||
-- GT2: X0Y10 2 2 2
|
||||
-- GT3: X0Y11 3 3 3
|
||||
constant kRxLaneIndices : NaturalVector(kNumLanes - 1 downto 0) :=
|
||||
(
|
||||
-- MGT => ADC (in above table)
|
||||
0 => 0,
|
||||
1 => 1,
|
||||
2 => 2,
|
||||
3 => 3
|
||||
);
|
||||
|
||||
constant kTxLaneIndices : NaturalVector(kNumLanes - 1 downto 0) :=
|
||||
(
|
||||
-- MGT => DAC lane
|
||||
0 => 0,
|
||||
1 => 1,
|
||||
2 => 2,
|
||||
3 => 3
|
||||
);
|
||||
|
||||
constant kLaneToQuadMap : NaturalVector(kNumLanes - 1 downto 0) :=
|
||||
(
|
||||
-- All lanes are in one quad
|
||||
0 => 0,
|
||||
1 => 0,
|
||||
2 => 0,
|
||||
3 => 0
|
||||
);
|
||||
|
||||
|
||||
-- The master transceiver channel for channel bonding. E(kMasterBondingChannel)
|
||||
-- must have the highest value decrementing to b"000" for that last channels to bond.
|
||||
constant kMasterBondingChannel : integer := 1;
|
||||
|
||||
-- Channel bonding occurs when a master detects a K-char sequence and aligns its
|
||||
-- internal FIFO to the start of this sequence. A signal is then generated to other
|
||||
-- slave transceivers that cause them to bond to the sequence - this bonding signal is
|
||||
-- cascaded from master to slave to slave to slave, etc where each slave must know how
|
||||
-- many levels to the master there are. The last slave to bond must be at level b"000"
|
||||
-- and the master is at the highest level; the number of levels in the sequence is
|
||||
-- governed by the size of the transceiver FIFO (see the Xilinx user guides for more
|
||||
-- information).
|
||||
type BondLevels_t is array(0 to kNumLanes - 1) of std_logic_vector(2 downto 0);
|
||||
constant kBondLevel : BondLevels_t := (
|
||||
0 => b"000", -- Control from 1
|
||||
1 => b"001", -- Master
|
||||
2 => b"000", -- Control from 1
|
||||
3 => b"000" -- Control from 1
|
||||
);
|
||||
|
||||
-- Option to pipeline stages to improve timing, if needed
|
||||
constant kPipelineDetectCharsStage : boolean := false;
|
||||
constant kPipelineCharReplStage : boolean := false;
|
||||
|
||||
|
||||
-- ADC & DAC Data Types
|
||||
--
|
||||
|
||||
-- ADC Words from JESD204B RX Core. The array is 4 elements wide to accommodate the
|
||||
-- I & Q elements from both RX channels.
|
||||
subtype AdcWord_t is std_logic_vector(kAdcDataWidth - 1 downto 0);
|
||||
type AdcWordArray_t is array(4 - 1 downto 0) of AdcWord_t;
|
||||
|
||||
-- Data types for manipulation and presentation to outside world.
|
||||
type AdcData_t is record
|
||||
I : std_logic_vector(kAdcDataWidth - 1 downto 0);
|
||||
Q : std_logic_vector(kAdcDataWidth - 1 downto 0);
|
||||
end record;
|
||||
|
||||
type DacData_t is record
|
||||
I : std_logic_vector(kDacDataWidth - 1 downto 0);
|
||||
Q : std_logic_vector(kDacDataWidth - 1 downto 0);
|
||||
end record;
|
||||
|
||||
|
||||
-- Flattened data types for passing into and out of pre-synthesized components.
|
||||
subtype AdcDataFlat_t is std_logic_vector(2*kAdcDataWidth - 1 downto 0);
|
||||
subtype DacDataFlat_t is std_logic_vector(2*kDacDataWidth - 1 downto 0);
|
||||
|
||||
-- Functions to convert to/from types defined above.
|
||||
function Flatten (AdcData : AdcData_t) return AdcDataFlat_t;
|
||||
function Unflatten(AdcData : AdcDataFlat_t) return AdcData_t;
|
||||
|
||||
function Flatten (DacData : DacData_t) return DacDataFlat_t;
|
||||
function Unflatten(DacData : DacDataFlat_t) return DacData_t;
|
||||
|
||||
|
||||
end package;
|
||||
|
||||
|
||||
package body PkgJesdConfig is
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-- Flattens AdcData_t to AdcDataFlat_t
|
||||
function Flatten (AdcData : AdcData_t) return AdcDataFlat_t
|
||||
is
|
||||
variable ReturnVar : AdcDataFlat_t;
|
||||
begin
|
||||
ReturnVar := (others => '0');
|
||||
-- MSB is I
|
||||
ReturnVar := AdcData.I & AdcData.Q;
|
||||
return ReturnVar;
|
||||
end function Flatten;
|
||||
|
||||
|
||||
-- UnFlattens AdcDataFlat_t to AdcData_t
|
||||
function Unflatten(AdcData : AdcDataFlat_t) return AdcData_t
|
||||
is
|
||||
variable ReturnVar : AdcData_t;
|
||||
begin
|
||||
ReturnVar := (others => (others => '0'));
|
||||
-- MSB is I
|
||||
ReturnVar.I := AdcData(2*kAdcDataWidth - 1 downto kAdcDataWidth);
|
||||
ReturnVar.Q := AdcData( kAdcDataWidth - 1 downto 0);
|
||||
return ReturnVar;
|
||||
end function Unflatten;
|
||||
|
||||
|
||||
|
||||
-- Flattens DacData_t to DacDataFlat_t
|
||||
function Flatten (DacData : DacData_t) return DacDataFlat_t
|
||||
is
|
||||
variable ReturnVar : DacDataFlat_t;
|
||||
begin
|
||||
ReturnVar := (others => '0');
|
||||
-- MSB is I
|
||||
ReturnVar := DacData.I & DacData.Q;
|
||||
return ReturnVar;
|
||||
end function Flatten;
|
||||
|
||||
|
||||
-- UnFlattens DacDataFlat_t to DacData_t
|
||||
function Unflatten(DacData : DacDataFlat_t) return DacData_t
|
||||
is
|
||||
variable ReturnVar : DacData_t;
|
||||
begin
|
||||
ReturnVar := (others => (others => '0'));
|
||||
-- MSB is I
|
||||
ReturnVar.I := DacData(2*kDacDataWidth - 1 downto kDacDataWidth);
|
||||
ReturnVar.Q := DacData( kDacDataWidth - 1 downto 0);
|
||||
return ReturnVar;
|
||||
end function Unflatten;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
end package body;
|
||||
@@ -0,0 +1,61 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- File: PkgMgPersonality.vhd
|
||||
-- Author: National Instruments
|
||||
-- Original Project: N310
|
||||
-- Date: 13 April 2017
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
-- Copyright 2017 Ettus Research, A National Instruments Company
|
||||
-- SPDX-License-Identifier: LGPL-3.0
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Purpose: This package contains constants and helpful functions that enable
|
||||
-- the FPGA to be compiled with different features.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.PkgRegs.all;
|
||||
|
||||
|
||||
package PkgMgPersonality is
|
||||
|
||||
|
||||
-- RegPort Address Definitions : ------------------------------------------------------
|
||||
--
|
||||
-- DB Regs ...
|
||||
--
|
||||
-- Clocking Offset: 0x 000 Width: 0x 200
|
||||
-- Tdco0 Offset: 0x 200 Width: 0x 200
|
||||
-- Tdco1 Offset: 0x 400 Width: 0x 200
|
||||
-- Daughterboard Ctrl Offset: 0x 600 Width: 0x 200
|
||||
-- Total: 0x2000
|
||||
-- JESD 2x - A Offset: 0x2000 Width: 0x1000
|
||||
-- JESD 2x - B Offset: 0x3000 Width: 0x1000
|
||||
-- Total: 0x4000
|
||||
-- Total: 0x8000 for two DBs
|
||||
-- ------------------------------------------------------------------------------------
|
||||
|
||||
-- A single RegPort runs to the JESD204B Core.
|
||||
constant kJesdRegGroupInDbRegs : RegOffset_t := (kOffset => 16#2000#, -- 0x2000 to
|
||||
kWidth => 16#1000#); -- 0x2FFF
|
||||
|
||||
-- DB Regs : --------------------------------------------------------------------------
|
||||
constant kClockingOffsetInEndpoint : RegOffset_t := (kOffset => 16#0000#, -- 0x0000 to
|
||||
kWidth => 16#0200#); -- 0x01FF
|
||||
constant kTdc0OffsetsInEndpoint : RegOffset_t := (kOffset => 16#0200#, -- 0x0200 to
|
||||
kWidth => 16#0200#); -- 0x03FF
|
||||
constant kTdc1OffsetsInEndpoint : RegOffset_t := (kOffset => 16#0400#, -- 0x0400 to
|
||||
kWidth => 16#0200#); -- 0x05FF
|
||||
constant kDaughterboardOffsetInEndpoint : RegOffset_t := (kOffset => 16#0600#, -- 0x0600 to
|
||||
kWidth => 16#0200#); -- 0x07FF
|
||||
|
||||
|
||||
|
||||
|
||||
end package PkgMgPersonality;
|
||||
@@ -0,0 +1,304 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- File: RadioClocking.vhd
|
||||
-- Author: Daniel Jepson
|
||||
-- Original Project: N310
|
||||
-- Date: 22 February 2016
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
-- Copyright 2016-2018 Ettus Research, A National Instruments Company
|
||||
-- SPDX-License-Identifier: LGPL-3.0
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Purpose:
|
||||
--
|
||||
-- Instantiates a MMCM to produce 1x, 2x, and 3x versions of the Radio Clock
|
||||
-- coming from the FPGA input pin. Handles all the buffering for the input clock.
|
||||
-- Additionally allows the clocks to be turned on and off, and phase shifted.
|
||||
--
|
||||
-- NOTE: This module hard-codes the MMCM settings for a SPECIFIC clock rate!
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
library unisim;
|
||||
use unisim.vcomponents.all;
|
||||
|
||||
|
||||
entity RadioClocking is
|
||||
port (
|
||||
-- Async reset. Can be tied low if desired.
|
||||
aReset : in boolean;
|
||||
-- Sync reset... used in the same places as the async one.
|
||||
bReset : in boolean;
|
||||
|
||||
-- Should be a always-on clock
|
||||
BusClk : in std_logic;
|
||||
|
||||
-- Sync reset to the RadioClkMmcm.
|
||||
bRadioClkMmcmReset : in std_logic;
|
||||
|
||||
-- Locked indication from the RadioClkMmcm in BusClk and aReset domains.
|
||||
bRadioClksValid : out std_logic;
|
||||
|
||||
bRadioClk1xEnabled : in std_logic;
|
||||
bRadioClk2xEnabled : in std_logic;
|
||||
bRadioClk3xEnabled : in std_logic;
|
||||
|
||||
-- Phase shift interface for the RadioClkMmcm. PsClk must be <= 200 MHz.
|
||||
pPsInc : in std_logic;
|
||||
pPsEn : in std_logic;
|
||||
PsClk : in std_logic;
|
||||
pPsDone : out std_logic;
|
||||
|
||||
-- Straight from pins. Buffer included in here.
|
||||
FpgaClk_n : in std_logic;
|
||||
FpgaClk_p : in std_logic;
|
||||
|
||||
RadioClk1x : out std_logic;
|
||||
RadioClk2x : out std_logic;
|
||||
RadioClk3x : out std_logic
|
||||
|
||||
);
|
||||
end RadioClocking;
|
||||
|
||||
|
||||
architecture rtl of RadioClocking is
|
||||
|
||||
--vhook_sigstart
|
||||
signal RadioClk1xLcl: std_logic;
|
||||
signal RadioClk1xPll: std_logic;
|
||||
signal RadioClk2xLcl: std_logic;
|
||||
signal RadioClk2xPll: std_logic;
|
||||
signal RadioClk3xLcl: std_logic;
|
||||
signal RadioClk3xPll: std_logic;
|
||||
--vhook_sigend
|
||||
|
||||
signal RadioClkMmcmFeedbackIn,
|
||||
RadioClkMmcmFeedbackOut,
|
||||
FpgaClkSE,
|
||||
aRadioClkMmcmLocked : std_logic;
|
||||
|
||||
signal bRadioClkMmcmLocked_ms,
|
||||
bRadioClkMmcmLocked,
|
||||
bEnableRadioClkBufgOutputs,
|
||||
bEnableRadioClk1xBufgOutput,
|
||||
bEnableRadioClk2xBufgOutput,
|
||||
bEnableRadioClk3xBufgOutput : std_logic := '0';
|
||||
|
||||
signal aRadioClkMmcmResetInternal : std_logic := '1';
|
||||
|
||||
attribute ASYNC_REG : string;
|
||||
attribute ASYNC_REG of bRadioClkMmcmLocked_ms : signal is "true";
|
||||
attribute ASYNC_REG of bRadioClkMmcmLocked : signal is "true";
|
||||
|
||||
begin
|
||||
|
||||
-- Radio Clock Buffering : ------------------------------------------------------------
|
||||
--
|
||||
-- ------------------------------------------------------------------------------------
|
||||
--vhook_i IBUFDS FpgaClkIbufg hidegeneric=true
|
||||
--vhook_a I FpgaClk_p
|
||||
--vhook_a IB FpgaClk_n
|
||||
--vhook_a O FpgaClkSE
|
||||
FpgaClkIbufg: IBUFDS
|
||||
port map (
|
||||
O => FpgaClkSE, --out std_ulogic
|
||||
I => FpgaClk_p, --in std_ulogic
|
||||
IB => FpgaClk_n); --in std_ulogic
|
||||
|
||||
ResetDelay : process(aReset, BusClk)
|
||||
begin
|
||||
if aReset then
|
||||
aRadioClkMmcmResetInternal <= '1';
|
||||
elsif rising_edge(BusClk) then
|
||||
if bReset then
|
||||
aRadioClkMmcmResetInternal <= '1';
|
||||
else
|
||||
-- Delay by 1 to allow the BUFGs to turn off before the MMCM is reset.
|
||||
aRadioClkMmcmResetInternal <= bRadioClkMmcmReset;
|
||||
end if;
|
||||
end if;
|
||||
end process ResetDelay;
|
||||
|
||||
|
||||
RadioClkMmcm: MMCME2_ADV
|
||||
generic map(
|
||||
COMPENSATION => "ZHOLD",
|
||||
BANDWIDTH => "OPTIMIZED",
|
||||
CLKFBOUT_MULT_F => 6.000, -- Feedback
|
||||
CLKOUT0_DIVIDE_F => 6.000, -- Data Clock 1x, RadioClk1xPll
|
||||
CLKOUT1_DIVIDE => 3, -- Data Clock 2x, RadioClk2xPll
|
||||
CLKOUT2_DIVIDE => 2, -- Data Clock 3x, RadioClk3xPll
|
||||
CLKOUT3_DIVIDE => 1, -- unused
|
||||
CLKOUT4_DIVIDE => 1, -- unused
|
||||
CLKOUT5_DIVIDE => 1, -- unused
|
||||
CLKOUT6_DIVIDE => 1, -- unused
|
||||
CLKFBOUT_PHASE => 0.000, -- Feedback
|
||||
CLKOUT0_PHASE => 0.000, -- Data Clock 1x
|
||||
CLKOUT1_PHASE => 0.000, -- Data Clock 2x
|
||||
CLKOUT2_PHASE => 0.000, -- Data Clock 3x
|
||||
CLKOUT3_PHASE => 0.000, -- unused
|
||||
CLKOUT4_PHASE => 0.000, -- unused
|
||||
CLKOUT5_PHASE => 0.000, -- unused
|
||||
CLKOUT6_PHASE => 0.000, -- unused
|
||||
CLKOUT0_DUTY_CYCLE => 0.500,
|
||||
CLKOUT1_DUTY_CYCLE => 0.500,
|
||||
CLKOUT2_DUTY_CYCLE => 0.500,
|
||||
CLKOUT3_DUTY_CYCLE => 0.500,
|
||||
CLKOUT4_DUTY_CYCLE => 0.500,
|
||||
CLKOUT5_DUTY_CYCLE => 0.500,
|
||||
CLKOUT6_DUTY_CYCLE => 0.500,
|
||||
DIVCLK_DIVIDE => 1,
|
||||
REF_JITTER1 => 0.010,
|
||||
CLKIN1_PERIOD => 6.510, -- 153.6 MHz max
|
||||
CLKFBOUT_USE_FINE_PS => true,
|
||||
CLKOUT0_USE_FINE_PS => false,
|
||||
CLKOUT1_USE_FINE_PS => false,
|
||||
CLKOUT2_USE_FINE_PS => false,
|
||||
CLKOUT3_USE_FINE_PS => false,
|
||||
CLKOUT4_USE_FINE_PS => false,
|
||||
CLKOUT5_USE_FINE_PS => false,
|
||||
CLKOUT6_USE_FINE_PS => false,
|
||||
STARTUP_WAIT => false,
|
||||
CLKOUT4_CASCADE => false)
|
||||
port map (
|
||||
CLKINSEL => '1',
|
||||
CLKIN1 => FpgaClkSE,
|
||||
CLKIN2 => '0',
|
||||
CLKFBIN => RadioClkMmcmFeedbackIn,
|
||||
RST => aRadioClkMmcmResetInternal,
|
||||
PWRDWN => '0',
|
||||
DADDR => (others => '0'),
|
||||
DI => (others => '0'),
|
||||
DWE => '0',
|
||||
DEN => '0',
|
||||
DCLK => '0',
|
||||
DO => open,
|
||||
DRDY => open,
|
||||
PSINCDEC => pPsInc,
|
||||
PSEN => pPsEn,
|
||||
PSCLK => PsClk,
|
||||
PSDONE => pPsDone,
|
||||
CLKOUT0 => RadioClk1xPll,
|
||||
CLKOUT0B => open,
|
||||
CLKOUT1 => RadioClk2xPll,
|
||||
CLKOUT1B => open,
|
||||
CLKOUT2 => RadioClk3xPll,
|
||||
CLKOUT2B => open,
|
||||
CLKOUT3 => open,
|
||||
CLKOUT3B => open,
|
||||
CLKOUT4 => open,
|
||||
CLKOUT5 => open,
|
||||
CLKOUT6 => open,
|
||||
CLKFBOUT => RadioClkMmcmFeedbackOut,
|
||||
CLKFBOUTB => open,
|
||||
LOCKED => aRadioClkMmcmLocked,
|
||||
CLKINSTOPPED => open,
|
||||
CLKFBSTOPPED => open);
|
||||
|
||||
RadioClkMmcmFeedbackBufg: BUFG
|
||||
port map (
|
||||
I => RadioClkMmcmFeedbackOut,
|
||||
O => RadioClkMmcmFeedbackIn
|
||||
);
|
||||
|
||||
|
||||
-- Only enable the WRAPBUFGs when the MMCM is locked. If the MMCM is ever placed in
|
||||
-- reset, we turn off the clocks one cycle before the asynchronous version
|
||||
-- (aRadioClkMmcmResetInternal) reaches the MMCM inputs in order to prevent
|
||||
-- output glitches.
|
||||
CombineEnablesForBuffers : process(aReset, BusClk)
|
||||
begin
|
||||
if aReset then
|
||||
bRadioClkMmcmLocked_ms <= '0';
|
||||
bRadioClkMmcmLocked <= '0';
|
||||
bEnableRadioClk1xBufgOutput <= '0';
|
||||
bEnableRadioClk2xBufgOutput <= '0';
|
||||
bEnableRadioClk3xBufgOutput <= '0';
|
||||
bEnableRadioClkBufgOutputs <= '0';
|
||||
elsif rising_edge(BusClk) then
|
||||
if bReset then
|
||||
bRadioClkMmcmLocked_ms <= '0';
|
||||
bRadioClkMmcmLocked <= '0';
|
||||
bEnableRadioClk1xBufgOutput <= '0';
|
||||
bEnableRadioClk2xBufgOutput <= '0';
|
||||
bEnableRadioClk3xBufgOutput <= '0';
|
||||
bEnableRadioClkBufgOutputs <= '0';
|
||||
else
|
||||
bRadioClkMmcmLocked_ms <= aRadioClkMmcmLocked;
|
||||
bRadioClkMmcmLocked <= bRadioClkMmcmLocked_ms;
|
||||
|
||||
bEnableRadioClkBufgOutputs <= bRadioClkMmcmLocked and
|
||||
not bRadioClkMmcmReset;
|
||||
bEnableRadioClk1xBufgOutput <= bRadioClk1xEnabled and bEnableRadioClkBufgOutputs;
|
||||
bEnableRadioClk2xBufgOutput <= bRadioClk2xEnabled and bEnableRadioClkBufgOutputs;
|
||||
bEnableRadioClk3xBufgOutput <= bRadioClk3xEnabled and bEnableRadioClkBufgOutputs;
|
||||
end if;
|
||||
end if;
|
||||
end process CombineEnablesForBuffers;
|
||||
|
||||
bRadioClksValid <= bEnableRadioClkBufgOutputs;
|
||||
|
||||
--vhook_e WrapBufg RadioClk1xBuf
|
||||
--vhook_a kEnableByDefault false
|
||||
--vhook_a kIgnore false
|
||||
--vhook_a kEnableIsAsync true
|
||||
--vhook_a ClkIn RadioClk1xPll
|
||||
--vhook_a aCe bEnableRadioClk1xBufgOutput
|
||||
--vhook_a ClkOut RadioClk1xLcl
|
||||
RadioClk1xBuf: entity work.WrapBufg (rtl)
|
||||
generic map (
|
||||
kEnableByDefault => false, --boolean:=false
|
||||
kIgnore => false, --boolean:=false
|
||||
kEnableIsAsync => true) --boolean:=false
|
||||
port map (
|
||||
ClkIn => RadioClk1xPll, --in std_logic
|
||||
aCe => bEnableRadioClk1xBufgOutput, --in std_logic
|
||||
ClkOut => RadioClk1xLcl); --out std_logic
|
||||
|
||||
--vhook_e WrapBufg RadioClk2xBuf
|
||||
--vhook_a kEnableByDefault false
|
||||
--vhook_a kIgnore false
|
||||
--vhook_a kEnableIsAsync true
|
||||
--vhook_a ClkIn RadioClk2xPll
|
||||
--vhook_a aCe bEnableRadioClk2xBufgOutput
|
||||
--vhook_a ClkOut RadioClk2xLcl
|
||||
RadioClk2xBuf: entity work.WrapBufg (rtl)
|
||||
generic map (
|
||||
kEnableByDefault => false, --boolean:=false
|
||||
kIgnore => false, --boolean:=false
|
||||
kEnableIsAsync => true) --boolean:=false
|
||||
port map (
|
||||
ClkIn => RadioClk2xPll, --in std_logic
|
||||
aCe => bEnableRadioClk2xBufgOutput, --in std_logic
|
||||
ClkOut => RadioClk2xLcl); --out std_logic
|
||||
|
||||
--vhook_e WrapBufg RadioClk3xBuf
|
||||
--vhook_a kEnableByDefault false
|
||||
--vhook_a kIgnore false
|
||||
--vhook_a kEnableIsAsync true
|
||||
--vhook_a ClkIn RadioClk3xPll
|
||||
--vhook_a aCe bEnableRadioClk3xBufgOutput
|
||||
--vhook_a ClkOut RadioClk3xLcl
|
||||
RadioClk3xBuf: entity work.WrapBufg (rtl)
|
||||
generic map (
|
||||
kEnableByDefault => false, --boolean:=false
|
||||
kIgnore => false, --boolean:=false
|
||||
kEnableIsAsync => true) --boolean:=false
|
||||
port map (
|
||||
ClkIn => RadioClk3xPll, --in std_logic
|
||||
aCe => bEnableRadioClk3xBufgOutput, --in std_logic
|
||||
ClkOut => RadioClk3xLcl); --out std_logic
|
||||
|
||||
|
||||
-- Assign outputs from locals.
|
||||
RadioClk1x <= RadioClk1xLcl;
|
||||
RadioClk2x <= RadioClk2xLcl;
|
||||
RadioClk3x <= RadioClk3xLcl;
|
||||
|
||||
|
||||
|
||||
end rtl;
|
||||
@@ -0,0 +1,347 @@
|
||||
#
|
||||
# Copyright 2017 Ettus Research, A National Instruments Company
|
||||
# SPDX-License-Identifier: LGPL-3.0
|
||||
#
|
||||
# Timing analysis is performed in "/n3xx/dboards/mg/doc/mg_timing.xlsx". See
|
||||
# the spreadsheet for more details and explanations.
|
||||
|
||||
#*******************************************************************************
|
||||
## Daughterboard Clocks
|
||||
|
||||
# 122.88, 125, and 153.6 MHz Sample Clocks are allowable. Constrain the paths to the max
|
||||
# rate in order to support all rates in a single FPGA image.
|
||||
set SAMPLE_CLK_PERIOD 6.510
|
||||
create_clock -name fpga_clk_a -period $SAMPLE_CLK_PERIOD [get_ports DBA_FPGA_CLK_P]
|
||||
create_clock -name fpga_clk_b -period $SAMPLE_CLK_PERIOD [get_ports DBB_FPGA_CLK_P]
|
||||
create_clock -name mgt_clk_dba -period $SAMPLE_CLK_PERIOD [get_ports USRPIO_A_MGTCLK_P]
|
||||
create_clock -name mgt_clk_dbb -period $SAMPLE_CLK_PERIOD [get_ports USRPIO_B_MGTCLK_P]
|
||||
|
||||
# The Radio Clocks coming from the DBs are synchronized together (at the ADCs) to a
|
||||
# typical value of less than 100ps. To give ourselves and Vivado some margin, we claim
|
||||
# here that the DB-B Radio Clock can arrive 500ps before or after the DB-A clock at
|
||||
# the FPGA (note that the trace lengths of the Radio Clocks coming from the DBs to the
|
||||
# FPGA are about 0.5" different, thereby incurring ~80ps of additional skew at the FPGA).
|
||||
# There is one spot in the FPGA where we cross domains between the DB-A and
|
||||
# DB-B clock, so we must ensure that Vivado can analyze that path safely.
|
||||
set FPGA_CLK_EARLY -0.5
|
||||
set FPGA_CLK_LATE 0.5
|
||||
set_clock_latency -source -early $FPGA_CLK_EARLY [get_clocks fpga_clk_b]
|
||||
set_clock_latency -source -late $FPGA_CLK_LATE [get_clocks fpga_clk_b]
|
||||
|
||||
# Virtual clocks for constraining I/O (used below)
|
||||
create_clock -name fpga_clk_a_v -period $SAMPLE_CLK_PERIOD
|
||||
create_clock -name fpga_clk_b_v -period $SAMPLE_CLK_PERIOD
|
||||
|
||||
# The set_clock_latency constraints set on fpga_clk_b are problematic when used with
|
||||
# I/O timing, since the analyzer gives us a double-hit on the latency. One workaround
|
||||
# (used here) is to simply swap the early and late times for the virtual clock so that
|
||||
# it cancels out the source latency during analysis. I tested this by setting the
|
||||
# early and late numbers to zero and then their actual value, running timing reports
|
||||
# on each. The slack report matches for both cases, showing that the reversed early/late
|
||||
# numbers on the virtual clock zero out the latency effects on the actual clock.
|
||||
#
|
||||
# Note this is not a problem for the fpga_clk_a, since no latency is added. So only apply
|
||||
# it to fpga_clk_b_v.
|
||||
set_clock_latency -source -early $FPGA_CLK_LATE [get_clocks fpga_clk_b_v]
|
||||
set_clock_latency -source -late $FPGA_CLK_EARLY [get_clocks fpga_clk_b_v]
|
||||
|
||||
|
||||
|
||||
#*******************************************************************************
|
||||
## Aliases for auto-generated clocks
|
||||
|
||||
create_generated_clock -name radio_clk_fb [get_pins {dba_core/RadioClockingx/RadioClkMmcm/CLKFBOUT}]
|
||||
create_generated_clock -name radio_clk [get_pins {dba_core/RadioClockingx/RadioClkMmcm/CLKOUT0}]
|
||||
create_generated_clock -name radio_clk_2x [get_pins {dba_core/RadioClockingx/RadioClkMmcm/CLKOUT1}]
|
||||
|
||||
create_generated_clock -name radio_clk_b_fb [get_pins {dbb_core/RadioClockingx/RadioClkMmcm/CLKFBOUT}]
|
||||
create_generated_clock -name radio_clk_b [get_pins {dbb_core/RadioClockingx/RadioClkMmcm/CLKOUT0}]
|
||||
create_generated_clock -name radio_clk_b_2x [get_pins {dbb_core/RadioClockingx/RadioClkMmcm/CLKOUT1}]
|
||||
|
||||
|
||||
|
||||
#*******************************************************************************
|
||||
## Generated clocks for output busses to the daughterboard
|
||||
#
|
||||
# These clock definitions need to come above the set_clock_groups commands below to work!
|
||||
|
||||
# Define clocks on the PL SPI clock output pins for both DBs. Actual divider values are
|
||||
# set by SW at run-time. Divider values are 123, 125, or 154 based on what radio clock
|
||||
# rate is set. To be ultra-conservative (which still provides 10s of ns of slack), we
|
||||
# set an over-constrained divider value of 50.
|
||||
set PL_SPI_DIVIDE_VAL 50
|
||||
set PL_SPI_CLK_A [get_ports DBA_CPLD_PL_SPI_SCLK]
|
||||
create_generated_clock -name pl_spi_clk_a \
|
||||
-source [get_pins [all_fanin -flat -only_cells -startpoints_only $PL_SPI_CLK_A]/C] \
|
||||
-divide_by $PL_SPI_DIVIDE_VAL $PL_SPI_CLK_A
|
||||
set PL_SPI_CLK_B [get_ports DBB_CPLD_PL_SPI_SCLK]
|
||||
create_generated_clock -name pl_spi_clk_b \
|
||||
-source [get_pins [all_fanin -flat -only_cells -startpoints_only $PL_SPI_CLK_B]/C] \
|
||||
-divide_by $PL_SPI_DIVIDE_VAL $PL_SPI_CLK_B
|
||||
|
||||
# Define one of the outputs of each bus as a clock (even though it isn't a clock). This
|
||||
# allows us to constrain the overall bus skew with respect to one of the bus outputs.
|
||||
# See the remainder of this constraint below for more details.
|
||||
set DSA_CLK [get_ports {DBA_CH1_RX_DSA_DATA[0]}]
|
||||
create_generated_clock -name dsa_bus_clk \
|
||||
-source [get_pins [all_fanin -flat -only_cells -startpoints_only $DSA_CLK]/C] \
|
||||
-divide_by 2 $DSA_CLK
|
||||
|
||||
set ATR_CLK [get_ports DBA_ATR_RX_1]
|
||||
create_generated_clock -name atr_bus_clk \
|
||||
-source [get_pins [all_fanin -flat -only_cells -startpoints_only $ATR_CLK]/C] \
|
||||
-divide_by 2 $ATR_CLK
|
||||
|
||||
# Interface Unused
|
||||
# set MGPIO_CLK [get_ports DBA_MYK_GPIO_0]
|
||||
# create_generated_clock -name myk_gpio_bus_clk \
|
||||
# -source [get_pins [all_fanin -flat -only_cells -startpoints_only [get_ports $MGPIO_CLK]]/C] \
|
||||
# -divide_by 2 [get_ports $MGPIO_CLK]
|
||||
|
||||
|
||||
|
||||
#*******************************************************************************
|
||||
## Asynchronous clock groups
|
||||
|
||||
# MGT reference clocks are also async to everything.
|
||||
set_clock_groups -asynchronous -group [get_clocks mgt_clk_dba -include_generated_clocks]
|
||||
set_clock_groups -asynchronous -group [get_clocks mgt_clk_dbb -include_generated_clocks]
|
||||
|
||||
# fpga_clk_a and fpga_clk_b are related to one another after synchronization.
|
||||
# However, we do need to declare that these clocks (both a and b) and their children
|
||||
# are async to the remainder of the design. Use the wildcard at the end to grab the
|
||||
# virtual clock as well as the real ones.
|
||||
set_clock_groups -asynchronous -group [get_clocks {fpga_clk_a* fpga_clk_b*} -include_generated_clocks]
|
||||
|
||||
|
||||
|
||||
#*******************************************************************************
|
||||
## PS SPI: since these lines all come from the PS and I don't have access to the
|
||||
# driving clock (or anything for that matter), I'm left with constraining the maximum
|
||||
# and minimum delay on these lines, per a Xilinx AR:
|
||||
# https://www.xilinx.com/support/answers/62122.html
|
||||
set CPLD_SPI_OUTS [get_ports {DB*_CPLD_PS_SPI_SCLK \
|
||||
DB*_CPLD_PS_SPI_SDI \
|
||||
DB*_CPLD_PS_SPI_LE \
|
||||
DB*_CPLD_PS_SPI_ADDR[0] \
|
||||
DB*_CPLD_PS_SPI_ADDR[1]}]
|
||||
|
||||
set_max_delay 12.0 -to $CPLD_SPI_OUTS
|
||||
set_min_delay 3.0 -to $CPLD_SPI_OUTS
|
||||
|
||||
set MYK_SPI_OUTS [get_ports {DB*_MYK_SPI_SCLK \
|
||||
DB*_MYK_SPI_SDIO \
|
||||
DB*_MYK_SPI_CS_n}]
|
||||
|
||||
set_max_delay 14.0 -to $MYK_SPI_OUTS
|
||||
set_min_delay 3.0 -to $MYK_SPI_OUTS
|
||||
|
||||
# report_timing -to $CPLD_SPI_OUTS -max_paths 20 -delay_type min_max -name CpldSpiOutTiming
|
||||
# report_timing -to $MYK_SPI_OUTS -max_paths 20 -delay_type min_max -name MykSpiOutTiming
|
||||
|
||||
set MIN_IN_DELAY 2.0
|
||||
set MAX_IN_DELAY 10.0
|
||||
|
||||
set PS_SPI_INPUTS_0 [get_pins -hierarchical -filter {NAME =~ "*/PS7_i/EMIOSPI0MI"}]
|
||||
set PS_SPI_INPUTS_1 [get_pins -hierarchical -filter {NAME =~ "*/PS7_i/EMIOSPI1MI"}]
|
||||
|
||||
set_max_delay $MAX_IN_DELAY -to $PS_SPI_INPUTS_0
|
||||
set_min_delay $MIN_IN_DELAY -to $PS_SPI_INPUTS_0
|
||||
set_max_delay $MAX_IN_DELAY -to $PS_SPI_INPUTS_1
|
||||
set_min_delay $MIN_IN_DELAY -to $PS_SPI_INPUTS_1
|
||||
|
||||
# report_timing -to $PS_SPI_INPUTS_0 -max_paths 30 -delay_type min_max -nworst 30 -name Spi0InTiming
|
||||
# report_timing -to $PS_SPI_INPUTS_1 -max_paths 30 -delay_type min_max -nworst 30 -name Spi1InTiming
|
||||
|
||||
|
||||
|
||||
#*******************************************************************************
|
||||
## PL SPI to the CPLD
|
||||
#
|
||||
# All of these lines are driven or received from flops in simple_spi_core. The CPLD
|
||||
# calculations assume the FPGA has less than 20 ns of skew between the SCK and
|
||||
# SDI/CS_n. Pretty easy constraint to write! See above for the clock definition.
|
||||
# Do this for DBA and DBB independently.
|
||||
set MAX_SKEW 20.0
|
||||
set SETUP_SKEW [expr {$MAX_SKEW / 2}]
|
||||
set HOLD_SKEW [expr {$MAX_SKEW / 2}]
|
||||
# Do not set the output delay constraint on the clock line!
|
||||
set PORT_LIST_A [get_ports {DBA_CPLD_PL_SPI_LE \
|
||||
DBA_CPLD_PL_SPI_SDI \
|
||||
DBA_CPLD_PL_SPI_ADDR[0] \
|
||||
DBA_CPLD_PL_SPI_ADDR[1]}]
|
||||
set PORT_LIST_B [get_ports {DBB_CPLD_PL_SPI_LE \
|
||||
DBB_CPLD_PL_SPI_SDI \
|
||||
DBB_CPLD_PL_SPI_ADDR[0] \
|
||||
DBB_CPLD_PL_SPI_ADDR[1]}]
|
||||
# Then add the output delay on each of the ports.
|
||||
set_output_delay -clock [get_clocks pl_spi_clk_a] -max -$SETUP_SKEW $PORT_LIST_A
|
||||
set_output_delay -add_delay -clock_fall -clock [get_clocks pl_spi_clk_a] -max -$SETUP_SKEW $PORT_LIST_A
|
||||
set_output_delay -clock [get_clocks pl_spi_clk_a] -min $HOLD_SKEW $PORT_LIST_A
|
||||
set_output_delay -add_delay -clock_fall -clock [get_clocks pl_spi_clk_a] -min $HOLD_SKEW $PORT_LIST_A
|
||||
set_output_delay -clock [get_clocks pl_spi_clk_b] -max -$SETUP_SKEW $PORT_LIST_B
|
||||
set_output_delay -add_delay -clock_fall -clock [get_clocks pl_spi_clk_b] -max -$SETUP_SKEW $PORT_LIST_B
|
||||
set_output_delay -clock [get_clocks pl_spi_clk_b] -min $HOLD_SKEW $PORT_LIST_B
|
||||
set_output_delay -add_delay -clock_fall -clock [get_clocks pl_spi_clk_b] -min $HOLD_SKEW $PORT_LIST_B
|
||||
# Finally, make both the setup and hold checks use the same launching and latching edges.
|
||||
set_multicycle_path -setup -from [get_clocks radio_clk] -to [get_clocks pl_spi_clk_a] -start 0
|
||||
set_multicycle_path -hold -from [get_clocks radio_clk] -to [get_clocks pl_spi_clk_a] -1
|
||||
set_multicycle_path -setup -from [get_clocks radio_clk] -to [get_clocks pl_spi_clk_b] -start 0
|
||||
set_multicycle_path -hold -from [get_clocks radio_clk] -to [get_clocks pl_spi_clk_b] -1
|
||||
|
||||
# For SDO input timing (MISO), we need to look at the CPLD's constraints on turnaround
|
||||
# time plus any board propagation delay.
|
||||
set MISO_INPUT_A [get_ports DBA_CPLD_PL_SPI_SDO]
|
||||
set MISO_INPUT_B [get_ports DBB_CPLD_PL_SPI_SDO]
|
||||
set_input_delay -clock [get_clocks pl_spi_clk_a] -clock_fall -max 68.041 $MISO_INPUT_A
|
||||
set_input_delay -clock [get_clocks pl_spi_clk_a] -clock_fall -min 12.218 $MISO_INPUT_A
|
||||
set_input_delay -clock [get_clocks pl_spi_clk_b] -clock_fall -max 68.041 $MISO_INPUT_B
|
||||
set_input_delay -clock [get_clocks pl_spi_clk_b] -clock_fall -min 12.218 $MISO_INPUT_B
|
||||
# Since the input delay span is clearly more than a period of the radio_clk, we need to
|
||||
# add a multicycle path here as well to define the clock divider ratio. The MISO data
|
||||
# is driven on the falling edge of the SPI clock and captured on the rising edge, so we
|
||||
# only have one half of a SPI clock cycle for our setup. Hold is left alone and is OK
|
||||
# as-is due to the delays in the CPLD and board.
|
||||
set SETUP_CYCLES [expr {$PL_SPI_DIVIDE_VAL / 2}]
|
||||
set HOLD_CYCLES 0
|
||||
set_multicycle_path -setup -from [get_clocks pl_spi_clk_a] -through $MISO_INPUT_A \
|
||||
$SETUP_CYCLES
|
||||
set_multicycle_path -hold -from [get_clocks pl_spi_clk_a] -through $MISO_INPUT_A -end \
|
||||
[expr {$SETUP_CYCLES + $HOLD_CYCLES - 1}]
|
||||
set_multicycle_path -setup -from [get_clocks pl_spi_clk_b] -through $MISO_INPUT_B \
|
||||
$SETUP_CYCLES
|
||||
set_multicycle_path -hold -from [get_clocks pl_spi_clk_b] -through $MISO_INPUT_B -end \
|
||||
[expr {$SETUP_CYCLES + $HOLD_CYCLES - 1}]
|
||||
|
||||
# One of the PL_SPI_ADDR lines is used instead for the LMK SYNC strobe. This line is
|
||||
# driven asynchronously.
|
||||
set_output_delay -clock [get_clocks async_out_clk] 0.000 [get_ports DB*_CPLD_PL_SPI_ADDR[2]]
|
||||
set_max_delay -to [get_ports DB*_CPLD_PL_SPI_ADDR[2]] 50.000
|
||||
set_min_delay -to [get_ports DB*_CPLD_PL_SPI_ADDR[2]] 0.000
|
||||
|
||||
|
||||
|
||||
#*******************************************************************************
|
||||
## DSA Bus
|
||||
# The DSA controls are driven from the DB-A radio clock. Although they are received async
|
||||
# at the DSAs, they should be tightly constrained in the FPGA to arrive as closely as
|
||||
# possible. The best way to do this is a skew constraint across all the bits.
|
||||
set MAX_SKEW 2.5
|
||||
set SETUP_SKEW [expr {($MAX_SKEW / 2)+0.5}]
|
||||
set HOLD_SKEW [expr {($MAX_SKEW / 2)-0.5}]
|
||||
set PORT_LIST [get_ports {DB*_CH*_*X_DSA_DATA[*]}]
|
||||
# Then add the output delay on each of the ports.
|
||||
set_output_delay -clock [get_clocks dsa_bus_clk] -max -$SETUP_SKEW $PORT_LIST
|
||||
set_output_delay -add_delay -clock_fall -clock [get_clocks dsa_bus_clk] -max -$SETUP_SKEW $PORT_LIST
|
||||
set_output_delay -clock [get_clocks dsa_bus_clk] -min $HOLD_SKEW $PORT_LIST
|
||||
set_output_delay -add_delay -clock_fall -clock [get_clocks dsa_bus_clk] -min $HOLD_SKEW $PORT_LIST
|
||||
# Finally, make both the setup and hold checks use the same launching and latching edges.
|
||||
# The clock, which is essentially one of the data lines, should arrive at the pin
|
||||
# +/- MAX_DELAY compared to the other data lines, so setup and hold checks need to be
|
||||
# relative to the SAME edges for both the clock and the data.
|
||||
set_multicycle_path -setup -from [get_clocks radio_clk] -to [get_clocks dsa_bus_clk] -start 0
|
||||
set_multicycle_path -hold -from [get_clocks radio_clk] -to [get_clocks dsa_bus_clk] -1
|
||||
# Remove analysis from the output "clock" pin. There are ways to do this using TCL, but
|
||||
# they aren't supported in XDC files... so we do it the old fashioned way.
|
||||
set_output_delay -clock [get_clocks async_out_clk] 0.000 $DSA_CLK
|
||||
set_max_delay -to $DSA_CLK 50.000
|
||||
set_min_delay -to $DSA_CLK 0.000
|
||||
|
||||
|
||||
|
||||
#*******************************************************************************
|
||||
## ATR Bus
|
||||
# The ATR bits are driven from the DB-A radio clock. Although they are received async in
|
||||
# the CPLD, they should be tightly constrained in the FPGA to avoid any race conditions.
|
||||
# The best way to do this is a skew constraint across all the bits.
|
||||
set MAX_SKEW 2.5
|
||||
set SETUP_SKEW [expr {($MAX_SKEW / 2)+0.5}]
|
||||
set HOLD_SKEW [expr {($MAX_SKEW / 2)-0.5}]
|
||||
set PORT_LIST [get_ports DB*_ATR_*X_*]
|
||||
# Then add the output delay on each of the ports.
|
||||
set_output_delay -clock [get_clocks atr_bus_clk] -max -$SETUP_SKEW $PORT_LIST
|
||||
set_output_delay -add_delay -clock_fall -clock [get_clocks atr_bus_clk] -max -$SETUP_SKEW $PORT_LIST
|
||||
set_output_delay -clock [get_clocks atr_bus_clk] -min $HOLD_SKEW $PORT_LIST
|
||||
set_output_delay -add_delay -clock_fall -clock [get_clocks atr_bus_clk] -min $HOLD_SKEW $PORT_LIST
|
||||
# Finally, make both the setup and hold checks use the same launching and latching edges.
|
||||
set_multicycle_path -setup -to [get_clocks atr_bus_clk] -start 0
|
||||
set_multicycle_path -hold -to [get_clocks atr_bus_clk] -1
|
||||
# Remove analysis from the output "clock" pin. There are ways to do this using TCL, but
|
||||
# they aren't supported in XDC files... so we do it the old fashioned way.
|
||||
set_output_delay -clock [get_clocks async_out_clk] 0.000 $ATR_CLK
|
||||
set_max_delay -to $ATR_CLK 50.000
|
||||
set_min_delay -to $ATR_CLK 0.000
|
||||
|
||||
|
||||
|
||||
#*******************************************************************************
|
||||
## Mykonos Ports
|
||||
# Mykonos GPIO is driven from the DB-A radio clock. Although they are received async in
|
||||
# Mykonos, they should be tightly constrained in the FPGA to avoid any race conditions.
|
||||
# The best way to do this is a skew constraint across all the bits.
|
||||
# set MAX_SKEW 2.5
|
||||
# set SETUP_SKEW [expr {($MAX_SKEW / 2)+0.5}]
|
||||
# set HOLD_SKEW [expr {($MAX_SKEW / 2)-0.5}]
|
||||
# set PORT_LIST [get_ports DB*_ATR_*X_*]
|
||||
# # Then add the output delay on each of the ports.
|
||||
# set_output_delay -clock [get_clocks myk_gpio_bus_clk] -max -$SETUP_SKEW $PORT_LIST
|
||||
# set_output_delay -add_delay -clock_fall -clock [get_clocks myk_gpio_bus_clk] -max -$SETUP_SKEW $PORT_LIST
|
||||
# set_output_delay -clock [get_clocks myk_gpio_bus_clk] -min $HOLD_SKEW $PORT_LIST
|
||||
# set_output_delay -add_delay -clock_fall -clock [get_clocks myk_gpio_bus_clk] -min $HOLD_SKEW $PORT_LIST
|
||||
# # Finally, make both the setup and hold checks use the same launching and latching edges.
|
||||
# set_multicycle_path -setup -to [get_clocks myk_gpio_bus_clk] -start 0
|
||||
# set_multicycle_path -hold -to [get_clocks myk_gpio_bus_clk] -1
|
||||
# # Remove analysis from the output "clock" pin. There are ways to do this using TCL, but
|
||||
# # they aren't supported in XDC files... so we do it the old fashioned way.
|
||||
# set_output_delay -clock [get_clocks async_out_clk] 0.000 $MGPIO_CLK
|
||||
# set_max_delay -to $MGPIO_CLK 50.000
|
||||
# set_min_delay -to $MGPIO_CLK 0.000
|
||||
|
||||
# Mykonos Interrupt is received asynchronously, and driven directly to the PS.
|
||||
set_input_delay -clock [get_clocks async_in_clk] 0.000 [get_ports DB*_MYK_INTRQ]
|
||||
set_max_delay -from [get_ports DB*_MYK_INTRQ] 50.000
|
||||
set_min_delay -from [get_ports DB*_MYK_INTRQ] 0.000
|
||||
|
||||
|
||||
|
||||
#*******************************************************************************
|
||||
## SYSREF/SYNC JESD Timing
|
||||
#
|
||||
# SYNC is async, SYSREF is tightly timed.
|
||||
|
||||
# The SYNC output for both DBs is governed by the JESD cores, which are solely driven by
|
||||
# DB-A clock... but it is an asynchronous signal so we use the async_out_clk.
|
||||
set_output_delay -clock [get_clocks async_out_clk] 0.000 [get_ports DB*_MYK_SYNC_IN_n]
|
||||
set_max_delay -to [get_ports DB*_MYK_SYNC_IN_n] 50.000
|
||||
set_min_delay -to [get_ports DB*_MYK_SYNC_IN_n] 0.000
|
||||
|
||||
# The SYNC input for both DBs is received by the DB-A clock inside the JESD cores... but
|
||||
# again, it is asynchronous and therefore uses the async_in_clk.
|
||||
set_input_delay -clock [get_clocks async_in_clk] 0.000 [get_ports DB*_MYK_SYNC_OUT_n]
|
||||
set_max_delay -from [get_ports DB*_MYK_SYNC_OUT_n] 50.000
|
||||
set_min_delay -from [get_ports DB*_MYK_SYNC_OUT_n] 0.000
|
||||
|
||||
# SYSREF is driven by the LMK directly to the FPGA. Timing analysis was performed once
|
||||
# for the worst-case numbers across both DBs to produce one set of numbers for both DBs.
|
||||
# Since we easily meet setup and hold in Vivado, then this is an acceptable approach.
|
||||
# SYSREF is captured by the local clock from each DB, so we have two sets of constraints.
|
||||
set_input_delay -clock fpga_clk_a_v -min -0.906 [get_ports DBA_FPGA_SYSREF_*]
|
||||
set_input_delay -clock fpga_clk_a_v -max 0.646 [get_ports DBA_FPGA_SYSREF_*]
|
||||
|
||||
set_input_delay -clock fpga_clk_b_v -min -0.906 [get_ports DBB_FPGA_SYSREF_*]
|
||||
set_input_delay -clock fpga_clk_b_v -max 0.646 [get_ports DBB_FPGA_SYSREF_*]
|
||||
|
||||
|
||||
|
||||
#*******************************************************************************
|
||||
## PPS Timing
|
||||
|
||||
# Due to the N3xx synchronization and clocking structure, the PPS output is driven from
|
||||
# the Sample Clock domain instead of the input Reference Clock. Constrain the output as
|
||||
# tightly as possible to accurately mimic the internal Sample Clock timing.
|
||||
set SETUP_SKEW 2.0
|
||||
set HOLD_SKEW -0.5
|
||||
set_output_delay -clock [get_clocks fpga_clk_a_v] -max -$SETUP_SKEW [get_ports REF_1PPS_OUT]
|
||||
set_output_delay -clock [get_clocks fpga_clk_a_v] -min $HOLD_SKEW [get_ports REF_1PPS_OUT]
|
||||
set_multicycle_path -setup -to [get_ports REF_1PPS_OUT] -start 0
|
||||
set_multicycle_path -hold -to [get_ports REF_1PPS_OUT] -1
|
||||
@@ -0,0 +1,2 @@
|
||||
Timing closure of the CPLD design relies on the pre-set seed value. The build
|
||||
requires Quartus 16.1.2.
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,32 @@
|
||||
#
|
||||
# Copyright 2018 Ettus Research, a National Instruments Company
|
||||
#
|
||||
|
||||
##################################################
|
||||
# DB IFC Sources
|
||||
##################################################
|
||||
RHODIUM_DB_SRCS = $(abspath $(addprefix $(BASE_DIR)/n3xx/dboards/rh/db_ifc/, \
|
||||
DbCore.vhd \
|
||||
DaughterboardRegs.vhd \
|
||||
ClockingRegs.vhd \
|
||||
PkgRhPersonality.vhd \
|
||||
PkgDaughterboardRegMap.vhd \
|
||||
PkgClockingRegMap.vhd \
|
||||
PkgJesdConfig.vhd \
|
||||
PkgAdcDacInterfaceTypes.vhd \
|
||||
RadioClocking.vhd \
|
||||
Jesd204bXcvrCore.edf \
|
||||
))
|
||||
|
||||
RHODIUM_TOP_SRCS = $(abspath $(addprefix $(BASE_DIR)/n3xx/dboards/rh/, \
|
||||
n3xx.v \
|
||||
))
|
||||
|
||||
RHODIUM_DB_CLOCKS_XDC = $(abspath $(addprefix $(BASE_DIR)/n3xx/dboards/rh/, \
|
||||
db_clocks.xdc \
|
||||
))
|
||||
|
||||
RHODIUM_DB_XDC = $(abspath $(addprefix $(BASE_DIR)/n3xx/dboards/rh/, \
|
||||
db_pins.xdc \
|
||||
db_timing.xdc \
|
||||
))
|
||||
@@ -0,0 +1,27 @@
|
||||
#
|
||||
# Copyright 2018 Ettus Research, a National Instruments Company
|
||||
#
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
SRCS=rhodium_top.qpf rhodium_top.qsf rhodium_top.sdc rhodium_top.v rhodium_gain_ctrl.v rhodium_gain_table.v rhodium_lo_gain.v
|
||||
SIM_SRCS=rh_tb.v rhodium_top.v rhodium_gain_ctrl.v rhodium_gain_table.v rhodium_lo_gain.v
|
||||
SHORT_HASH=$(addprefix GIT_HASH=,$(shell ../../../../../tools/scripts/git-hash.sh))
|
||||
|
||||
all: cpld-rhodium-revb.svf
|
||||
|
||||
output_files/rhodium_top.pof: $(SRCS)
|
||||
quartus_map rhodium_top --verilog_macro="$(SHORT_HASH)"
|
||||
quartus_fit rhodium_top
|
||||
quartus_asm rhodium_top
|
||||
quartus_sta rhodium_top
|
||||
|
||||
cpld-rhodium-revb.svf: output_files/rhodium_top.pof
|
||||
quartus_cpf --convert --frequency 10.0MHz --voltage 2.5 --operation p $? $@
|
||||
|
||||
clean:
|
||||
rm -rf db incremental_db output_files simulation cpld-rhodium-revb.svf
|
||||
|
||||
a.out: $(SIM_SRCS)
|
||||
iverilog -tvvp -D$(SHORT_HASH) -s rh_tb $(SIM_SRCS)
|
||||
|
||||
@@ -0,0 +1,410 @@
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2018 Ettus Research, A National Instruments Company
|
||||
//
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
//
|
||||
// Module: rh_tb
|
||||
// Simple testbench for rhodium_top
|
||||
// This creates a rudimentary stimulus only, to allow results to be viewed
|
||||
// in the waveform viewer
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
`timescale 1ns/1ps
|
||||
|
||||
|
||||
module rh_tb;
|
||||
|
||||
reg ADC_A_Over_Range_18, ADC_B_Over_Range_18;
|
||||
|
||||
wire [13:0] usrpio_io; // TODO: use one of these as pl_spi_addr[3]
|
||||
|
||||
wire CPLD_PS_SPI_LE_25, CPLD_PS_SPI_CLK_25,
|
||||
CPLD_PS_ADDR0_25, CPLD_PS_ADDR1_25, CPLD_PS_SPI_SDI_25;
|
||||
wire CPLD_PS_SPI_SDO_25;
|
||||
|
||||
wire CPLD_PL_SPI_SDO_18;
|
||||
wire CPLD_PL_SPI_LE_18, CPLD_PL_SPI_SCLK_18,
|
||||
CPLD_PL_SPI_SDI_18,
|
||||
CPLD_PL_SPI_ADDR0_18, CPLD_PL_SPI_ADDR1_18,
|
||||
CPLD_PL_SPI_ADDR2_18,
|
||||
CPLD_ATR_TX_18, CPLD_ATR_RX_18;
|
||||
// NOTE: TxRx front-end switches are driven direct from the motherboard, so these ATR
|
||||
// lines have no function at this time.
|
||||
|
||||
wire ADC_SPI_CS_L_18, ADC_SPI_SCLK_18;
|
||||
wire ADC_SPI_SDIO_18;
|
||||
|
||||
wire DAC_SPI_CS_L_18, DAC_SPI_SCLK_18;
|
||||
wire DAC_SPI_SDIO_18;
|
||||
reg DAC_Alarm_18; // TODO: drive to gpio?
|
||||
|
||||
wire PHDAC_SPI_CS_L, PHDAC_SPI_SCLK, PHDAC_SPI_SDI;
|
||||
|
||||
|
||||
reg LO_SYNC;
|
||||
|
||||
wire CLKDIST_SPI_CS_L,
|
||||
CLKDIST_SPI_SCLK;
|
||||
wire CLKDIST_SPI_SDIO;
|
||||
|
||||
wire Tx_DSA_C1,
|
||||
Tx_DSA_C2,
|
||||
Tx_DSA_C4,
|
||||
Tx_DSA_C8,
|
||||
Tx_DSA_C16;
|
||||
wire Tx_DSA1_LE,
|
||||
Tx_DSA2_LE;
|
||||
wire Tx_Sw1_Ctrl_1,
|
||||
Tx_Sw1_Ctrl_2,
|
||||
Tx_Sw2_Ctrl_1,
|
||||
Tx_Sw2_Ctrl_2,
|
||||
Tx_Sw3_Ctrl_1,
|
||||
Tx_Sw3_Ctrl_2,
|
||||
Tx_Sw3_Ctrl_3,
|
||||
Tx_Sw3_Ctrl_4,
|
||||
Rx_LO_Input_Select,
|
||||
Rx_LO_Filter_Sw_1,
|
||||
Rx_LO_Filter_Sw_2,
|
||||
Tx_LO_Input_Select,
|
||||
Tx_LO_Filter_Sw_1,
|
||||
Tx_LO_Filter_Sw_2;
|
||||
wire CLKDIST_Status_LD1,
|
||||
CLKDIST_Status_LD2;
|
||||
wire LOSYNTH_RX_MUXOUT,
|
||||
LOSYNTH_TX_MUXOUT;
|
||||
|
||||
wire LO_SPI_SCLK,
|
||||
LO_SPI_SDI,
|
||||
LO_TX_CS_L,
|
||||
LO_RX_CS_L,
|
||||
Rx_Sw1_Ctrl_1,
|
||||
Rx_Sw1_Ctrl_2,
|
||||
Rx_DSA_C1,
|
||||
Rx_DSA_C2,
|
||||
Rx_DSA_C4,
|
||||
Rx_DSA_C8,
|
||||
Rx_DSA_C16;
|
||||
wire Rx_DSA1_LE,
|
||||
Rx_DSA2_LE;
|
||||
wire Rx_Sw2_Ctrl,
|
||||
Rx_Sw3_Ctrl_1,
|
||||
Rx_Sw3_Ctrl_2,
|
||||
Rx_Sw4_Ctrl_1,
|
||||
Rx_Sw4_Ctrl_2,
|
||||
Rx_Sw4_Ctrl_3,
|
||||
Rx_Sw4_Ctrl_4,
|
||||
Rx_Demod_ADJ_1,
|
||||
Rx_Demod_ADJ_2;
|
||||
wire LO_DSA_C1,
|
||||
LO_DSA_C2,
|
||||
LO_DSA_C4,
|
||||
LO_DSA_C8,
|
||||
LO_DSA_C16;
|
||||
wire RxLO_DSA_LE,
|
||||
TxLO_DSA_LE;
|
||||
wire LODIST_Bd_SPI_CS_L,
|
||||
LODIST_Bd_SPI_SDI,
|
||||
LODIST_Bd_SPI_SCLK,
|
||||
Tx_Sw5_Ctrl_1,
|
||||
Tx_Sw5_Ctrl_2,
|
||||
Rx_Sw6_Ctrl_1,
|
||||
Rx_Sw6_Ctrl_2;
|
||||
wire LODIST_Bd_IO1;
|
||||
wire Tx_HB_LB_Select,
|
||||
Rx_HB_LB_Select,
|
||||
Cal_iso_Sw_Ctrl;
|
||||
|
||||
|
||||
parameter dly = 20;
|
||||
|
||||
integer scnt;
|
||||
integer acnt;
|
||||
integer ccnt;
|
||||
integer ccnt_max;
|
||||
|
||||
reg ps_sck;
|
||||
reg ps_mosi;
|
||||
reg clkdis_cs_b;
|
||||
reg cpld_ps_cs_b;
|
||||
reg phdac_cs_b;
|
||||
reg adc_cs_b;
|
||||
reg dac_cs_b;
|
||||
|
||||
reg pl_sck;
|
||||
reg pl_mosi;
|
||||
reg txlo_cs_b;
|
||||
reg rxlo_cs_b;
|
||||
reg lodis_cs_b;
|
||||
reg cpld_pl_cs_b;
|
||||
|
||||
task ps_cpld_xfer;
|
||||
input [1:0] tbl;
|
||||
input [5:0] cmd;
|
||||
input [15:0] data;
|
||||
reg [23:0] shiftreg;
|
||||
integer i;
|
||||
begin
|
||||
ps_sck <= 1'b0;
|
||||
clkdis_cs_b <= 1'b1;
|
||||
cpld_ps_cs_b <= 1'b1;
|
||||
phdac_cs_b <= 1'b1;
|
||||
adc_cs_b <= 1'b1;
|
||||
dac_cs_b <= 1'b1;
|
||||
txlo_cs_b <= 1'b1;
|
||||
rxlo_cs_b <= 1'b1;
|
||||
lodis_cs_b <= 1'b1;
|
||||
cpld_pl_cs_b <= 1'b1;
|
||||
shiftreg <= {tbl,cmd,data};
|
||||
#(dly);
|
||||
cpld_ps_cs_b <= 1'b0;
|
||||
#(dly);
|
||||
for (i = 0; i < 24; i = i + 1) begin
|
||||
ps_sck <= 1'b0;
|
||||
ps_mosi <= shiftreg[23-i];
|
||||
#(dly);
|
||||
ps_sck <= 1'b1;
|
||||
#(dly);
|
||||
end
|
||||
ps_sck <= 1'b0;
|
||||
#(dly);
|
||||
cpld_ps_cs_b <= 1'b1;
|
||||
#(dly);
|
||||
end
|
||||
endtask
|
||||
|
||||
task pl_cpld_xfer;
|
||||
input [1:0] tbl;
|
||||
input [5:0] cmd;
|
||||
input [15:0] data;
|
||||
reg [23:0] shiftreg;
|
||||
integer i;
|
||||
begin
|
||||
pl_sck <= 1'b0;
|
||||
clkdis_cs_b <= 1'b1;
|
||||
cpld_ps_cs_b <= 1'b1;
|
||||
phdac_cs_b <= 1'b1;
|
||||
adc_cs_b <= 1'b1;
|
||||
dac_cs_b <= 1'b1;
|
||||
txlo_cs_b <= 1'b1;
|
||||
rxlo_cs_b <= 1'b1;
|
||||
lodis_cs_b <= 1'b1;
|
||||
cpld_pl_cs_b <= 1'b1;
|
||||
shiftreg <= {tbl,cmd,data};
|
||||
#(dly);
|
||||
cpld_pl_cs_b <= 1'b0;
|
||||
#(dly);
|
||||
for (i = 0; i < 24; i = i + 1) begin
|
||||
pl_sck <= 1'b0;
|
||||
pl_mosi <= shiftreg[23-i];
|
||||
#(dly);
|
||||
pl_sck <= 1'b1;
|
||||
#(dly);
|
||||
end
|
||||
pl_sck <= 1'b0;
|
||||
#(dly);
|
||||
cpld_pl_cs_b <= 1'b1;
|
||||
#(dly);
|
||||
end
|
||||
endtask
|
||||
|
||||
assign CPLD_PS_SPI_LE_25 = clkdis_cs_b;
|
||||
assign CPLD_PS_ADDR0_25 = cpld_ps_cs_b;
|
||||
assign CPLD_PS_ADDR1_25 = phdac_cs_b;
|
||||
assign usrpio_io[12] = adc_cs_b;
|
||||
assign usrpio_io[13] = dac_cs_b;
|
||||
assign CPLD_PS_SPI_CLK_25 = ps_sck;
|
||||
assign CPLD_PS_SPI_SDI_25 = ps_mosi;
|
||||
|
||||
assign CPLD_PL_SPI_LE_18 = txlo_cs_b;
|
||||
assign CPLD_PL_SPI_ADDR1_18 = rxlo_cs_b;
|
||||
assign CPLD_PL_SPI_ADDR2_18 = lodis_cs_b;
|
||||
assign CPLD_PL_SPI_ADDR0_18 = cpld_pl_cs_b;
|
||||
assign CPLD_PL_SPI_SCLK_18 = pl_sck;
|
||||
assign CPLD_PL_SPI_SDI_18 = pl_mosi;
|
||||
|
||||
assign CLKDIST_Status_LD1 = 1'b0;
|
||||
assign LOSYNTH_RX_MUXOUT = 1'b1;
|
||||
assign LOSYNTH_TX_MUXOUT = 1'b1;
|
||||
|
||||
initial
|
||||
begin
|
||||
$dumpfile("rh_cpld.vcd");
|
||||
$dumpvars;
|
||||
// Check Signature register read-back
|
||||
#(dly) ps_cpld_xfer(2'b00, {5'b00000, 1'b1}, 16'h0000);
|
||||
// Check Signature register is read-only
|
||||
#(dly) ps_cpld_xfer(2'b00, {5'b00000, 1'b0}, 16'h1234);
|
||||
#(dly) ps_cpld_xfer(2'b00, {5'b00000, 1'b1}, 16'h0000);
|
||||
|
||||
// Load portions of lower RX gain table with some values
|
||||
#(dly) ps_cpld_xfer(2'b00, {5'b00110, 1'b0}, 16'h0000); /* Write GAIN_BAND_SEL for lower table */
|
||||
#(dly) ps_cpld_xfer(2'b01, 6'd0, {2'd0, 5'd0, 5'd1, 1'b1, 3'd0});
|
||||
#(dly) ps_cpld_xfer(2'b01, 6'd1, {2'd0, 5'd0, 5'd2, 1'b1, 3'd0});
|
||||
#(dly) ps_cpld_xfer(2'b01, 6'd2, {2'd0, 5'd1, 5'd2, 1'b1, 3'd0});
|
||||
#(dly) ps_cpld_xfer(2'b01, 6'd3, {2'd0, 5'd1, 5'd3, 1'b1, 3'd0});
|
||||
|
||||
// Load portions of upper RX gain table with some values
|
||||
#(dly) ps_cpld_xfer(2'b00, {5'b00110, 1'b0}, 16'h0101); /* Write GAIN_BAND_SEL for upper table */
|
||||
#(dly) ps_cpld_xfer(2'b01, 6'd4, {2'd0, 5'd2, 5'd3, 1'b1, 3'd0});
|
||||
#(dly) ps_cpld_xfer(2'b01, 6'd5, {2'd0, 5'd2, 5'd4, 1'b1, 3'd0});
|
||||
#(dly) ps_cpld_xfer(2'b01, 6'd6, {2'd0, 5'd3, 5'd4, 1'b1, 3'd0});
|
||||
#(dly) ps_cpld_xfer(2'b01, 6'd7, {2'd0, 5'd3, 5'd5, 1'b1, 3'd0});
|
||||
|
||||
// Check RX gain table readback
|
||||
#(dly) ps_cpld_xfer(2'b01, 6'd0, 16'h0);
|
||||
#(dly) ps_cpld_xfer(2'b01, 6'd1, 16'h0);
|
||||
#(dly) ps_cpld_xfer(2'b01, 6'd2, 16'h0);
|
||||
#(dly) ps_cpld_xfer(2'b01, 6'd3, 16'h0);
|
||||
#(dly) ps_cpld_xfer(2'b01, 6'd4, 16'h0);
|
||||
#(dly) ps_cpld_xfer(2'b01, 6'd5, 16'h0);
|
||||
#(dly) ps_cpld_xfer(2'b01, 6'd6, 16'h0);
|
||||
|
||||
// Check can write a couple registers on PL side
|
||||
// (Also make sure we're looking at the lower gain tables)
|
||||
#(dly) pl_cpld_xfer(2'b00, {5'd6, 1'b0}, 16'h0000);
|
||||
#(dly) pl_cpld_xfer(2'b00, {5'd7, 1'b0}, 16'h0000);
|
||||
|
||||
// Check retrieval of gain values for RX table and program DSAs
|
||||
#(dly) pl_cpld_xfer(2'b01, 6'd2, {2'b0, 1'b1, 6'b0, 1'b1, 6'b0});
|
||||
#(dly) pl_cpld_xfer(2'b01, 6'd3, {2'b0, 1'b0, 6'b0, 1'b1, 6'b0});
|
||||
#(dly) pl_cpld_xfer(2'b01, 6'd1, {2'b0, 1'b1, 6'b0, 1'b0, 6'b0});
|
||||
|
||||
// Check writes to RXBS and TXBS registers
|
||||
#(dly) pl_cpld_xfer(2'b00, {5'd6, 1'b0}, 16'h1ABC);
|
||||
#(dly) pl_cpld_xfer(2'b00, {5'd7, 1'b0}, 16'h1CAB);
|
||||
|
||||
// Check TX DSA programming is independent of RX DSA programming
|
||||
#(dly) pl_cpld_xfer(2'b10, 6'd4, {2'b0, 1'b1, 6'b0, 1'b0, 6'b0});
|
||||
|
||||
// Check LO gain programming works
|
||||
#(dly) pl_cpld_xfer(2'b11, 6'd5, {2'b0, 1'b1, 6'b0, 1'b0, 6'b0});
|
||||
#(dly) pl_cpld_xfer(2'b11, 6'd7, {2'b0, 1'b0, 6'b0, 1'b1, 6'b0});
|
||||
#(dly) pl_cpld_xfer(2'b11, 6'd0, {2'b0, 1'b0, 6'b0, 1'b0, 6'b0});
|
||||
|
||||
// More checks for PL register writes
|
||||
#(dly) pl_cpld_xfer(2'b00, {5'd6, 1'b0}, 16'h0ABC);
|
||||
#(dly) pl_cpld_xfer(2'b00, {5'd7, 1'b0}, 16'h0CAB);
|
||||
#(dly) pl_cpld_xfer(2'b00, {5'd8, 1'b0}, 16'hAA5C);
|
||||
#(dly) pl_cpld_xfer(2'b00, {5'd8, 1'b0}, 16'h5A5C);
|
||||
#(dly) pl_cpld_xfer(2'b00, {5'd6, 1'b0}, 16'h1C42);
|
||||
|
||||
// Check low/high gain tables and independence of RX vs. TX
|
||||
#(dly) pl_cpld_xfer(2'b01, 6'd0, 16'h2040);
|
||||
#(dly) pl_cpld_xfer(2'b00, {5'd7, 1'b0}, 16'h104C);
|
||||
#(dly) pl_cpld_xfer(2'b10, 6'd0, 16'h2040);
|
||||
#(dly) pl_cpld_xfer(2'b00, {5'd7, 1'b0}, 16'h0C80);
|
||||
#(dly) pl_cpld_xfer(2'b10, 6'd5, 16'h2040);
|
||||
$finish;
|
||||
end
|
||||
|
||||
rhodium_top toplevel_inst(usrpio_io, // bank 1A, 1B and 6
|
||||
ADC_A_Over_Range_18, ADC_B_Over_Range_18, // bank 1A
|
||||
|
||||
// bank 6
|
||||
CPLD_PS_SPI_LE_25,
|
||||
CPLD_PS_SPI_CLK_25,
|
||||
CPLD_PS_ADDR0_25,
|
||||
CPLD_PS_ADDR1_25,
|
||||
CPLD_PS_SPI_SDI_25,
|
||||
CPLD_PS_SPI_SDO_25,
|
||||
PHDAC_SPI_CS_L, PHDAC_SPI_SCLK, PHDAC_SPI_SDI,
|
||||
LO_SYNC,
|
||||
|
||||
// bank 2
|
||||
CPLD_PL_SPI_SDO_18,
|
||||
CPLD_PL_SPI_LE_18,
|
||||
CPLD_PL_SPI_SCLK_18,
|
||||
CPLD_PL_SPI_SDI_18,
|
||||
CPLD_PL_SPI_ADDR0_18,
|
||||
CPLD_PL_SPI_ADDR1_18,
|
||||
CPLD_PL_SPI_ADDR2_18,
|
||||
CPLD_ATR_TX_18,
|
||||
CPLD_ATR_RX_18,
|
||||
ADC_SPI_CS_L_18,
|
||||
ADC_SPI_SCLK_18,
|
||||
ADC_SPI_SDIO_18,
|
||||
DAC_SPI_CS_L_18,
|
||||
DAC_SPI_SCLK_18,
|
||||
DAC_SPI_SDIO_18,
|
||||
DAC_Alarm_18,
|
||||
|
||||
// bank 3
|
||||
|
||||
CLKDIST_SPI_CS_L,
|
||||
CLKDIST_SPI_SCLK,
|
||||
CLKDIST_SPI_SDIO,
|
||||
Tx_DSA_C1,
|
||||
Tx_DSA_C2,
|
||||
Tx_DSA_C4,
|
||||
Tx_DSA_C8,
|
||||
Tx_DSA_C16,
|
||||
Tx_DSA1_LE,
|
||||
Tx_DSA2_LE,
|
||||
Tx_Sw1_Ctrl_1,
|
||||
Tx_Sw1_Ctrl_2,
|
||||
Tx_Sw2_Ctrl_1,
|
||||
Tx_Sw2_Ctrl_2,
|
||||
Tx_Sw3_Ctrl_1,
|
||||
Tx_Sw3_Ctrl_2,
|
||||
Tx_Sw3_Ctrl_3,
|
||||
Tx_Sw3_Ctrl_4,
|
||||
Rx_LO_Input_Select,
|
||||
Rx_LO_Filter_Sw_1,
|
||||
Rx_LO_Filter_Sw_2,
|
||||
Tx_LO_Input_Select,
|
||||
Tx_LO_Filter_Sw_1,
|
||||
Tx_LO_Filter_Sw_2,
|
||||
CLKDIST_Status_LD1,
|
||||
CLKDIST_Status_LD2,
|
||||
LOSYNTH_RX_MUXOUT,
|
||||
LOSYNTH_TX_MUXOUT,
|
||||
|
||||
// bank 8
|
||||
LO_SPI_SCLK, // fans out to both rx & tx synths
|
||||
LO_SPI_SDI,
|
||||
LO_TX_CS_L,
|
||||
LO_RX_CS_L,
|
||||
Rx_Sw1_Ctrl_1,
|
||||
Rx_Sw1_Ctrl_2,
|
||||
Rx_DSA_C1,
|
||||
Rx_DSA_C2,
|
||||
Rx_DSA_C4,
|
||||
Rx_DSA_C8,
|
||||
Rx_DSA_C16,
|
||||
Rx_DSA1_LE,
|
||||
Rx_DSA2_LE,
|
||||
Rx_Sw2_Ctrl,
|
||||
Rx_Sw3_Ctrl_1,
|
||||
Rx_Sw3_Ctrl_2,
|
||||
Rx_Sw4_Ctrl_1,
|
||||
Rx_Sw4_Ctrl_2,
|
||||
Rx_Sw4_Ctrl_3,
|
||||
Rx_Sw4_Ctrl_4,
|
||||
Rx_Demod_ADJ_1,
|
||||
Rx_Demod_ADJ_2,
|
||||
|
||||
// bank 5
|
||||
LO_DSA_C1,
|
||||
LO_DSA_C2,
|
||||
LO_DSA_C4,
|
||||
LO_DSA_C8,
|
||||
LO_DSA_C16,
|
||||
RxLO_DSA_LE,
|
||||
TxLO_DSA_LE,
|
||||
LODIST_Bd_SPI_CS_L,
|
||||
LODIST_Bd_SPI_SDI,
|
||||
LODIST_Bd_SPI_SCLK,
|
||||
LODIST_Bd_IO1,
|
||||
Tx_Sw5_Ctrl_1,
|
||||
Tx_Sw5_Ctrl_2,
|
||||
Rx_Sw6_Ctrl_1,
|
||||
Rx_Sw6_Ctrl_2,
|
||||
|
||||
Tx_HB_LB_Select,
|
||||
Rx_HB_LB_Select,
|
||||
Cal_iso_Sw_Ctrl
|
||||
|
||||
|
||||
);
|
||||
endmodule // rh_tb
|
||||
@@ -0,0 +1,203 @@
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2018 Ettus Research, A National Instruments Company
|
||||
//
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
//
|
||||
// Module: rhodium_gain_ctrl
|
||||
// Description:
|
||||
// Gain controller for Rhodium
|
||||
// Provides 2 SPI slaves:
|
||||
// The "load" slave is used to load the gain table with DSA settings for
|
||||
// each index.
|
||||
// The "ctrl" slave takes in a gain index and drives the DSAs with the
|
||||
// setting found in the gain table.
|
||||
// The SPI formats are provided below.
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
`default_nettype none
|
||||
|
||||
/**
|
||||
* SPI DATA FORMAT
|
||||
* LOADER
|
||||
* M {table_sel[1:0], gain_index[5:0], rsvd[1:0], dsa1[4:0], dsa2[4:0], wr_en, rsvd[2:0]}
|
||||
* S {-------------------------------, rsvd[1:0], dsa1[4:0], dsa2[4:0], -------rsvd[3:0]}
|
||||
* CTRL
|
||||
* M {table_sel[1:0], gain_index[5:0], rsvd[1:0], wr_dsa1, -rsvd[5:0], wr_dsa2, rsvd[5:0]}
|
||||
* S {-------------------------------, ---------rsvd[2:0], gain1[5:0], ---rsvd, gain2[5:0]}
|
||||
*/
|
||||
module rhodium_gain_ctrl
|
||||
#(
|
||||
parameter TABLE_NUM = 2'b01
|
||||
) (
|
||||
input wire load_table_sel,
|
||||
input wire load_sck,
|
||||
input wire load_csb,
|
||||
input wire load_mosi,
|
||||
output wire load_miso,
|
||||
input wire ctrl_table_sel,
|
||||
input wire ctrl_sck,
|
||||
input wire ctrl_csb,
|
||||
input wire ctrl_mosi,
|
||||
output reg ctrl_miso,
|
||||
output wire [4:0] dsa,
|
||||
output reg dsa1_le,
|
||||
output reg dsa2_le
|
||||
);
|
||||
|
||||
localparam CNT_GAIN1_DRIVE = 10,
|
||||
CNT_DSA1_LE_RISE = 11,
|
||||
CNT_DSA1_LE_FALL = 14,
|
||||
CNT_GAIN1_RELEASE = 17;
|
||||
localparam CNT_GAIN2_DRIVE = 17,
|
||||
CNT_DSA2_LE_RISE = 18,
|
||||
CNT_DSA2_LE_FALL = 21,
|
||||
CNT_GAIN2_RELEASE = 24;
|
||||
|
||||
/******************
|
||||
* Gain table loader
|
||||
*******************/
|
||||
reg [4:0] load_bit_cnt;
|
||||
reg [1:0] load_tbl;
|
||||
reg [5:0] load_index;
|
||||
reg [15:0] load_rd_data;
|
||||
reg [4:0] load_dsa1;
|
||||
reg [4:0] load_dsa2;
|
||||
wire [4:0] load_dsa1_prev;
|
||||
wire [4:0] load_dsa2_prev;
|
||||
|
||||
assign load_miso = load_rd_data[15]; // Shift out on neg edge
|
||||
|
||||
wire wr_en;
|
||||
assign wr_en = (!load_csb) && (load_tbl == TABLE_NUM) && (load_bit_cnt == 20) && (load_mosi);
|
||||
|
||||
// Cycle counter for where we are in protocol and shift register for input
|
||||
always @ (posedge load_sck or posedge load_csb)
|
||||
begin
|
||||
if (load_csb) begin
|
||||
load_bit_cnt <= 5'd0;
|
||||
end else if (!load_csb) begin
|
||||
{load_dsa1, load_dsa2} <= {load_dsa1[3:0], load_dsa2, load_mosi};
|
||||
|
||||
if (load_bit_cnt < 23) begin
|
||||
load_bit_cnt <= load_bit_cnt + 5'd1;
|
||||
end
|
||||
if (load_bit_cnt < 8) begin
|
||||
{load_tbl, load_index} <= {load_tbl[0], load_index, load_mosi};
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Readback shift register
|
||||
always @ (negedge load_sck)
|
||||
begin
|
||||
if (load_bit_cnt == 9) begin
|
||||
load_rd_data <= {load_dsa1_prev, load_dsa2_prev, 5'b000};
|
||||
end else begin
|
||||
load_rd_data <= {load_rd_data[14:0], 1'b0};
|
||||
end
|
||||
end
|
||||
|
||||
/******************
|
||||
* Gain table RAM
|
||||
*******************/
|
||||
wire [4:0] ctrl_dsa1;
|
||||
wire [4:0] ctrl_dsa2;
|
||||
|
||||
/* Use half of table for low band, other half for high band
|
||||
* Software decides address mapping
|
||||
*/
|
||||
rhodium_gain_table gain_table(
|
||||
.wr_clk(load_sck),
|
||||
.wr_en(wr_en),
|
||||
.wr_addr({load_table_sel, load_index}),
|
||||
.wr_data({load_dsa1, load_dsa2}),
|
||||
.wr_data_prev({load_dsa1_prev, load_dsa2_prev}),
|
||||
.rd_clk(ctrl_sck),
|
||||
.rd_addr({ctrl_table_sel, ctrl_index}),
|
||||
.rd_data({ctrl_dsa1, ctrl_dsa2})
|
||||
);
|
||||
|
||||
/******************
|
||||
* Gain control
|
||||
*******************/
|
||||
reg [4:0] ctrl_bit_cnt;
|
||||
reg [1:0] ctrl_tbl;
|
||||
reg [5:0] ctrl_index;
|
||||
|
||||
reg [5:0] gain1;
|
||||
reg [5:0] gain2;
|
||||
reg gain1_t;
|
||||
reg gain2_t;
|
||||
|
||||
assign dsa = !gain1_t ? ctrl_dsa1 :
|
||||
(!gain2_t ? ctrl_dsa2 :
|
||||
5'b11111);
|
||||
|
||||
// Cycle counter for where we are in protocol and shift register for input
|
||||
// Also controls timing of DSAs' latch enable signals
|
||||
always @ (posedge ctrl_sck or posedge ctrl_csb)
|
||||
begin
|
||||
if (ctrl_csb) begin
|
||||
ctrl_bit_cnt <= 5'd0;
|
||||
dsa1_le <= 1'b0;
|
||||
dsa2_le <= 1'b0;
|
||||
gain1_t <= 1'b1;
|
||||
gain2_t <= 1'b1;
|
||||
end else if (!ctrl_csb) begin
|
||||
if (ctrl_bit_cnt < 23) begin
|
||||
ctrl_bit_cnt <= ctrl_bit_cnt + 5'd1;
|
||||
end
|
||||
|
||||
if (ctrl_bit_cnt < 8) begin
|
||||
{ctrl_tbl, ctrl_index} <= {ctrl_tbl[0], ctrl_index, ctrl_mosi};
|
||||
end
|
||||
|
||||
if (ctrl_tbl == TABLE_NUM) begin
|
||||
if ((ctrl_bit_cnt == CNT_GAIN1_DRIVE) && (ctrl_mosi)) begin
|
||||
gain1 <= ctrl_index;
|
||||
gain1_t <= 1'b0;
|
||||
end else if ((gain1_t == 1'b0) && (ctrl_bit_cnt == CNT_DSA1_LE_RISE)) begin
|
||||
dsa1_le <= 1'b1;
|
||||
end else if ((gain1_t == 1'b0) && (ctrl_bit_cnt == CNT_DSA1_LE_FALL)) begin
|
||||
dsa1_le <= 1'b0;
|
||||
end else if ((gain1_t == 1'b0) && (ctrl_bit_cnt == CNT_GAIN1_RELEASE)) begin
|
||||
gain1_t <= 1'b1;
|
||||
end
|
||||
|
||||
if ((ctrl_bit_cnt == CNT_GAIN2_DRIVE) && (ctrl_mosi)) begin
|
||||
gain2 <= ctrl_index;
|
||||
gain2_t <= 1'b0;
|
||||
end else if ((gain2_t == 1'b0) && (ctrl_bit_cnt == CNT_DSA2_LE_RISE)) begin
|
||||
dsa2_le <= 1'b1;
|
||||
end else if ((gain2_t == 1'b0) && (ctrl_bit_cnt == CNT_DSA2_LE_FALL)) begin
|
||||
dsa2_le <= 1'b0;
|
||||
end else if ((gain2_t == 1'b0) && (ctrl_bit_cnt == CNT_GAIN2_RELEASE)) begin
|
||||
gain2_t <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// SPI readback for ctrl bus, based on current bit count
|
||||
always @ (negedge ctrl_sck)
|
||||
begin
|
||||
case (ctrl_bit_cnt) // Shift out on neg edge
|
||||
11: ctrl_miso <= gain1[5];
|
||||
12: ctrl_miso <= gain1[4];
|
||||
13: ctrl_miso <= gain1[3];
|
||||
14: ctrl_miso <= gain1[2];
|
||||
15: ctrl_miso <= gain1[1];
|
||||
16: ctrl_miso <= gain1[0];
|
||||
18: ctrl_miso <= gain2[5];
|
||||
19: ctrl_miso <= gain2[4];
|
||||
20: ctrl_miso <= gain2[3];
|
||||
21: ctrl_miso <= gain2[2];
|
||||
22: ctrl_miso <= gain2[1];
|
||||
23: ctrl_miso <= gain2[0];
|
||||
default: ctrl_miso <= 1'b0;
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule // rhodium_gain_ctrl
|
||||
`default_nettype wire
|
||||
@@ -0,0 +1,54 @@
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2018 Ettus Research, A National Instruments Company
|
||||
//
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
//
|
||||
// Module: rhodium_gain_table
|
||||
// Description:
|
||||
// Simple dual port memory for use as gain table
|
||||
// Implements a 128 x 16 bit dual-port RAM for storing 10-bit gain values.
|
||||
// Write and read domains are independent. Data takes 1 cycle to become valid
|
||||
// on the output of the RAM once written.
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
`default_nettype none
|
||||
|
||||
module rhodium_gain_table
|
||||
(
|
||||
input wire wr_clk,
|
||||
input wire wr_en,
|
||||
input wire [6:0] wr_addr,
|
||||
input wire [9:0] wr_data,
|
||||
|
||||
// Read data for wr_addr (read-first/read-before-write): One cycle latency
|
||||
output wire [9:0] wr_data_prev,
|
||||
|
||||
input wire rd_clk,
|
||||
input wire [6:0] rd_addr,
|
||||
output wire [9:0] rd_data // Read data for rd_addr: One cycle latency
|
||||
);
|
||||
|
||||
reg [15:0] gain_table[127:0];
|
||||
reg [15:0] wr_data_prev_r;
|
||||
reg [15:0] rd_data_r;
|
||||
|
||||
assign wr_data_prev = wr_data_prev_r[15:6];
|
||||
assign rd_data = rd_data_r[15:6];
|
||||
|
||||
always @ (posedge wr_clk)
|
||||
begin
|
||||
if (wr_en)
|
||||
gain_table[wr_addr] <= {wr_data, 6'b0};
|
||||
wr_data_prev_r <= gain_table[wr_addr];
|
||||
end
|
||||
|
||||
always @ (posedge rd_clk)
|
||||
begin
|
||||
rd_data_r <= gain_table[rd_addr];
|
||||
end
|
||||
|
||||
|
||||
endmodule // rhodium_gain_table
|
||||
`default_nettype wire
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2018 Ettus Research, A National Instruments Company
|
||||
//
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
//
|
||||
// Module: rhodium_lo_gain
|
||||
// Description:
|
||||
// LO Gain controller for Rhodium
|
||||
// Implements a gain index register (not a table)
|
||||
//
|
||||
// Provides 1 SPI slave:
|
||||
// The "ctrl" slave takes in a gain index and drives the DSA with that
|
||||
// value.
|
||||
// The SPI formats are provided below.
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
`default_nettype none
|
||||
|
||||
/**
|
||||
* SPI DATA FORMAT (left-most bit is first)
|
||||
* CTRL
|
||||
* M {table_sel[1:0], rsvd, gain[4:0], rsvd[1:0], wr_dsa1, ------rsvd[5:0], wr_dsa2, ----rsvd[5:0]
|
||||
* S {-------------------------------, --------------rsvd[3:0], gain1[4:0], -rsvd[1:0], gain2[4:0]}
|
||||
*/
|
||||
module rhodium_lo_gain #(
|
||||
parameter TABLE_NUM = 2'b01
|
||||
) (
|
||||
input wire ctrl_sck,
|
||||
input wire ctrl_csb,
|
||||
input wire ctrl_mosi,
|
||||
output reg ctrl_miso,
|
||||
output wire [4:0] dsa,
|
||||
output reg dsa1_le,
|
||||
output reg dsa2_le
|
||||
);
|
||||
|
||||
localparam CNT_GAIN1_DRIVE = 10,
|
||||
CNT_DSA1_LE_RISE = 11,
|
||||
CNT_DSA1_LE_FALL = 14,
|
||||
CNT_GAIN1_RELEASE = 17;
|
||||
localparam CNT_GAIN2_DRIVE = 17,
|
||||
CNT_DSA2_LE_RISE = 18,
|
||||
CNT_DSA2_LE_FALL = 21,
|
||||
CNT_GAIN2_RELEASE = 24;
|
||||
|
||||
reg [4:0] ctrl_bit_cnt;
|
||||
reg [1:0] ctrl_tbl;
|
||||
reg [5:0] ctrl_index;
|
||||
reg [5:0] gain1, gain2;
|
||||
reg gain1_t;
|
||||
reg gain2_t;
|
||||
|
||||
assign dsa = (!gain1_t | !gain2_t) ? ctrl_index[4:0] : 5'b11111;
|
||||
|
||||
// Cycle counter for where we are in protocol and shift register for input
|
||||
// Also controls timing of DSAs' latch enable signals
|
||||
always @ (posedge ctrl_sck or posedge ctrl_csb)
|
||||
begin
|
||||
if (ctrl_csb) begin
|
||||
ctrl_bit_cnt <= 5'd0;
|
||||
dsa1_le <= 1'b0;
|
||||
dsa2_le <= 1'b0;
|
||||
gain1_t <= 1'b1;
|
||||
gain2_t <= 1'b1;
|
||||
end else if (!ctrl_csb) begin
|
||||
if (ctrl_bit_cnt < 23) begin
|
||||
ctrl_bit_cnt <= ctrl_bit_cnt + 5'd1;
|
||||
end
|
||||
|
||||
if (ctrl_bit_cnt < 8) begin
|
||||
{ctrl_tbl, ctrl_index} <= {ctrl_tbl[0], ctrl_index, ctrl_mosi};
|
||||
end
|
||||
|
||||
if (ctrl_tbl == TABLE_NUM) begin
|
||||
if ((ctrl_bit_cnt == CNT_GAIN1_DRIVE) && (ctrl_mosi)) begin
|
||||
gain1 <= ctrl_index;
|
||||
gain1_t <= 1'b0;
|
||||
end else if ((gain1_t == 1'b0) && (ctrl_bit_cnt == CNT_DSA1_LE_RISE)) begin
|
||||
dsa1_le <= 1'b1;
|
||||
end else if ((gain1_t == 1'b0) && (ctrl_bit_cnt == CNT_DSA1_LE_FALL)) begin
|
||||
dsa1_le <= 1'b0;
|
||||
end else if ((gain1_t == 1'b0) && (ctrl_bit_cnt == CNT_GAIN1_RELEASE)) begin
|
||||
gain1_t <= 1'b1;
|
||||
end
|
||||
|
||||
if ((ctrl_bit_cnt == CNT_GAIN2_DRIVE) && (ctrl_mosi)) begin
|
||||
gain2 <= ctrl_index;
|
||||
gain2_t <= 1'b0;
|
||||
end else if ((gain2_t == 1'b0) && (ctrl_bit_cnt == CNT_DSA2_LE_RISE)) begin
|
||||
dsa2_le <= 1'b1;
|
||||
end else if ((gain2_t == 1'b0) && (ctrl_bit_cnt == CNT_DSA2_LE_FALL)) begin
|
||||
dsa2_le <= 1'b0;
|
||||
end else if ((gain2_t == 1'b0) && (ctrl_bit_cnt == CNT_GAIN2_RELEASE)) begin
|
||||
gain2_t <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// SPI readback for ctrl bus, based on current bit count
|
||||
always @ (negedge ctrl_sck)
|
||||
begin
|
||||
case (ctrl_bit_cnt) // Shift out on neg edge
|
||||
11: ctrl_miso <= gain1[5];
|
||||
12: ctrl_miso <= gain1[4];
|
||||
13: ctrl_miso <= gain1[3];
|
||||
14: ctrl_miso <= gain1[2];
|
||||
15: ctrl_miso <= gain1[1];
|
||||
16: ctrl_miso <= gain1[0];
|
||||
18: ctrl_miso <= gain2[5];
|
||||
19: ctrl_miso <= gain2[4];
|
||||
20: ctrl_miso <= gain2[3];
|
||||
21: ctrl_miso <= gain2[2];
|
||||
22: ctrl_miso <= gain2[1];
|
||||
23: ctrl_miso <= gain2[0];
|
||||
default: ctrl_miso <= 1'b0;
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
endmodule // rhodium_lo_gain
|
||||
`default_nettype wire
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Copyright (C) 2017 Intel Corporation. All rights reserved.
|
||||
# Your use of Intel Corporation's design tools, logic functions
|
||||
# and other software and tools, and its AMPP partner logic
|
||||
# functions, and any output files from any of the foregoing
|
||||
# (including device programming or simulation files), and any
|
||||
# associated documentation or information are expressly subject
|
||||
# to the terms and conditions of the Intel Program License
|
||||
# Subscription Agreement, the Intel Quartus Prime License Agreement,
|
||||
# the Intel MegaCore Function License Agreement, or other
|
||||
# applicable license agreement, including, without limitation,
|
||||
# that your use is for the sole purpose of programming logic
|
||||
# devices manufactured by Intel and sold by Intel or its
|
||||
# authorized distributors. Please refer to the applicable
|
||||
# agreement for further details.
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Quartus Prime
|
||||
# Version 17.0.2 Build 602 07/19/2017 SJ Lite Edition
|
||||
# Date created = 08:22:34 September 13, 2017
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
|
||||
QUARTUS_VERSION = "17.0"
|
||||
DATE = "08:22:34 September 13, 2017"
|
||||
|
||||
# Revisions
|
||||
|
||||
PROJECT_REVISION = "rhodium_top"
|
||||
@@ -0,0 +1,306 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Copyright (C) 2017 Intel Corporation. All rights reserved.
|
||||
# Your use of Intel Corporation's design tools, logic functions
|
||||
# and other software and tools, and its AMPP partner logic
|
||||
# functions, and any output files from any of the foregoing
|
||||
# (including device programming or simulation files), and any
|
||||
# associated documentation or information are expressly subject
|
||||
# to the terms and conditions of the Intel Program License
|
||||
# Subscription Agreement, the Intel Quartus Prime License Agreement,
|
||||
# the Intel MegaCore Function License Agreement, or other
|
||||
# applicable license agreement, including, without limitation,
|
||||
# that your use is for the sole purpose of programming logic
|
||||
# devices manufactured by Intel and sold by Intel or its
|
||||
# authorized distributors. Please refer to the applicable
|
||||
# agreement for further details.
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Quartus Prime
|
||||
# Version 17.0.2 Build 602 07/19/2017 SJ Lite Edition
|
||||
# Date created = 08:22:34 September 13, 2017
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Notes:
|
||||
#
|
||||
# 1) The default values for assignments are stored in the file:
|
||||
# rhodium_top_assignment_defaults.qdf
|
||||
# If this file doesn't exist, see file:
|
||||
# assignment_defaults.qdf
|
||||
#
|
||||
# 2) Altera recommends that you do not modify this file. This
|
||||
# file is updated automatically by the Quartus Prime software
|
||||
# and any changes you make may be lost or overwritten.
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
|
||||
|
||||
set_global_assignment -name FAMILY "MAX 10"
|
||||
set_global_assignment -name DEVICE 10M04SAU169I7G
|
||||
set_global_assignment -name TOP_LEVEL_ENTITY rhodium_top
|
||||
set_global_assignment -name ORIGINAL_QUARTUS_VERSION 17.0.2
|
||||
set_global_assignment -name PROJECT_CREATION_TIME_DATE "08:22:34 SEPTEMBER 13, 2017"
|
||||
set_global_assignment -name LAST_QUARTUS_VERSION "18.1.0 Lite Edition"
|
||||
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
|
||||
set_global_assignment -name MIN_CORE_JUNCTION_TEMP "-40"
|
||||
set_global_assignment -name MAX_CORE_JUNCTION_TEMP 100
|
||||
set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 256
|
||||
set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
|
||||
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
|
||||
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
|
||||
set_location_assignment PIN_D11 -to CPLD_PS_SPI_LE_25
|
||||
set_location_assignment PIN_F13 -to CPLD_PS_SPI_CLK_25
|
||||
set_location_assignment PIN_E10 -to CPLD_PS_ADDR0_25
|
||||
set_location_assignment PIN_A12 -to CPLD_PS_ADDR1_25
|
||||
set_location_assignment PIN_F12 -to CPLD_PS_SPI_SDI_25
|
||||
set_location_assignment PIN_F10 -to CPLD_PS_SPI_SDO_25
|
||||
set_location_assignment PIN_B1 -to ADC_A_Over_Range_18
|
||||
set_location_assignment PIN_D1 -to ADC_B_Over_Range_18
|
||||
set_instance_assignment -name IO_STANDARD "1.8 V" -to ADC_A_Over_Range_18
|
||||
set_instance_assignment -name IO_STANDARD "1.8 V" -to ADC_B_Over_Range_18
|
||||
set_instance_assignment -name IO_STANDARD LVDS -to LO_SYNC
|
||||
set_location_assignment PIN_G9 -to LO_SYNC
|
||||
set_location_assignment PIN_G10 -to "LO_SYNC(n)"
|
||||
set_instance_assignment -name IO_STANDARD "1.8 V" -to ADC_SPI_CS_L_18
|
||||
set_location_assignment PIN_C2 -to ADC_SPI_CS_L_18
|
||||
set_location_assignment PIN_C1 -to ADC_SPI_SCLK_18
|
||||
set_location_assignment PIN_E3 -to ADC_SPI_SDIO_18
|
||||
set_location_assignment PIN_M5 -to CLKDIST_SPI_CS_L
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to CLKDIST_SPI_CS_L
|
||||
set_instance_assignment -name IO_STANDARD "1.8 V" -to ADC_SPI_SCLK_18
|
||||
set_instance_assignment -name IO_STANDARD "1.8 V" -to ADC_SPI_SDIO_18
|
||||
set_location_assignment PIN_L5 -to CLKDIST_SPI_SCLK
|
||||
set_location_assignment PIN_N5 -to CLKDIST_SPI_SDIO
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to CLKDIST_SPI_SCLK
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to CLKDIST_SPI_SDIO
|
||||
set_location_assignment PIN_K6 -to CLKDIST_Status_LD1
|
||||
set_location_assignment PIN_J6 -to CLKDIST_Status_LD2
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to CLKDIST_Status_LD1
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to CLKDIST_Status_LD2
|
||||
set_location_assignment PIN_M1 -to CPLD_ATR_TX_18
|
||||
set_location_assignment PIN_L1 -to CPLD_ATR_RX_18
|
||||
set_instance_assignment -name IO_STANDARD "1.8 V" -to CPLD_ATR_RX_18
|
||||
set_instance_assignment -name IO_STANDARD "1.8 V" -to CPLD_ATR_TX_18
|
||||
set_location_assignment PIN_H6 -to CPLD_PL_SPI_ADDR0_18
|
||||
set_location_assignment PIN_K2 -to CPLD_PL_SPI_ADDR1_18
|
||||
set_location_assignment PIN_J2 -to CPLD_PL_SPI_ADDR2_18
|
||||
set_instance_assignment -name IO_STANDARD "1.8 V" -to CPLD_PL_SPI_ADDR0_18
|
||||
set_instance_assignment -name IO_STANDARD "1.8 V" -to CPLD_PL_SPI_ADDR1_18
|
||||
set_instance_assignment -name IO_STANDARD "1.8 V" -to CPLD_PL_SPI_ADDR2_18
|
||||
set_location_assignment PIN_K1 -to CPLD_PL_SPI_LE_18
|
||||
set_location_assignment PIN_H5 -to CPLD_PL_SPI_SCLK_18
|
||||
set_location_assignment PIN_L3 -to CPLD_PL_SPI_SDI_18
|
||||
set_location_assignment PIN_L2 -to CPLD_PL_SPI_SDO_18
|
||||
set_instance_assignment -name IO_STANDARD "1.8 V" -to CPLD_PL_SPI_LE_18
|
||||
set_instance_assignment -name IO_STANDARD "1.8 V" -to CPLD_PL_SPI_SCLK_18
|
||||
set_instance_assignment -name IO_STANDARD "1.8 V" -to CPLD_PL_SPI_SDI_18
|
||||
set_instance_assignment -name IO_STANDARD "1.8 V" -to CPLD_PL_SPI_SDO_18
|
||||
set_location_assignment PIN_M2 -to DAC_Alarm_18
|
||||
set_instance_assignment -name IO_STANDARD "1.8 V" -to DAC_Alarm_18
|
||||
set_location_assignment PIN_N3 -to DAC_SPI_SDIO_18
|
||||
set_location_assignment PIN_N2 -to DAC_SPI_SCLK_18
|
||||
set_location_assignment PIN_M3 -to DAC_SPI_CS_L_18
|
||||
set_instance_assignment -name IO_STANDARD "1.8 V" -to DAC_SPI_CS_L_18
|
||||
set_instance_assignment -name IO_STANDARD "1.8 V" -to DAC_SPI_SCLK_18
|
||||
set_instance_assignment -name IO_STANDARD "1.8 V" -to DAC_SPI_SDIO_18
|
||||
set_location_assignment PIN_M7 -to LOSYNTH_RX_MUXOUT
|
||||
set_location_assignment PIN_N7 -to LOSYNTH_TX_MUXOUT
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LOSYNTH_RX_MUXOUT
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LOSYNTH_TX_MUXOUT
|
||||
set_location_assignment PIN_E6 -to LO_RX_CS_L
|
||||
set_location_assignment PIN_B2 -to LO_SPI_SCLK
|
||||
set_location_assignment PIN_M4 -to LO_SPI_SDI
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LO_RX_CS_L
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LO_SPI_SCLK
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LO_SPI_SDI
|
||||
set_location_assignment PIN_K5 -to LO_TX_CS_L
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LO_TX_CS_L
|
||||
set_location_assignment PIN_B6 -to Rx_DSA1_LE
|
||||
set_location_assignment PIN_A9 -to Rx_DSA2_LE
|
||||
set_location_assignment PIN_D8 -to Rx_DSA_C1
|
||||
set_location_assignment PIN_D6 -to Rx_DSA_C2
|
||||
set_location_assignment PIN_A11 -to Rx_DSA_C4
|
||||
set_location_assignment PIN_B10 -to Rx_DSA_C8
|
||||
set_location_assignment PIN_A10 -to Rx_DSA_C16
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Rx_DSA1_LE
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Rx_DSA2_LE
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Rx_DSA_C1
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Rx_DSA_C2
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Rx_DSA_C4
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Rx_DSA_C8
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Rx_DSA_C16
|
||||
set_location_assignment PIN_B3 -to Rx_Demod_ADJ_1
|
||||
set_location_assignment PIN_N4 -to Rx_Demod_ADJ_2
|
||||
set_location_assignment PIN_J5 -to Rx_LO_Filter_Sw_1
|
||||
set_location_assignment PIN_J7 -to Rx_LO_Filter_Sw_2
|
||||
set_location_assignment PIN_L4 -to Rx_LO_Input_Select
|
||||
set_location_assignment PIN_A6 -to Rx_Sw1_Ctrl_1
|
||||
set_location_assignment PIN_A7 -to Rx_Sw1_Ctrl_2
|
||||
set_location_assignment PIN_A5 -to Rx_Sw2_Ctrl
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Rx_Demod_ADJ_1
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Rx_Demod_ADJ_2
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Rx_Sw1_Ctrl_1
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Rx_Sw1_Ctrl_2
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Rx_Sw2_Ctrl
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Rx_LO_Filter_Sw_1
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Rx_LO_Filter_Sw_2
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Rx_LO_Input_Select
|
||||
set_location_assignment PIN_A4 -to Rx_Sw3_Ctrl_1
|
||||
set_location_assignment PIN_A3 -to Rx_Sw3_Ctrl_2
|
||||
set_location_assignment PIN_C10 -to Rx_Sw4_Ctrl_1
|
||||
set_location_assignment PIN_A8 -to Rx_Sw4_Ctrl_2
|
||||
set_location_assignment PIN_B9 -to Rx_Sw4_Ctrl_3
|
||||
set_location_assignment PIN_C9 -to Rx_Sw4_Ctrl_4
|
||||
set_location_assignment PIN_K13 -to Tx_DSA1_LE
|
||||
set_location_assignment PIN_K12 -to Tx_DSA2_LE
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Rx_Sw3_Ctrl_1
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Rx_Sw3_Ctrl_2
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Rx_Sw4_Ctrl_1
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Rx_Sw4_Ctrl_2
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Rx_Sw4_Ctrl_3
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Rx_Sw4_Ctrl_4
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Tx_DSA1_LE
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Tx_DSA2_LE
|
||||
set_location_assignment PIN_H13 -to Tx_DSA_C1
|
||||
set_location_assignment PIN_H8 -to Tx_DSA_C2
|
||||
set_location_assignment PIN_J13 -to Tx_DSA_C4
|
||||
set_location_assignment PIN_H10 -to Tx_DSA_C8
|
||||
set_location_assignment PIN_J12 -to Tx_DSA_C16
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Tx_DSA_C1
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Tx_DSA_C2
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Tx_DSA_C4
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Tx_DSA_C8
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Tx_DSA_C16
|
||||
set_location_assignment PIN_N6 -to Tx_LO_Filter_Sw_1
|
||||
set_location_assignment PIN_N12 -to Tx_LO_Filter_Sw_2
|
||||
set_location_assignment PIN_N8 -to Tx_LO_Input_Select
|
||||
set_location_assignment PIN_L10 -to Tx_Sw1_Ctrl_1
|
||||
set_location_assignment PIN_N10 -to Tx_Sw1_Ctrl_2
|
||||
set_location_assignment PIN_N11 -to Tx_Sw2_Ctrl_1
|
||||
set_location_assignment PIN_L11 -to Tx_Sw2_Ctrl_2
|
||||
set_location_assignment PIN_L12 -to Tx_Sw3_Ctrl_1
|
||||
set_location_assignment PIN_M13 -to Tx_Sw3_Ctrl_2
|
||||
set_location_assignment PIN_K11 -to Tx_Sw3_Ctrl_3
|
||||
set_location_assignment PIN_J9 -to Tx_Sw3_Ctrl_4
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Tx_LO_Filter_Sw_1
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Tx_LO_Filter_Sw_2
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Tx_LO_Input_Select
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Tx_Sw1_Ctrl_1
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Tx_Sw1_Ctrl_2
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Tx_Sw2_Ctrl_1
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Tx_Sw2_Ctrl_2
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Tx_Sw3_Ctrl_1
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Tx_Sw3_Ctrl_2
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Tx_Sw3_Ctrl_3
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Tx_Sw3_Ctrl_4
|
||||
set_location_assignment PIN_B11 -to PHDAC_SPI_CS_L
|
||||
set_location_assignment PIN_C11 -to PHDAC_SPI_SCLK
|
||||
set_location_assignment PIN_D9 -to PHDAC_SPI_SDI
|
||||
set_location_assignment PIN_N9 -to LODIST_Bd_SPI_CS_L
|
||||
set_location_assignment PIN_J8 -to LODIST_Bd_SPI_SCLK
|
||||
set_location_assignment PIN_M9 -to LODIST_Bd_SPI_SDI
|
||||
set_location_assignment PIN_L13 -to LO_DSA_C1
|
||||
set_location_assignment PIN_K10 -to LO_DSA_C2
|
||||
set_location_assignment PIN_H9 -to LO_DSA_C4
|
||||
set_location_assignment PIN_G12 -to LO_DSA_C8
|
||||
set_location_assignment PIN_G13 -to LO_DSA_C16
|
||||
set_location_assignment PIN_J10 -to RxLO_DSA_LE
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LODIST_Bd_SPI_CS_L
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LODIST_Bd_SPI_SCLK
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LODIST_Bd_SPI_SDI
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LO_DSA_C1
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LO_DSA_C2
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LO_DSA_C4
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LO_DSA_C8
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LO_DSA_C16
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to RxLO_DSA_LE
|
||||
set_location_assignment PIN_B4 -to Rx_Sw6_Ctrl_1
|
||||
set_location_assignment PIN_B5 -to Rx_Sw6_Ctrl_2
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Rx_Sw6_Ctrl_1
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Rx_Sw6_Ctrl_2
|
||||
set_location_assignment PIN_M8 -to TxLO_DSA_LE
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to TxLO_DSA_LE
|
||||
set_location_assignment PIN_M11 -to Tx_Sw5_Ctrl_1
|
||||
set_location_assignment PIN_M12 -to Tx_Sw5_Ctrl_2
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Tx_Sw5_Ctrl_1
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Tx_Sw5_Ctrl_2
|
||||
set_location_assignment PIN_D12 -to Cal_iso_Sw_Ctrl
|
||||
set_location_assignment PIN_K8 -to LODIST_Bd_IO1
|
||||
set_location_assignment PIN_M10 -to Tx_HB_LB_Select
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Tx_HB_LB_Select
|
||||
set_location_assignment PIN_E8 -to Rx_HB_LB_Select
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to Rx_HB_LB_Select
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to PHDAC_SPI_CS_L
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to PHDAC_SPI_SCLK
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to PHDAC_SPI_SDI
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to CPLD_PS_ADDR0_25
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to CPLD_PS_ADDR1_25
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to CPLD_PS_SPI_CLK_25
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to CPLD_PS_SPI_LE_25
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to CPLD_PS_SPI_SDI_25
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to CPLD_PS_SPI_SDO_25
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to Cal_iso_Sw_Ctrl
|
||||
set_instance_assignment -name IO_STANDARD "3.3 V SCHMITT TRIGGER" -to LODIST_Bd_IO1
|
||||
set_global_assignment -name EDA_SIMULATION_TOOL "ModelSim-Altera (Verilog)"
|
||||
set_global_assignment -name EDA_OUTPUT_DATA_FORMAT "VERILOG HDL" -section_id eda_simulation
|
||||
set_location_assignment PIN_E4 -to usrp_io[0]
|
||||
set_location_assignment PIN_G5 -to usrp_io[1]
|
||||
set_location_assignment PIN_H4 -to usrp_io[2]
|
||||
set_location_assignment PIN_J1 -to usrp_io[3]
|
||||
set_location_assignment PIN_F1 -to usrp_io[4]
|
||||
set_location_assignment PIN_C12 -to usrp_io[5]
|
||||
set_location_assignment PIN_C13 -to usrp_io[6]
|
||||
set_location_assignment PIN_E12 -to usrp_io[7]
|
||||
set_location_assignment PIN_E13 -to usrp_io[8]
|
||||
set_location_assignment PIN_B13 -to usrp_io[9]
|
||||
set_location_assignment PIN_F9 -to usrp_io[10]
|
||||
set_location_assignment PIN_B12 -to usrp_io[11]
|
||||
set_location_assignment PIN_E9 -to usrp_io[12]
|
||||
set_location_assignment PIN_F8 -to usrp_io[13]
|
||||
set_instance_assignment -name IO_STANDARD "1.8 V" -to usrp_io[0]
|
||||
set_instance_assignment -name IO_STANDARD "1.8 V" -to usrp_io[1]
|
||||
set_instance_assignment -name IO_STANDARD "1.8 V" -to usrp_io[2]
|
||||
set_instance_assignment -name IO_STANDARD "1.8 V" -to usrp_io[3]
|
||||
set_instance_assignment -name IO_STANDARD "1.8 V" -to usrp_io[4]
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to usrp_io[5]
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to usrp_io[6]
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to usrp_io[7]
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to usrp_io[8]
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to usrp_io[9]
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to usrp_io[10]
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to usrp_io[11]
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to usrp_io[12]
|
||||
set_instance_assignment -name IO_STANDARD "2.5 V" -to usrp_io[13]
|
||||
set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW"
|
||||
set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)"
|
||||
set_global_assignment -name EDA_TIME_SCALE "1 ps" -section_id eda_simulation
|
||||
set_global_assignment -name EDA_TEST_BENCH_ENABLE_STATUS TEST_BENCH_MODE -section_id eda_simulation
|
||||
set_global_assignment -name EDA_NATIVELINK_SIMULATION_TEST_BENCH rh_tb -section_id eda_simulation
|
||||
set_global_assignment -name EDA_TEST_BENCH_NAME rh_tb -section_id eda_simulation
|
||||
set_global_assignment -name EDA_DESIGN_INSTANCE_NAME NA -section_id rh_tb
|
||||
set_global_assignment -name EDA_TEST_BENCH_RUN_SIM_FOR "9000 ns" -section_id rh_tb
|
||||
set_global_assignment -name EDA_TEST_BENCH_MODULE_NAME rh_tb -section_id rh_tb
|
||||
set_global_assignment -name FLOW_ENABLE_POWER_ANALYZER ON
|
||||
set_global_assignment -name POWER_DEFAULT_INPUT_IO_TOGGLE_RATE "12.5 %"
|
||||
set_global_assignment -name EDA_RUN_TOOL_AUTOMATICALLY OFF -section_id eda_simulation
|
||||
set_global_assignment -name OPTIMIZATION_MODE "HIGH PERFORMANCE EFFORT"
|
||||
set_global_assignment -name VERILOG_FILE rhodium_top.v
|
||||
set_global_assignment -name VERILOG_FILE rhodium_gain_ctrl.v
|
||||
set_global_assignment -name VERILOG_FILE rhodium_gain_table.v
|
||||
set_global_assignment -name VERILOG_FILE rhodium_lo_gain.v
|
||||
set_global_assignment -name VERILOG_FILE rh_tb.v
|
||||
set_global_assignment -name EDA_TEST_BENCH_FILE rh_tb.v -section_id rh_tb
|
||||
|
||||
|
||||
set_global_assignment -name ENABLE_OCT_DONE OFF
|
||||
set_global_assignment -name STRATIXV_CONFIGURATION_SCHEME "PASSIVE SERIAL"
|
||||
set_global_assignment -name USE_CONFIGURATION_DEVICE ON
|
||||
set_global_assignment -name CRC_ERROR_OPEN_DRAIN OFF
|
||||
set_global_assignment -name GENERATE_SVF_FILE ON
|
||||
set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -rise
|
||||
set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -fall
|
||||
set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -rise
|
||||
set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -fall
|
||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
||||
@@ -0,0 +1,415 @@
|
||||
# SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
#
|
||||
# Copyright 2019 Ettus Research, A National Instruments Company
|
||||
#
|
||||
# Timing constraints for Rhodium's MAX 10 board controller
|
||||
|
||||
set_time_format -unit ns -decimal_places 3
|
||||
|
||||
# Some constants for constraining the design with the FPGA-centric method:
|
||||
# Maximum trace propagation delay is assumed to be 0.6 ns on any traces
|
||||
# to on-dboard slaves
|
||||
set board_delay 0.600
|
||||
set clk_uncertainty 0.150
|
||||
|
||||
###############################################################################
|
||||
# Clocks
|
||||
###############################################################################
|
||||
|
||||
# The PS SPI clock is maximum 10 MHz. It is driven from another source and
|
||||
# provided with the data.
|
||||
# CPLD_PS_SPI_CLK_25: 8 MHz
|
||||
set sclk_ps_period 125.000
|
||||
|
||||
# Create clock for the PS's SPI interface
|
||||
create_clock -name sclk_ps -period $sclk_ps_period \
|
||||
[get_ports CPLD_PS_SPI_CLK_25]
|
||||
|
||||
# The PL SPI clock is split into two pieces. For the normal case, the clock
|
||||
# frequency is 10 MHz. This is for any read operations.
|
||||
#
|
||||
# CPLD_PL_SPI_SCLK_18 pass through / read back ONLY: 10 MHz
|
||||
set sclk_pl_period 100.000
|
||||
create_clock -name sclk_pl -period $sclk_pl_period \
|
||||
[get_ports CPLD_PL_SPI_SCLK_18]
|
||||
|
||||
# We can go faster for the PL writes to the internal registers and LOs.
|
||||
# This rate is not supported for readback, but it helps with getting the DSA
|
||||
# settings and LO settings in faster.
|
||||
# CPLD_PL_SPI_SCLK_18 internal ONLY: 25 MHz
|
||||
set sclk_pl_wr_period 40.000
|
||||
create_clock -name sclk_pl_wr -period $sclk_pl_wr_period \
|
||||
[get_ports CPLD_PL_SPI_SCLK_18] -add
|
||||
|
||||
# Output clocks for the MAX 10's SPI master interfaces (1 for each slave IC)
|
||||
create_generated_clock -source [get_ports CPLD_PS_SPI_CLK_25] \
|
||||
-name clkdist_clk [get_ports CLKDIST_SPI_SCLK]
|
||||
create_generated_clock -source [get_ports CPLD_PS_SPI_CLK_25] \
|
||||
-name adc_clk [get_ports ADC_SPI_SCLK_18]
|
||||
create_generated_clock -source [get_ports CPLD_PS_SPI_CLK_25] \
|
||||
-name dac_clk [get_ports DAC_SPI_SCLK_18]
|
||||
create_generated_clock -source [get_ports CPLD_PS_SPI_CLK_25] \
|
||||
-name phdac_clk [get_ports PHDAC_SPI_SCLK]
|
||||
|
||||
create_generated_clock -source [get_ports CPLD_PL_SPI_SCLK_18] \
|
||||
-master_clock [get_clocks sclk_pl] \
|
||||
-name lo_clk [get_ports LO_SPI_SCLK]
|
||||
create_generated_clock -source [get_ports CPLD_PL_SPI_SCLK_18] \
|
||||
-master_clock [get_clocks sclk_pl_wr] \
|
||||
-name lo_wr_clk [get_ports LO_SPI_SCLK] -add
|
||||
create_generated_clock -source [get_ports CPLD_PL_SPI_SCLK_18] \
|
||||
-master_clock [get_clocks sclk_pl] \
|
||||
-name lodist_clk [get_ports LODIST_Bd_SPI_SCLK]
|
||||
|
||||
# Virtual clock for DSA writes for skew calculations
|
||||
#create_generated_clock -source [get_pins lo_gain_table\|dsa1_le\|clk]
|
||||
create_generated_clock -source [get_ports CPLD_PL_SPI_SCLK_18] \
|
||||
-master_clock [get_clocks sclk_pl_wr] \
|
||||
-name dsa_reg_clk [get_pins lo_gain_table\|dsa1_le\|q]
|
||||
|
||||
create_generated_clock -source [get_pins lo_gain_table\|dsa1_le\|q] \
|
||||
-name dsa_clk [get_ports RxLO_DSA_LE]
|
||||
|
||||
# PL's pass through clock doesn't interact with internal clock
|
||||
set_clock_groups -physically_exclusive \
|
||||
-group [get_clocks {sclk_pl_wr lo_wr_clk dsa_reg_clk dsa_clk}] \
|
||||
-group [get_clocks {sclk_pl lo_clk lodist_clk}]
|
||||
|
||||
set_clock_groups -asynchronous \
|
||||
-group [get_clocks {sclk_ps clkdist_clk adc_clk dac_clk phdac_clk}] \
|
||||
-group [get_clocks {sclk_pl sclk_pl_wr lo_clk lodist_clk}]
|
||||
|
||||
set_clock_uncertainty -to [get_clocks {sclk_ps sclk_pl sclk_pl_wr clkdist_clk
|
||||
adc_clk dac_clk phdac_clk lo_clk lo_wr_clk lodist_clk dsa_reg_clk dsa_clk}] \
|
||||
$clk_uncertainty
|
||||
|
||||
###############################################################################
|
||||
# Timing Budget Calculations
|
||||
###############################################################################
|
||||
# Here we carve out some timing budget for the master's SPI interfaces.
|
||||
# The master will use these values to time its SPI interface.
|
||||
# The PL's write-only values are smaller because there are no external chip
|
||||
# dependencies.
|
||||
set setup_ps 25
|
||||
set hold_ps 30
|
||||
|
||||
# PL SPI is constrained on the master with an allowed skew value of +/- 3 ns
|
||||
# relative to the launch clock
|
||||
# Increase to 5 ns here for more margin
|
||||
set pl_skew 5
|
||||
|
||||
# Clocks are nominally a 50% duty cycle, so difference between latch and
|
||||
# launch is half a period, so subtract allowed skew from that for setup/hold
|
||||
# specification. The half period is due to launch being the falling edge and
|
||||
# latch being the rising edge.
|
||||
set setup_pl [expr {$sclk_pl_period / 2 - $pl_skew}]
|
||||
set hold_pl [expr {$sclk_pl_period / 2 - $pl_skew}]
|
||||
set setup_pl_wr [expr {$sclk_pl_wr_period / 2 - $pl_skew}]
|
||||
set hold_pl_wr [expr {$sclk_pl_wr_period / 2 - $pl_skew}]
|
||||
|
||||
# Calculate input delays relative to falling edge (launch)
|
||||
# Min is hold time after previous rising edge (previous latch)
|
||||
# Max is setup time before next rising edge (next latch)
|
||||
set input_delay_min_ps [expr {-$sclk_ps_period / 2 + $hold_ps}]
|
||||
set input_delay_max_ps [expr {$sclk_ps_period / 2 - $setup_ps}]
|
||||
set input_delay_min_pl [expr {-$sclk_pl_period / 2 + $hold_pl}]
|
||||
set input_delay_max_pl [expr {$sclk_pl_period / 2 - $setup_pl}]
|
||||
set input_delay_min_pl_wr [expr {-$sclk_pl_wr_period / 2 + $hold_pl_wr}]
|
||||
set input_delay_max_pl_wr [expr {$sclk_pl_wr_period / 2 - $setup_pl_wr}]
|
||||
|
||||
# Again, carve out timing budget for master's SPI interface
|
||||
# Readback on the master will depend on clk-to-q of our slave.
|
||||
# These values will need to be at least as large as the worst slave.
|
||||
# Clock arrival at the slave will be delayed by propagation through the MAX 10
|
||||
# Data to the MAX 10's input port will be further delayed by slave's clk-to-q
|
||||
# On top of that, we then need budget for the data to cross the MAX 10, head
|
||||
# out the I/O, and propagate to the master's pin. Then the master will need
|
||||
# some budget for setup time.
|
||||
#
|
||||
# Here is what we'll budget:
|
||||
# Clk propagation to I/O: 7 ns
|
||||
# Clk trace delay: 1 ns
|
||||
# Worst-case chip clk-to-q: 10 ns
|
||||
# Data trace delay: 1 ns
|
||||
# Data propagation delay from input pin to output pin: 8 ns
|
||||
# Total clk-to-q from MAX 10 sclk input to MAX 10 output: 27 ns
|
||||
#
|
||||
# Then master's budget is 23 ns for clock delay + data delay + setup time
|
||||
set clk_q_max_ps 27.000
|
||||
|
||||
# For the PL, the worst-case chip changes to 2 ns, so there is more budget
|
||||
set clk_q_max_pl 20.000
|
||||
|
||||
# clk-to-q determines one side of the data invalid window
|
||||
# The maximum output delay is simply latch edge - clk-to-q
|
||||
# Launch is falling edge, and latch is rising edge, so...
|
||||
set output_delay_max_ps [expr {$sclk_ps_period / 2 - $clk_q_max_ps}]
|
||||
set output_delay_max_pl [expr {$sclk_pl_period / 2 - $clk_q_max_pl}]
|
||||
|
||||
# The minimum output delay represents the other edge of the data invalid
|
||||
# window. Our clock is likely quite delayed already, but add a little more
|
||||
# margin for hold time.
|
||||
set output_delay_min_ps -5.000
|
||||
set output_delay_min_pl -5.000
|
||||
|
||||
|
||||
###############################################################################
|
||||
# I/O groups (for reference later)
|
||||
###############################################################################
|
||||
|
||||
# Chip selects
|
||||
set ps_csb [get_ports {
|
||||
CPLD_PS_ADDR0_25
|
||||
CPLD_PS_ADDR1_25
|
||||
CPLD_PS_SPI_LE_25
|
||||
usrp_io[12]
|
||||
usrp_io[13]
|
||||
}]
|
||||
set pl_csb [get_ports {
|
||||
CPLD_PL_SPI_ADDR0_18
|
||||
CPLD_PL_SPI_ADDR1_18
|
||||
CPLD_PL_SPI_ADDR2_18
|
||||
CPLD_PL_SPI_LE_18
|
||||
}]
|
||||
|
||||
# Data for internal PL SPI
|
||||
set pl_src [get_ports {
|
||||
CPLD_PL_SPI_SDI_18
|
||||
}]
|
||||
|
||||
# Passthrough inputs (forward direction)
|
||||
# CPLD_PS_SPI_CLK_25 and CPLD_PL_SPI_SCLK_18 are special
|
||||
set ps_pt_src [get_ports {CPLD_PS_SPI_LE_25
|
||||
usrp_io[12]
|
||||
usrp_io[13]
|
||||
CPLD_PS_ADDR1_25
|
||||
CPLD_PS_SPI_SDI_25
|
||||
}]
|
||||
|
||||
set pl_pt_src [get_ports {CPLD_PL_SPI_LE_18
|
||||
CPLD_PL_SPI_ADDR1_18
|
||||
CPLD_PL_SPI_ADDR2_18
|
||||
CPLD_PL_SPI_SDI_18
|
||||
}]
|
||||
|
||||
# Passthrough outputs (forward direction)
|
||||
# And inputs from the SPI slaves (readback direction)
|
||||
set clkdist_spi_out [get_ports {
|
||||
CLKDIST_SPI_CS_L
|
||||
CLKDIST_SPI_SDIO
|
||||
}]
|
||||
|
||||
set clkdist_spi_in [get_ports {
|
||||
CLKDIST_SPI_SDIO
|
||||
}]
|
||||
|
||||
set phdac_spi [get_ports {
|
||||
PHDAC_SPI_CS_L
|
||||
PHDAC_SPI_SDI
|
||||
}]
|
||||
|
||||
set dac_spi_out [get_ports {
|
||||
DAC_SPI_CS_L_18
|
||||
DAC_SPI_SDIO_18
|
||||
}]
|
||||
|
||||
set dac_spi_in [get_ports {
|
||||
DAC_SPI_SDIO_18
|
||||
}]
|
||||
|
||||
set adc_spi_out [get_ports {
|
||||
ADC_SPI_CS_L_18
|
||||
ADC_SPI_SDIO_18
|
||||
}]
|
||||
|
||||
set adc_spi_in [get_ports {
|
||||
ADC_SPI_SDIO_18
|
||||
}]
|
||||
|
||||
set lo_spi_out [get_ports {
|
||||
LO_TX_CS_L
|
||||
LO_RX_CS_L
|
||||
LO_SPI_SDI
|
||||
}]
|
||||
|
||||
set lo_spi_in [get_ports {
|
||||
LOSYNTH_RX_MUXOUT
|
||||
LOSYNTH_TX_MUXOUT
|
||||
}]
|
||||
|
||||
set lodist_spi_out [get_ports {
|
||||
LODIST_Bd_SPI_CS_L
|
||||
LODIST_Bd_SPI_SDI
|
||||
}]
|
||||
|
||||
# Readback outputs
|
||||
set ps_rb_out [get_ports CPLD_PS_SPI_SDO_25]
|
||||
set pl_rb_out [get_ports CPLD_PL_SPI_SDO_18]
|
||||
|
||||
##############################################################################
|
||||
# Chip-selects provide async resets
|
||||
##############################################################################
|
||||
set_false_path -from $ps_csb -to [get_pins *|clrn]
|
||||
set_false_path -from $pl_csb -to [get_pins *|clrn]
|
||||
|
||||
# Also ignore setup/hold analysis for chip-selects affecting readback path
|
||||
# These are available many cycles before readback begins and have
|
||||
# combinatorial paths to the output
|
||||
set_false_path -from $ps_csb -to $ps_rb_out
|
||||
set_false_path -from $pl_csb -to $pl_rb_out
|
||||
|
||||
set_input_delay -clock sclk_ps -clock_fall -max $input_delay_max_ps \
|
||||
[get_ports CPLD_PS_ADDR0_25]
|
||||
set_input_delay -clock sclk_ps -clock_fall -min $input_delay_min_ps \
|
||||
[get_ports CPLD_PS_ADDR0_25]
|
||||
|
||||
set_input_delay -clock sclk_pl -clock_fall -max $input_delay_max_pl \
|
||||
[get_ports CPLD_PL_SPI_ADDR0_18]
|
||||
set_input_delay -clock sclk_pl -clock_fall -min $input_delay_min_pl \
|
||||
[get_ports CPLD_PL_SPI_ADDR0_18]
|
||||
|
||||
set_input_delay -clock sclk_pl_wr -clock_fall -max $input_delay_max_pl_wr \
|
||||
[get_ports CPLD_PL_SPI_ADDR0_18] -add
|
||||
set_input_delay -clock sclk_pl_wr -clock_fall -min $input_delay_min_pl_wr \
|
||||
[get_ports CPLD_PL_SPI_ADDR0_18] -add
|
||||
|
||||
|
||||
##############################################################################
|
||||
# Input delays from SPI master
|
||||
##############################################################################
|
||||
set_input_delay -clock sclk_ps -clock_fall -max $input_delay_max_ps $ps_pt_src
|
||||
set_input_delay -clock sclk_ps -clock_fall -min $input_delay_min_ps $ps_pt_src
|
||||
|
||||
set_input_delay -clock sclk_pl -clock_fall -max $input_delay_max_pl $pl_pt_src
|
||||
set_input_delay -clock sclk_pl -clock_fall -min $input_delay_min_pl $pl_pt_src
|
||||
|
||||
set_input_delay -clock sclk_pl_wr -clock_fall -max $input_delay_max_pl_wr $pl_src -add
|
||||
set_input_delay -clock sclk_pl_wr -clock_fall -min $input_delay_min_pl_wr $pl_src -add
|
||||
|
||||
##############################################################################
|
||||
# Output delays to each SPI slave (uses setup/hold times from data sheet)
|
||||
##############################################################################
|
||||
set adc_setup 4
|
||||
set adc_hold 2
|
||||
set_output_delay -clock adc_clk -max [expr {$adc_setup + $board_delay}] \
|
||||
$adc_spi_out
|
||||
set_output_delay -clock adc_clk -min [expr {-$adc_hold - $board_delay}] \
|
||||
$adc_spi_out
|
||||
|
||||
set dac_setup 10
|
||||
set dac_hold 5
|
||||
set_output_delay -clock dac_clk -max [expr {$dac_setup + $board_delay}] \
|
||||
$dac_spi_out
|
||||
set_output_delay -clock dac_clk -min [expr {-$dac_hold - $board_delay}] \
|
||||
$dac_spi_out
|
||||
|
||||
set phdac_setup 5
|
||||
set phdac_hold 5
|
||||
set_output_delay -clock phdac_clk -max [expr {$phdac_setup + $board_delay}] \
|
||||
$phdac_spi
|
||||
set_output_delay -clock phdac_clk -min [expr {-$phdac_hold - $board_delay}] \
|
||||
$phdac_spi
|
||||
|
||||
set clkdist_setup 10
|
||||
set clkdist_hold 10
|
||||
set_output_delay -clock clkdist_clk -max [expr {$clkdist_setup + $board_delay}] \
|
||||
$clkdist_spi_out
|
||||
set_output_delay -clock clkdist_clk -min [expr {-$clkdist_hold - $board_delay}] \
|
||||
$clkdist_spi_out
|
||||
|
||||
set lo_setup 2
|
||||
set lo_hold 2
|
||||
set_output_delay -clock lo_wr_clk -max [expr {$lo_setup + $board_delay}] \
|
||||
$lo_spi_out
|
||||
set_output_delay -clock lo_wr_clk -min [expr {-$lo_hold - $board_delay}] \
|
||||
$lo_spi_out
|
||||
|
||||
##############################################################################
|
||||
# Input delays from each SPI slave (uses clk-to-q times from data sheet)
|
||||
# One board delay for clock, another for data
|
||||
##############################################################################
|
||||
set lo_clk_q 2
|
||||
set_input_delay -clock lo_clk -clock_fall -max [expr {$lo_clk_q + $board_delay + $board_delay}] \
|
||||
$lo_spi_in
|
||||
set_input_delay -clock lo_clk -clock_fall -min 0 \
|
||||
$lo_spi_in
|
||||
|
||||
set adc_clk_q 10
|
||||
set dac_clk_q 10
|
||||
set clkdist_clk_q 10
|
||||
set_input_delay -clock adc_clk -clock_fall -max [expr {$adc_clk_q + $board_delay + $board_delay}] \
|
||||
$adc_spi_in
|
||||
set_input_delay -clock adc_clk -clock_fall -min 0 \
|
||||
$adc_spi_in
|
||||
set_input_delay -clock dac_clk -clock_fall -max [expr {$dac_clk_q + $board_delay + $board_delay}] \
|
||||
$dac_spi_in
|
||||
set_input_delay -clock dac_clk -clock_fall -min 0 \
|
||||
$dac_spi_in
|
||||
set_input_delay -clock clkdist_clk -clock_fall -max [expr {$clkdist_clk_q + $board_delay + $board_delay}] \
|
||||
$clkdist_spi_in
|
||||
set_input_delay -clock clkdist_clk -clock_fall -min 0 \
|
||||
$clkdist_spi_in
|
||||
|
||||
|
||||
##############################################################################
|
||||
# Output delays for readback path
|
||||
##############################################################################
|
||||
set_output_delay -clock sclk_ps -max $output_delay_max_ps $ps_rb_out
|
||||
set_output_delay -clock sclk_ps -min $output_delay_min_ps $ps_rb_out
|
||||
|
||||
set_output_delay -clock sclk_pl -max $output_delay_max_pl $pl_rb_out
|
||||
set_output_delay -clock sclk_pl -min $output_delay_min_pl $pl_rb_out
|
||||
|
||||
##############################################################################
|
||||
# GPIOs and DSAs
|
||||
# Outputs that aren't timing-critical
|
||||
##############################################################################
|
||||
set gpos [get_ports {Tx_Sw*
|
||||
Rx_LO_*
|
||||
Tx_LO_*
|
||||
Rx_Sw*
|
||||
Rx_Demod_*
|
||||
Tx_HB_LB_Select
|
||||
Rx_HB_LB_Select
|
||||
Cal_iso_Sw_Ctrl
|
||||
LODIST_Bd_IO1
|
||||
}]
|
||||
|
||||
# Inputs that aren't timing-critical
|
||||
set gpis [get_ports {LO_SYNC
|
||||
CPLD_ATR_TX_18
|
||||
CPLD_ATR_RX_18
|
||||
DAC_Alarm_18
|
||||
CLKDIST_Status*
|
||||
LODIST_Bd_IO1
|
||||
}]
|
||||
|
||||
# DSAs (special skew needs)
|
||||
# RxLO_DSA_LE used for skew basis
|
||||
set dsas [get_ports {Tx_DSA*
|
||||
Rx_DSA*
|
||||
TxLO_DSA*
|
||||
LO_DSA*
|
||||
}]
|
||||
|
||||
# Just do false paths for gpios
|
||||
set_false_path -to $gpos
|
||||
set_false_path -from $gpis
|
||||
|
||||
# Unused
|
||||
set_false_path -to $lodist_spi_out
|
||||
|
||||
# DSA skew timing
|
||||
# Earlier, we created a "clock" for one of the DSA latch enable signals
|
||||
# Use set_output_delay to constrain skew around the latch enable
|
||||
# set_multicycle_path is used to make latch clock = launch clock for setup
|
||||
# Constrain skew to 8 ns -- controller nominally does 120 ns minimum between
|
||||
# edges, and 100 ns is the DSA's requirement for setup/hold
|
||||
set dsa_skew 8.0
|
||||
set_output_delay -clock dsa_clk -max -$dsa_skew $dsas
|
||||
set_output_delay -clock dsa_clk -min $dsa_skew $dsas
|
||||
set_multicycle_path -start -setup 0 -to $dsas
|
||||
|
||||
set_max_delay -from [get_ports CPLD_ATR_TX_18] \
|
||||
-to [get_ports {Tx_Sw1_Ctrl_1 Tx_Sw1_Ctrl_2}] 10.0
|
||||
|
||||
@@ -0,0 +1,605 @@
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright 2018 Ettus Research, A National Instruments Company
|
||||
//
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
//
|
||||
// Module: rhodium_top
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
`default_nettype none
|
||||
|
||||
module rhodium_top(
|
||||
|
||||
input [13:0] usrp_io, // bank 1A, 1B and 6
|
||||
|
||||
input ADC_A_Over_Range_18, input ADC_B_Over_Range_18, // bank 1A
|
||||
|
||||
// bank 6
|
||||
input CPLD_PS_SPI_LE_25,
|
||||
input CPLD_PS_SPI_CLK_25,
|
||||
input CPLD_PS_ADDR0_25,
|
||||
input CPLD_PS_ADDR1_25,
|
||||
input CPLD_PS_SPI_SDI_25,
|
||||
output reg CPLD_PS_SPI_SDO_25,
|
||||
output PHDAC_SPI_CS_L,
|
||||
output PHDAC_SPI_SCLK,
|
||||
output PHDAC_SPI_SDI,
|
||||
input LO_SYNC,
|
||||
|
||||
// bank 2
|
||||
output reg CPLD_PL_SPI_SDO_18,
|
||||
input CPLD_PL_SPI_LE_18,
|
||||
input CPLD_PL_SPI_SCLK_18,
|
||||
input CPLD_PL_SPI_SDI_18,
|
||||
input CPLD_PL_SPI_ADDR0_18,
|
||||
input CPLD_PL_SPI_ADDR1_18,
|
||||
input CPLD_PL_SPI_ADDR2_18,
|
||||
// NOTE: TxRx front-end switches are driven direct from the motherboard, so these ATR
|
||||
// lines have no function at this time.
|
||||
input CPLD_ATR_TX_18,
|
||||
input CPLD_ATR_RX_18,
|
||||
output ADC_SPI_CS_L_18,
|
||||
output ADC_SPI_SCLK_18,
|
||||
inout ADC_SPI_SDIO_18,
|
||||
output DAC_SPI_CS_L_18,
|
||||
output DAC_SPI_SCLK_18,
|
||||
inout DAC_SPI_SDIO_18,
|
||||
input DAC_Alarm_18, // TODO: drive to gpio?
|
||||
|
||||
// bank 3
|
||||
|
||||
output CLKDIST_SPI_CS_L,
|
||||
output CLKDIST_SPI_SCLK,
|
||||
inout CLKDIST_SPI_SDIO,
|
||||
output Tx_DSA_C1,
|
||||
output Tx_DSA_C2,
|
||||
output Tx_DSA_C4,
|
||||
output Tx_DSA_C8,
|
||||
output Tx_DSA_C16,
|
||||
output Tx_DSA1_LE,
|
||||
output Tx_DSA2_LE,
|
||||
output Tx_Sw1_Ctrl_1,
|
||||
output Tx_Sw1_Ctrl_2,
|
||||
output Tx_Sw2_Ctrl_1,
|
||||
output Tx_Sw2_Ctrl_2,
|
||||
output Tx_Sw3_Ctrl_1,
|
||||
output Tx_Sw3_Ctrl_2,
|
||||
output Tx_Sw3_Ctrl_3,
|
||||
output Tx_Sw3_Ctrl_4,
|
||||
output Rx_LO_Input_Select,
|
||||
output Rx_LO_Filter_Sw_1,
|
||||
output Rx_LO_Filter_Sw_2,
|
||||
output Tx_LO_Input_Select,
|
||||
output Tx_LO_Filter_Sw_1,
|
||||
output Tx_LO_Filter_Sw_2,
|
||||
input CLKDIST_Status_LD1,
|
||||
input CLKDIST_Status_LD2,
|
||||
input LOSYNTH_RX_MUXOUT,
|
||||
input LOSYNTH_TX_MUXOUT,
|
||||
|
||||
// bank 8
|
||||
output LO_SPI_SCLK, // fans out to both rx & tx synths
|
||||
output LO_SPI_SDI,
|
||||
output LO_TX_CS_L,
|
||||
output LO_RX_CS_L,
|
||||
output Rx_Sw1_Ctrl_1,
|
||||
output Rx_Sw1_Ctrl_2,
|
||||
output Rx_DSA_C1,
|
||||
output Rx_DSA_C2,
|
||||
output Rx_DSA_C4,
|
||||
output Rx_DSA_C8,
|
||||
output Rx_DSA_C16,
|
||||
output Rx_DSA1_LE,
|
||||
output Rx_DSA2_LE,
|
||||
output Rx_Sw2_Ctrl,
|
||||
output Rx_Sw3_Ctrl_1,
|
||||
output Rx_Sw3_Ctrl_2,
|
||||
output Rx_Sw4_Ctrl_1,
|
||||
output Rx_Sw4_Ctrl_2,
|
||||
output Rx_Sw4_Ctrl_3,
|
||||
output Rx_Sw4_Ctrl_4,
|
||||
output Rx_Demod_ADJ_1,
|
||||
output Rx_Demod_ADJ_2,
|
||||
|
||||
// bank 5
|
||||
output LO_DSA_C1,
|
||||
output LO_DSA_C2,
|
||||
output LO_DSA_C4,
|
||||
output LO_DSA_C8,
|
||||
output LO_DSA_C16,
|
||||
output RxLO_DSA_LE,
|
||||
output TxLO_DSA_LE,
|
||||
output LODIST_Bd_SPI_CS_L,
|
||||
output LODIST_Bd_SPI_SDI,
|
||||
output LODIST_Bd_SPI_SCLK,
|
||||
inout LODIST_Bd_IO1,
|
||||
output Tx_Sw5_Ctrl_1,
|
||||
output Tx_Sw5_Ctrl_2,
|
||||
output Rx_Sw6_Ctrl_1,
|
||||
output Rx_Sw6_Ctrl_2,
|
||||
|
||||
output Tx_HB_LB_Select,
|
||||
output Rx_HB_LB_Select,
|
||||
output Cal_iso_Sw_Ctrl
|
||||
|
||||
|
||||
);
|
||||
|
||||
/* PS SPI */
|
||||
|
||||
localparam GIT_HASH = 36'h`GIT_HASH;
|
||||
localparam PROD_SIGNATURE = 16'h0045; // Product signature (Rhodium atomic number in BCD)
|
||||
localparam REVISION_MINOR = 16'h0002;
|
||||
localparam REVISION_MAJOR = 16'h0004;
|
||||
localparam CPLD_BUILD_LSB = GIT_HASH[15:0]; // Build code LSB
|
||||
localparam CPLD_BUILD_MSB = GIT_HASH[31:16]; // Build code MSB
|
||||
localparam PSADDR_SIGNATURE = 3'd0;
|
||||
localparam PSADDR_REV_MINOR = 3'd1; // Minor version register
|
||||
localparam PSADDR_REV_MAJOR = 3'd2; // Major version register
|
||||
localparam PSADDR_BUILD_LSB = 3'd3;
|
||||
localparam PSADDR_BUILD_MSB = 3'd4;
|
||||
localparam PSADDR_SCRATCH = 3'd5; // scratchpad register
|
||||
localparam PSADDR_GAIN_SEL = 3'd6; // band select for gain table loader
|
||||
localparam PSADDR_DAC_ALARM = 3'd7; // DAC alarm pin register
|
||||
|
||||
// Sub-device selection for PS SPI
|
||||
localparam PS_CPLD_REGS = 2'b00;
|
||||
localparam GAIN_TABLE_RX = 2'b01;
|
||||
localparam GAIN_TABLE_TX = 2'b10;
|
||||
localparam GAIN_TABLE_LO = 2'b11;
|
||||
|
||||
// Setting to put TX SW1 in isolation mode
|
||||
localparam [1:0] TX_SW1_TERM = 2'b11;
|
||||
|
||||
wire clkdis_cs_b = CPLD_PS_SPI_LE_25;
|
||||
wire cpld_ps_cs_b = CPLD_PS_ADDR0_25;
|
||||
wire phdac_cs_b = CPLD_PS_ADDR1_25;
|
||||
wire adc_cs_b = usrp_io[12];
|
||||
wire dac_cs_b = usrp_io[13];
|
||||
|
||||
// CPLD PS SPI format (left-most bit first):
|
||||
// {table_sel[1:0], rsvd, reg_addr[3:0], rnw, data[15:0]}
|
||||
wire [1:0] cpld_ps_table_sel;
|
||||
wire [6:0] cpld_ps_spi_addr;
|
||||
wire cpld_ps_spi_rnw;
|
||||
reg [7:0] cpld_ps_spi_cmd;
|
||||
reg [15:0] cpld_ps_spi_rdata;
|
||||
reg [14:0] cpld_ps_spi_wdata;
|
||||
reg cpld_ps_spi_sdo;
|
||||
reg [4:0] cpld_ps_cnt;
|
||||
|
||||
assign {cpld_ps_spi_addr, cpld_ps_spi_rnw} = cpld_ps_spi_cmd;
|
||||
|
||||
// CPLD registers
|
||||
reg [15:0] spad;
|
||||
reg [15:0] gain_load_sel;
|
||||
|
||||
// Double sync. the DAC ALARM pin (async).
|
||||
reg dac_alarm_ms, dac_alarm = 0;
|
||||
always @(posedge CPLD_PS_SPI_CLK_25) begin
|
||||
{dac_alarm, dac_alarm_ms} <= {dac_alarm_ms, DAC_Alarm_18};
|
||||
end
|
||||
|
||||
wire rx_gain_load_tbl_sel;
|
||||
wire rx_gain_load_miso;
|
||||
wire rx_gain_ctrl_tbl_sel;
|
||||
wire rx_gain_ctrl_miso;
|
||||
wire tx_gain_load_tbl_sel;
|
||||
wire tx_gain_load_miso;
|
||||
wire tx_gain_ctrl_tbl_sel;
|
||||
wire tx_gain_ctrl_miso;
|
||||
wire lo_gain_ctrl_miso;
|
||||
|
||||
assign rx_gain_load_tbl_sel = gain_load_sel[0];
|
||||
assign tx_gain_load_tbl_sel = gain_load_sel[8];
|
||||
|
||||
always @(posedge CPLD_PS_SPI_CLK_25 or posedge cpld_ps_cs_b)
|
||||
begin
|
||||
if (cpld_ps_cs_b) begin
|
||||
cpld_ps_cnt <= 5'd0;
|
||||
end else if (!cpld_ps_cs_b) begin
|
||||
if (cpld_ps_cnt < 8) begin // Address / command
|
||||
cpld_ps_spi_cmd <= {cpld_ps_spi_cmd[6:0], CPLD_PS_SPI_SDI_25};
|
||||
cpld_ps_cnt <= cpld_ps_cnt + 5'd1;
|
||||
end else if (cpld_ps_cnt < 23) begin // Shift in write data
|
||||
cpld_ps_spi_wdata <= {cpld_ps_spi_wdata[13:0], CPLD_PS_SPI_SDI_25};
|
||||
cpld_ps_cnt <= cpld_ps_cnt + 5'd1;
|
||||
end else if (!cpld_ps_spi_rnw && cpld_ps_cnt == 23 && cpld_ps_spi_addr[6:5] == PS_CPLD_REGS) begin // Write
|
||||
case (cpld_ps_spi_addr[2:0])
|
||||
PSADDR_SIGNATURE: ;
|
||||
PSADDR_REV_MINOR: ;
|
||||
PSADDR_REV_MAJOR: ;
|
||||
PSADDR_BUILD_LSB: ;
|
||||
PSADDR_BUILD_MSB: ;
|
||||
PSADDR_SCRATCH: spad <= {cpld_ps_spi_wdata, CPLD_PS_SPI_SDI_25};
|
||||
PSADDR_GAIN_SEL: gain_load_sel <= {cpld_ps_spi_wdata, CPLD_PS_SPI_SDI_25};
|
||||
endcase
|
||||
end
|
||||
if (cpld_ps_cnt == 7) begin // Set up read one cycle earlier
|
||||
case (cpld_ps_spi_cmd[2:0])
|
||||
|
||||
PSADDR_SIGNATURE: cpld_ps_spi_rdata <= PROD_SIGNATURE;
|
||||
PSADDR_REV_MINOR: cpld_ps_spi_rdata <= REVISION_MINOR;
|
||||
PSADDR_REV_MAJOR: cpld_ps_spi_rdata <= REVISION_MAJOR;
|
||||
PSADDR_BUILD_LSB: cpld_ps_spi_rdata <= CPLD_BUILD_LSB;
|
||||
PSADDR_BUILD_MSB: cpld_ps_spi_rdata <= CPLD_BUILD_MSB;
|
||||
PSADDR_SCRATCH: cpld_ps_spi_rdata <= spad;
|
||||
PSADDR_GAIN_SEL: cpld_ps_spi_rdata <= gain_load_sel;
|
||||
PSADDR_DAC_ALARM: cpld_ps_spi_rdata <= {15'b0, dac_alarm};
|
||||
endcase
|
||||
end else begin
|
||||
cpld_ps_spi_rdata <= {cpld_ps_spi_rdata[14:0], 1'b1};
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(negedge CPLD_PS_SPI_CLK_25)
|
||||
begin
|
||||
cpld_ps_spi_sdo <= cpld_ps_spi_rdata[15]; // Shift out on negative edge
|
||||
end
|
||||
|
||||
// CLKDIST 3-wire to 4-wire
|
||||
reg [4:0] clkdis_cnt;
|
||||
reg clkdis_rd_pre, clkdis_rd, clkdis_sdio_t;
|
||||
|
||||
always @(posedge CPLD_PS_SPI_CLK_25 or posedge clkdis_cs_b)
|
||||
begin
|
||||
if (clkdis_cs_b) begin
|
||||
clkdis_cnt <= 5'd0;
|
||||
clkdis_rd <= 1'b0;
|
||||
clkdis_rd_pre <= 1'b0;
|
||||
end else if (!clkdis_cs_b) begin
|
||||
if (clkdis_cnt < 23)
|
||||
clkdis_cnt <= clkdis_cnt + 5'd1;
|
||||
|
||||
if (clkdis_cnt == 5'd0) // Check if read
|
||||
clkdis_rd_pre <= CPLD_PS_SPI_SDI_25;
|
||||
|
||||
if (clkdis_cnt == 5'd15)
|
||||
clkdis_rd <= clkdis_rd_pre;
|
||||
end
|
||||
end
|
||||
|
||||
always @(negedge CPLD_PS_SPI_CLK_25 or posedge clkdis_cs_b)
|
||||
begin
|
||||
if (clkdis_cs_b) begin
|
||||
clkdis_sdio_t <= 1'b0;
|
||||
end else begin
|
||||
clkdis_sdio_t <= clkdis_rd;
|
||||
end
|
||||
end
|
||||
|
||||
// ADC 3-wire to 4-wire
|
||||
reg [4:0] adc_cnt;
|
||||
reg adc_rd_pre, adc_rd, adc_sdio_t;
|
||||
|
||||
always @(posedge CPLD_PS_SPI_CLK_25 or posedge adc_cs_b)
|
||||
begin
|
||||
if (adc_cs_b) begin
|
||||
adc_cnt <= 5'd0;
|
||||
adc_rd <= 1'b0;
|
||||
adc_rd_pre <= 1'b0;
|
||||
end else if (!adc_cs_b) begin
|
||||
if (adc_cnt < 23)
|
||||
adc_cnt <= adc_cnt + 5'd1;
|
||||
|
||||
if (adc_cnt == 5'd0) // Check if read
|
||||
adc_rd_pre <= CPLD_PS_SPI_SDI_25;
|
||||
|
||||
if (adc_cnt == 5'd15)
|
||||
adc_rd <= adc_rd_pre;
|
||||
end
|
||||
end
|
||||
|
||||
always @(negedge CPLD_PS_SPI_CLK_25 or posedge adc_cs_b)
|
||||
begin
|
||||
if (adc_cs_b) begin
|
||||
adc_sdio_t <= 1'b0;
|
||||
end else begin
|
||||
adc_sdio_t <= adc_rd;
|
||||
end
|
||||
end
|
||||
|
||||
// DAC 3-wire to 4-wire
|
||||
reg [4:0] dac_cnt;
|
||||
reg dac_rd_pre, dac_rd, dac_sdio_t;
|
||||
|
||||
always @(posedge CPLD_PS_SPI_CLK_25 or posedge dac_cs_b)
|
||||
begin
|
||||
if (dac_cs_b) begin
|
||||
dac_cnt <= 5'd0;
|
||||
dac_rd <= 1'b0;
|
||||
dac_rd_pre <= 1'b0;
|
||||
end else if (!dac_cs_b) begin
|
||||
if (dac_cnt < 23)
|
||||
dac_cnt <= dac_cnt + 5'd1;
|
||||
|
||||
if (dac_cnt == 5'd0) // Check if read
|
||||
dac_rd_pre <= CPLD_PS_SPI_SDI_25;
|
||||
|
||||
if (dac_cnt == 5'd7)
|
||||
dac_rd <= dac_rd_pre;
|
||||
end
|
||||
end
|
||||
|
||||
always @(negedge CPLD_PS_SPI_CLK_25 or posedge dac_cs_b)
|
||||
begin
|
||||
if (dac_cs_b) begin
|
||||
dac_sdio_t <= 1'b0;
|
||||
end else begin
|
||||
dac_sdio_t <= dac_rd;
|
||||
end
|
||||
end
|
||||
|
||||
// multiplexed slave device SPI ports
|
||||
wire phdac_sck, phdac_sdi;
|
||||
wire clkdis_sck, adc_sck, dac_sck;
|
||||
assign clkdis_sck = (clkdis_cs_b == 1'b0) ? CPLD_PS_SPI_CLK_25 : 1'b0;
|
||||
|
||||
assign CLKDIST_SPI_CS_L = clkdis_cs_b;
|
||||
assign CLKDIST_SPI_SCLK = clkdis_sck;
|
||||
|
||||
assign adc_sck = !adc_cs_b ? CPLD_PS_SPI_CLK_25 : 1'b0;
|
||||
assign dac_sck = !dac_cs_b ? CPLD_PS_SPI_CLK_25 : 1'b0;
|
||||
|
||||
assign ADC_SPI_CS_L_18 = adc_cs_b;
|
||||
assign ADC_SPI_SCLK_18 = adc_sck;
|
||||
|
||||
assign DAC_SPI_CS_L_18 = dac_cs_b;
|
||||
assign DAC_SPI_SCLK_18 = dac_sck;
|
||||
|
||||
assign CLKDIST_SPI_SDIO = (!clkdis_sdio_t && !clkdis_cs_b) ? CPLD_PS_SPI_SDI_25 : 1'bz ;
|
||||
assign ADC_SPI_SDIO_18 = (!adc_sdio_t && !adc_cs_b) ? CPLD_PS_SPI_SDI_25 : 1'bz ;
|
||||
assign DAC_SPI_SDIO_18 = (!dac_sdio_t && !dac_cs_b) ? CPLD_PS_SPI_SDI_25 : 1'bz ;
|
||||
|
||||
always @(*)
|
||||
begin
|
||||
CPLD_PS_SPI_SDO_25 = 1'b1;
|
||||
case ({cpld_ps_cs_b, clkdis_cs_b, adc_cs_b, dac_cs_b})
|
||||
4'b0111: begin
|
||||
case (cpld_ps_spi_addr[6:5])
|
||||
PS_CPLD_REGS : CPLD_PS_SPI_SDO_25 = cpld_ps_spi_sdo;
|
||||
GAIN_TABLE_RX: CPLD_PS_SPI_SDO_25 = rx_gain_load_miso;
|
||||
GAIN_TABLE_TX: CPLD_PS_SPI_SDO_25 = tx_gain_load_miso;
|
||||
GAIN_TABLE_LO: CPLD_PS_SPI_SDO_25 = 1'b1;
|
||||
endcase
|
||||
end
|
||||
4'b1011: CPLD_PS_SPI_SDO_25 = CLKDIST_SPI_SDIO;
|
||||
4'b1101: CPLD_PS_SPI_SDO_25 = ADC_SPI_SDIO_18;
|
||||
4'b1110: CPLD_PS_SPI_SDO_25 = DAC_SPI_SDIO_18;
|
||||
default: ;
|
||||
endcase
|
||||
end
|
||||
|
||||
// note: no readback from PHDAC
|
||||
assign phdac_sck = (phdac_cs_b == 1'b0) ? CPLD_PS_SPI_CLK_25 : 1'b0;
|
||||
assign phdac_sdi = (phdac_cs_b == 1'b0) ? CPLD_PS_SPI_SDI_25 : 1'b1;
|
||||
|
||||
|
||||
assign PHDAC_SPI_SCLK = phdac_sck;
|
||||
assign PHDAC_SPI_CS_L = phdac_cs_b;
|
||||
assign PHDAC_SPI_SDI = phdac_sdi;
|
||||
|
||||
|
||||
/* PL SPI */
|
||||
// CPLD PL SPI format (left-most bit first):
|
||||
// {table_sel[1:0], reg_addr[4:0], rnw, data[15:0]}
|
||||
|
||||
//TXLO, RXLO, LODIS, CPLD
|
||||
localparam PLADDR_SCRATCH = 4'b0101; // scratchpad register
|
||||
localparam PLADDR_RXBS = 4'b0110;
|
||||
localparam PLADDR_TXBS = 4'b0111;
|
||||
localparam PLADDR_RFCTRL = 4'b1000;
|
||||
localparam PL_CPLD_REGS = 2'b00;
|
||||
|
||||
// CPLD PL registers
|
||||
reg [15:0] rxbs = 'h0;
|
||||
reg [15:0] txbs = 'h0;
|
||||
reg [15:0] rfctrl = 'h0;
|
||||
|
||||
// register address on the falling edge of chip-select
|
||||
wire txlo_cs_b = CPLD_PL_SPI_LE_18;
|
||||
wire rxlo_cs_b = CPLD_PL_SPI_ADDR1_18;
|
||||
wire lodis_cs_b = CPLD_PL_SPI_ADDR2_18;
|
||||
wire cpld_pl_cs_b = CPLD_PL_SPI_ADDR0_18;
|
||||
|
||||
wire cpld_pl_spi_rnw;
|
||||
wire [6:0] cpld_pl_spi_addr;
|
||||
reg [7:0] cpld_pl_spi_cmd;
|
||||
reg [15:0] cpld_pl_spi_rdata;
|
||||
reg [14:0] cpld_pl_spi_wdata;
|
||||
reg cpld_pl_spi_sdo;
|
||||
reg [4:0] cpld_pl_cnt;
|
||||
|
||||
assign {cpld_pl_spi_addr, cpld_pl_spi_rnw} = cpld_pl_spi_cmd;
|
||||
|
||||
reg [15:0] pl_spad;
|
||||
|
||||
always @(posedge CPLD_PL_SPI_SCLK_18 or posedge cpld_pl_cs_b)
|
||||
begin
|
||||
if (cpld_pl_cs_b) begin
|
||||
cpld_pl_cnt <= 5'd0;
|
||||
end else if (!cpld_pl_cs_b) begin
|
||||
if (cpld_pl_cnt < 8) begin // Address / command
|
||||
cpld_pl_spi_cmd <= {cpld_pl_spi_cmd[6:0], CPLD_PL_SPI_SDI_18};
|
||||
cpld_pl_cnt <= cpld_pl_cnt + 5'd1;
|
||||
end else if (cpld_pl_cnt < 23) begin // Shift in write data
|
||||
cpld_pl_spi_wdata <= {cpld_pl_spi_wdata[13:0], CPLD_PL_SPI_SDI_18};
|
||||
cpld_pl_cnt <= cpld_pl_cnt + 5'd1;
|
||||
end else if (!cpld_pl_spi_rnw && cpld_pl_cnt == 23 && cpld_pl_spi_addr[6:5] == PL_CPLD_REGS) begin // Write
|
||||
case (cpld_pl_spi_addr[3:0])
|
||||
PLADDR_SCRATCH: pl_spad <= {cpld_pl_spi_wdata, CPLD_PL_SPI_SDI_18};
|
||||
PLADDR_RXBS: rxbs <= {cpld_pl_spi_wdata, CPLD_PL_SPI_SDI_18};
|
||||
PLADDR_TXBS: txbs <= {cpld_pl_spi_wdata, CPLD_PL_SPI_SDI_18};
|
||||
PLADDR_RFCTRL: rfctrl <= {cpld_pl_spi_wdata, CPLD_PL_SPI_SDI_18};
|
||||
endcase
|
||||
end
|
||||
if (cpld_pl_cnt == 7) begin // Set up read one cycle earlier
|
||||
case (cpld_pl_spi_cmd[3:0])
|
||||
PLADDR_SCRATCH: cpld_pl_spi_rdata <= pl_spad;
|
||||
PLADDR_RXBS: cpld_pl_spi_rdata <= rxbs;
|
||||
PLADDR_TXBS: cpld_pl_spi_rdata <= txbs;
|
||||
PLADDR_RFCTRL: cpld_pl_spi_rdata <= rfctrl;
|
||||
endcase
|
||||
end else begin
|
||||
cpld_pl_spi_rdata <= {cpld_pl_spi_rdata[14:0], 1'b1};
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(negedge CPLD_PL_SPI_SCLK_18)
|
||||
begin
|
||||
cpld_pl_spi_sdo <= cpld_pl_spi_rdata[15]; // Shift out on negative edge
|
||||
end
|
||||
|
||||
// multiplexed slave device SPI ports, names aliased to protect the innocent
|
||||
wire lo_sck, lodis_sck;
|
||||
wire lo_sdi, lodis_sdi;
|
||||
// Note: lo_sck and lo_sdi -> fan out to both rxlo and txlo synths
|
||||
|
||||
assign { LO_TX_CS_L, LO_RX_CS_L } = { txlo_cs_b, rxlo_cs_b};
|
||||
assign LO_SPI_SCLK = lo_sck;
|
||||
assign LO_SPI_SDI = lo_sdi;
|
||||
|
||||
|
||||
assign LODIST_Bd_SPI_CS_L = lodis_cs_b;
|
||||
assign LODIST_Bd_SPI_SDI = lodis_sdi;
|
||||
assign LODIST_Bd_SPI_SCLK = lodis_sck;
|
||||
|
||||
|
||||
assign lodis_sck = !lodis_cs_b ? CPLD_PL_SPI_SCLK_18 : 1'b0;
|
||||
assign lodis_sdi = !lodis_cs_b ? CPLD_PL_SPI_SDI_18 : 1'b1;
|
||||
|
||||
assign { lo_sck, lo_sdi } = (!txlo_cs_b | !rxlo_cs_b) ? {CPLD_PL_SPI_SCLK_18,CPLD_PL_SPI_SDI_18} : 2'b01;
|
||||
|
||||
|
||||
always @(*)
|
||||
begin
|
||||
CPLD_PL_SPI_SDO_18 = 1'bz;
|
||||
case ({cpld_pl_cs_b, txlo_cs_b, rxlo_cs_b})
|
||||
3'b110: CPLD_PL_SPI_SDO_18 = LOSYNTH_RX_MUXOUT;
|
||||
3'b101: CPLD_PL_SPI_SDO_18 = LOSYNTH_TX_MUXOUT;
|
||||
3'b011: begin
|
||||
case (cpld_pl_spi_addr[6:5])
|
||||
PL_CPLD_REGS : CPLD_PL_SPI_SDO_18 = cpld_pl_spi_sdo;
|
||||
GAIN_TABLE_RX: CPLD_PL_SPI_SDO_18 = rx_gain_ctrl_miso;
|
||||
GAIN_TABLE_TX: CPLD_PL_SPI_SDO_18 = tx_gain_ctrl_miso;
|
||||
GAIN_TABLE_LO: CPLD_PL_SPI_SDO_18 = lo_gain_ctrl_miso;
|
||||
endcase
|
||||
end
|
||||
default: ;
|
||||
endcase
|
||||
end
|
||||
|
||||
assign rx_gain_ctrl_tbl_sel = rxbs[12];
|
||||
assign { Rx_Sw6_Ctrl_2,
|
||||
Rx_Sw6_Ctrl_1,
|
||||
Rx_Sw4_Ctrl_4,
|
||||
Rx_Sw4_Ctrl_3,
|
||||
Rx_Sw4_Ctrl_2,
|
||||
Rx_Sw4_Ctrl_1,
|
||||
Rx_Sw3_Ctrl_2,
|
||||
Rx_Sw3_Ctrl_1,
|
||||
Rx_Sw2_Ctrl,
|
||||
Rx_Sw1_Ctrl_2,
|
||||
Rx_Sw1_Ctrl_1 } = { rxbs[11:1] };
|
||||
|
||||
assign tx_gain_ctrl_tbl_sel = txbs[12];
|
||||
assign { Tx_Sw5_Ctrl_2,
|
||||
Tx_Sw5_Ctrl_1,
|
||||
Tx_Sw3_Ctrl_4,
|
||||
Tx_Sw3_Ctrl_3,
|
||||
Tx_Sw3_Ctrl_2,
|
||||
Tx_Sw3_Ctrl_1,
|
||||
Tx_Sw2_Ctrl_2,
|
||||
Tx_Sw2_Ctrl_1} = { txbs[11:4] };
|
||||
|
||||
// Terminate TX when idle
|
||||
assign {Tx_Sw1_Ctrl_2, Tx_Sw1_Ctrl_1} = CPLD_ATR_TX_18 ? txbs[3:2] : TX_SW1_TERM;
|
||||
|
||||
assign { Rx_LO_Filter_Sw_2,
|
||||
Rx_LO_Filter_Sw_1,
|
||||
Tx_LO_Filter_Sw_2,
|
||||
Tx_LO_Filter_Sw_1,
|
||||
Rx_Demod_ADJ_1,
|
||||
Rx_Demod_ADJ_2,
|
||||
Rx_LO_Input_Select } = rfctrl[15:9];
|
||||
|
||||
assign { Rx_HB_LB_Select,
|
||||
Tx_LO_Input_Select } = rfctrl[7:6];
|
||||
|
||||
assign { Tx_HB_LB_Select,
|
||||
Cal_iso_Sw_Ctrl }
|
||||
= { rfctrl[4:3] };
|
||||
|
||||
|
||||
// RX Gain Table
|
||||
wire [4:0] rx_dsa;
|
||||
|
||||
rhodium_gain_ctrl #(
|
||||
.TABLE_NUM(GAIN_TABLE_RX)
|
||||
) rx_gain_table (
|
||||
.load_table_sel(rx_gain_load_tbl_sel),
|
||||
.load_sck(CPLD_PS_SPI_CLK_25),
|
||||
.load_csb(cpld_ps_cs_b),
|
||||
.load_mosi(CPLD_PS_SPI_SDI_25),
|
||||
.load_miso(rx_gain_load_miso),
|
||||
.ctrl_table_sel(rx_gain_ctrl_tbl_sel),
|
||||
.ctrl_sck(CPLD_PL_SPI_SCLK_18),
|
||||
.ctrl_csb(cpld_pl_cs_b),
|
||||
.ctrl_mosi(CPLD_PL_SPI_SDI_18),
|
||||
.ctrl_miso(rx_gain_ctrl_miso),
|
||||
.dsa(rx_dsa),
|
||||
.dsa1_le(Rx_DSA1_LE),
|
||||
.dsa2_le(Rx_DSA2_LE)
|
||||
);
|
||||
|
||||
// TX Gain Table
|
||||
wire [4:0] tx_dsa;
|
||||
|
||||
rhodium_gain_ctrl #(
|
||||
.TABLE_NUM(GAIN_TABLE_TX)
|
||||
) tx_gain_table (
|
||||
.load_table_sel(tx_gain_load_tbl_sel),
|
||||
.load_sck(CPLD_PS_SPI_CLK_25),
|
||||
.load_csb(cpld_ps_cs_b),
|
||||
.load_mosi(CPLD_PS_SPI_SDI_25),
|
||||
.load_miso(tx_gain_load_miso),
|
||||
.ctrl_table_sel(tx_gain_ctrl_tbl_sel),
|
||||
.ctrl_sck(CPLD_PL_SPI_SCLK_18),
|
||||
.ctrl_csb(cpld_pl_cs_b),
|
||||
.ctrl_mosi(CPLD_PL_SPI_SDI_18),
|
||||
.ctrl_miso(tx_gain_ctrl_miso),
|
||||
.dsa(tx_dsa),
|
||||
.dsa1_le(Tx_DSA1_LE),
|
||||
.dsa2_le(Tx_DSA2_LE)
|
||||
);
|
||||
|
||||
// LO Gain Table
|
||||
wire [4:0] lo_dsa;
|
||||
|
||||
rhodium_lo_gain #(
|
||||
.TABLE_NUM(GAIN_TABLE_LO)
|
||||
) lo_gain_table (
|
||||
.ctrl_sck(CPLD_PL_SPI_SCLK_18),
|
||||
.ctrl_csb(cpld_pl_cs_b),
|
||||
.ctrl_mosi(CPLD_PL_SPI_SDI_18),
|
||||
.ctrl_miso(lo_gain_ctrl_miso),
|
||||
.dsa(lo_dsa),
|
||||
.dsa1_le(RxLO_DSA_LE),
|
||||
.dsa2_le(TxLO_DSA_LE)
|
||||
);
|
||||
|
||||
// Rx data shared by DSA1, DSA2
|
||||
assign { Rx_DSA_C16, Rx_DSA_C8, Rx_DSA_C4, Rx_DSA_C2, Rx_DSA_C1 } = rx_dsa;
|
||||
|
||||
// Tx data shared by DSA1, DSA2
|
||||
assign { Tx_DSA_C16, Tx_DSA_C8, Tx_DSA_C4, Tx_DSA_C2, Tx_DSA_C1 } = tx_dsa;
|
||||
|
||||
// data shared by both tx and rx lo DSAs
|
||||
assign { LO_DSA_C16, LO_DSA_C8, LO_DSA_C4, LO_DSA_C2, LO_DSA_C1 } = lo_dsa;
|
||||
|
||||
endmodule
|
||||
`default_nettype wire
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
#
|
||||
# Copyright 2017 Ettus Research, A National Instruments Company
|
||||
# SPDX-License-Identifier: LGPL-3.0
|
||||
#
|
||||
# Timing analysis is performed in "usrp3/top/n3xx/dboards/rh/doc/rh_timing.xlsx".
|
||||
# See this spreadsheet for more details and explanations.
|
||||
|
||||
#*******************************************************************************
|
||||
## Daughterboard Clocks
|
||||
#
|
||||
# 122.88, 200, 245.76 and 250 MHz Sample Rates are allowable with 2:1/1:2 DSP and
|
||||
# 2 samples/cycle arriving at the FPGA:
|
||||
#
|
||||
# <-- 2:1/1:2 -->
|
||||
# | Supported | Sample rate | FPGA Clk |
|
||||
# |sample rates | at JESD core | Frequency |
|
||||
# | (MSPS) | (MSPS) | (MHz) |
|
||||
# |-------------|--------------|-----------|
|
||||
# | 122.88 | 491.52 | 245.76 | (uses DUC/DDC)
|
||||
# | 200.00 | 400.00 | 200.00 |
|
||||
# | 245.76 | 491.52 | 245.76 |
|
||||
# | 250.00 | 500.00 | 250.00 |
|
||||
#
|
||||
# Therefore, supported sample clocks are: 122.88, 200, 245.76 and 250 MHz.
|
||||
# Constrain the paths to the max rate to support all rates in a single FPGA image.
|
||||
set SAMPLE_CLK_PERIOD 4.00
|
||||
create_clock -name fpga_clk_a -period $SAMPLE_CLK_PERIOD [get_ports DBA_FPGA_CLK_P]
|
||||
create_clock -name fpga_clk_b -period $SAMPLE_CLK_PERIOD [get_ports DBB_FPGA_CLK_P]
|
||||
create_clock -name mgt_clk_dba -period $SAMPLE_CLK_PERIOD [get_ports DBA_MGTCLK_P]
|
||||
create_clock -name mgt_clk_dbb -period $SAMPLE_CLK_PERIOD [get_ports DBB_MGTCLK_P]
|
||||
|
||||
# The Radio Clocks coming from the DBs are synchronized together (at the converters) to
|
||||
# a typical value of less than 100ps. To give ourselves and Vivado some margin, we claim
|
||||
# here that the DB-B Radio Clock can arrive 500ps before or after the DB-A clock at
|
||||
# the FPGA (note that the trace lengths of the Radio Clocks coming from the DBs to the
|
||||
# FPGA are about 0.5" different, thereby incurring ~80ps of additional skew at the FPGA).
|
||||
# There is one spot in the FPGA where we cross domains between the DB-A and
|
||||
# DB-B clock, so we must ensure that Vivado can analyze that path safely.
|
||||
set FPGA_CLK_EARLY -0.5
|
||||
set FPGA_CLK_LATE 0.5
|
||||
set_clock_latency -source -early $FPGA_CLK_EARLY [get_clocks fpga_clk_b]
|
||||
set_clock_latency -source -late $FPGA_CLK_LATE [get_clocks fpga_clk_b]
|
||||
|
||||
# Virtual clocks for constraining I/O (used below)
|
||||
create_clock -name fpga_clk_a_v -period $SAMPLE_CLK_PERIOD
|
||||
create_clock -name fpga_clk_b_v -period $SAMPLE_CLK_PERIOD
|
||||
|
||||
# The set_clock_latency constraints set on fpga_clk_b are problematic when used with
|
||||
# I/O timing, since the analyzer gives us a double-hit on the latency. One workaround
|
||||
# (used here) is to simply swap the early and late times for the virtual clock so that
|
||||
# it cancels out the source latency during analysis. D. Jepson tested this by setting
|
||||
# the early and late numbers to zero and then their actual value, running timing reports
|
||||
# on each. The slack report matches for both cases, showing that the reversed early/late
|
||||
# numbers on the virtual clock zero out the latency effects on the actual clock.
|
||||
#
|
||||
# Note this is not a problem for the fpga_clk_a, since no latency is added. So only apply
|
||||
# it to fpga_clk_b_v.
|
||||
set_clock_latency -source -early $FPGA_CLK_LATE [get_clocks fpga_clk_b_v]
|
||||
set_clock_latency -source -late $FPGA_CLK_EARLY [get_clocks fpga_clk_b_v]
|
||||
|
||||
|
||||
|
||||
#*******************************************************************************
|
||||
## Aliases for auto-generated clocks
|
||||
|
||||
create_generated_clock -name radio_clk_fb [get_pins {dba_core/RadioClockingx/RadioClkMmcm/CLKFBOUT}]
|
||||
create_generated_clock -name radio_clk [get_pins {dba_core/RadioClockingx/RadioClkMmcm/CLKOUT0}]
|
||||
create_generated_clock -name radio_clk_2x [get_pins {dba_core/RadioClockingx/RadioClkMmcm/CLKOUT1}]
|
||||
|
||||
create_generated_clock -name radio_clk_b_fb [get_pins {dbb_core/RadioClockingx/RadioClkMmcm/CLKFBOUT}]
|
||||
create_generated_clock -name radio_clk_b [get_pins {dbb_core/RadioClockingx/RadioClkMmcm/CLKOUT0}]
|
||||
create_generated_clock -name radio_clk_b_2x [get_pins {dbb_core/RadioClockingx/RadioClkMmcm/CLKOUT1}]
|
||||
|
||||
|
||||
|
||||
#*******************************************************************************
|
||||
## Generated clocks for output busses to the daughterboard
|
||||
#
|
||||
# These clock definitions need to come above the set_clock_groups commands below to work!
|
||||
|
||||
# Define clocks on the PL SPI clock output pins for both DBs. Actual divider values are
|
||||
# set by SW at run-time. Current divider value is 125 based on what radio clock
|
||||
# rate is set.
|
||||
# For the CPLD SPI endpoint alone, we need it to run at ~25 MHz (writes only), this means
|
||||
# that at times, the PL SPI will have its divider set to 10 (radio_clock = 250 MHz) or 8
|
||||
# (radio_clock = 200 MHz).
|
||||
# The readback clock is lower (~10 MHz), so create a separate clock for it.
|
||||
# Use readback divide value of 24 for an even divider (and some overconstraining).
|
||||
set PL_SPI_DIVIDE_VAL 10
|
||||
set PL_SPI_RB_DIVIDE_VAL 24
|
||||
set PL_SPI_CLK_A [get_ports DBA_CPLD_PL_SPI_SCLK]
|
||||
create_generated_clock -name pl_spi_clk_a \
|
||||
-source [get_pins [all_fanin -flat -only_cells -startpoints_only $PL_SPI_CLK_A]/C] \
|
||||
-divide_by $PL_SPI_DIVIDE_VAL $PL_SPI_CLK_A
|
||||
create_generated_clock -name pl_spi_rb_clk_a \
|
||||
-master_clock [get_clocks radio_clk] \
|
||||
-source [get_pins [all_fanin -flat -only_cells -startpoints_only $PL_SPI_CLK_A]/C] \
|
||||
-divide_by $PL_SPI_RB_DIVIDE_VAL -add $PL_SPI_CLK_A
|
||||
set PL_SPI_CLK_B [get_ports DBB_CPLD_PL_SPI_SCLK]
|
||||
create_generated_clock -name pl_spi_clk_b \
|
||||
-source [get_pins [all_fanin -flat -only_cells -startpoints_only $PL_SPI_CLK_B]/C] \
|
||||
-divide_by $PL_SPI_DIVIDE_VAL $PL_SPI_CLK_B
|
||||
create_generated_clock -name pl_spi_rb_clk_b \
|
||||
-master_clock [get_clocks radio_clk] \
|
||||
-source [get_pins [all_fanin -flat -only_cells -startpoints_only $PL_SPI_CLK_B]/C] \
|
||||
-divide_by $PL_SPI_RB_DIVIDE_VAL -add $PL_SPI_CLK_B
|
||||
|
||||
#*******************************************************************************
|
||||
## JTAG
|
||||
set DB_JTAG_DIVISOR 4
|
||||
create_generated_clock -name dba_jtag_tck -divide_by $DB_JTAG_DIVISOR \
|
||||
-source [get_pins {inst_n310_ps/jtag_0/U0/bitq_ctrl/bitq_state_reg[1]/C}] \
|
||||
[get_ports DBA_CPLD_JTAG_TCK]
|
||||
|
||||
create_generated_clock -name dbb_jtag_tck -divide_by $DB_JTAG_DIVISOR \
|
||||
-source [get_pins {inst_n310_ps/jtag_1/U0/bitq_ctrl/bitq_state_reg[1]/C}] \
|
||||
[get_ports DBB_CPLD_JTAG_TCK]
|
||||
|
||||
@@ -0,0 +1,345 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- File: ClockingRegs.vhd
|
||||
-- Author: Daniel Jepson; mods by Humberto Jimenez
|
||||
-- Original Project: N310; N32x
|
||||
-- Date: 17 March 2016
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
-- Copyright 2016-2018 Ettus Research, A National Instruments Company
|
||||
-- SPDX-License-Identifier: LGPL-3.0
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Purpose:
|
||||
--
|
||||
-- Register access to the control/status bits and interfaces for the
|
||||
-- RadioClocking module.
|
||||
--
|
||||
-- XML register definition is included below the module.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
library work;
|
||||
use work.PkgClockingRegMap.all;
|
||||
use work.PkgRegs.all;
|
||||
|
||||
|
||||
entity ClockingRegs is
|
||||
port(
|
||||
-- Async reset. Can be tied low if desired.
|
||||
aReset : in boolean;
|
||||
-- Sync reset... used in the same places as the async one.
|
||||
bReset : in boolean;
|
||||
-- Register Bus Clock -- this module connects the BusClk to PsClk, so it's limited
|
||||
-- to 200 MHz!
|
||||
BusClk : in std_logic;
|
||||
|
||||
bRegPortOut : out RegPortOut_t;
|
||||
bRegPortIn : in RegPortIn_t;
|
||||
|
||||
-- Phase shift interface to the RadioClkMmcm.
|
||||
-- There is a reset crossing here between the MMCM reset and aReset. The outgoing
|
||||
-- crossing is safe because (a) the enable signal driven to the MMCM is a strobe-only
|
||||
-- signal and (b) this interface should only be used when the MMCM is not in reset
|
||||
-- (SW waits for the MMCM to be out of reset and locked before using this interface).
|
||||
-- The only input signal, pPsDone, is double-synced in this file before being used.
|
||||
-- This is OK (even though it is a strobe signal) because there is only a reset
|
||||
-- crossing and not a clock domain crossing.
|
||||
pPsInc : out std_logic;
|
||||
pPsEn : out std_logic;
|
||||
pPsDone : in std_logic;
|
||||
|
||||
-- PsClk is driven directly by BusClk, so p = b in the logic below!
|
||||
PsClk : out std_logic;
|
||||
|
||||
-- Sync reset strobes from the register bus to the RadioClkMmcm.
|
||||
bRadioClkMmcmReset : out std_logic;
|
||||
-- Status of RadioClk MMCM lock to register bus.
|
||||
aRadioClksValid : in std_logic;
|
||||
|
||||
bRadioClk1xEnabled : out std_logic;
|
||||
bRadioClk2xEnabled : out std_logic;
|
||||
bRadioClk3xEnabled : out std_logic;
|
||||
|
||||
bJesdRefClkPresent : in std_logic
|
||||
);
|
||||
end ClockingRegs;
|
||||
|
||||
|
||||
architecture RTL of ClockingRegs is
|
||||
|
||||
--vhook_sigstart
|
||||
--vhook_sigend
|
||||
|
||||
signal bRadioClkMmcmResetInt : std_logic := '1';
|
||||
|
||||
signal bRegPortOutLcl : RegPortOut_t := kRegPortOutZero;
|
||||
|
||||
signal bPsDone,
|
||||
bPsEn,
|
||||
bPsInc,
|
||||
pPsDoneDs_ms,
|
||||
pPsDoneDs : std_logic := '0';
|
||||
|
||||
signal bRadioClk1xEnabledInt,
|
||||
bRadioClk2xEnabledInt,
|
||||
bRadioClk3xEnabledInt,
|
||||
bRadioClksValid_ms,
|
||||
bRadioClksValid : std_logic := '0';
|
||||
|
||||
attribute ASYNC_REG : string;
|
||||
attribute ASYNC_REG of bRadioClksValid_ms : signal is "true";
|
||||
attribute ASYNC_REG of bRadioClksValid : signal is "true";
|
||||
attribute ASYNC_REG of pPsDoneDs_ms : signal is "true";
|
||||
attribute ASYNC_REG of pPsDoneDs : signal is "true";
|
||||
|
||||
begin
|
||||
|
||||
-- Locals to outputs.
|
||||
PsClk <= BusClk;
|
||||
pPsInc <= bPsInc;
|
||||
pPsEn <= bPsEn;
|
||||
|
||||
bRadioClkMmcmReset <= bRadioClkMmcmResetInt;
|
||||
|
||||
bRadioClk1xEnabled <= bRadioClk1xEnabledInt;
|
||||
bRadioClk2xEnabled <= bRadioClk2xEnabledInt;
|
||||
bRadioClk3xEnabled <= bRadioClk3xEnabledInt;
|
||||
|
||||
|
||||
-- Write Registers : ------------------------------------------------------------------
|
||||
-- ------------------------------------------------------------------------------------
|
||||
WriteRegisters: process(aReset, BusClk)
|
||||
begin
|
||||
if aReset then
|
||||
bRadioClkMmcmResetInt <= '1';
|
||||
bPsInc <= '0';
|
||||
bPsEn <= '0';
|
||||
bRadioClk1xEnabledInt <= '0';
|
||||
bRadioClk2xEnabledInt <= '0';
|
||||
bRadioClk3xEnabledInt <= '0';
|
||||
elsif rising_edge(BusClk) then
|
||||
|
||||
if bReset then
|
||||
bRadioClkMmcmResetInt <= '1';
|
||||
bPsInc <= '0';
|
||||
bPsEn <= '0';
|
||||
bRadioClk1xEnabledInt <= '0';
|
||||
bRadioClk2xEnabledInt <= '0';
|
||||
bRadioClk3xEnabledInt <= '0';
|
||||
else
|
||||
-- Clear strobe
|
||||
bPsEn <= '0';
|
||||
|
||||
if RegWrite(kPhaseShiftControl, bRegPortIn) then
|
||||
if bRegPortIn.Data(kPsInc) = '1' then
|
||||
bPsInc <= '1';
|
||||
bPsEn <= '1';
|
||||
elsif bRegPortIn.Data(kPsDec) = '1' then
|
||||
bPsInc <= '0';
|
||||
bPsEn <= '1';
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if RegWrite(kRadioClkMmcm, bRegPortIn) then
|
||||
-- Set/Clear pair
|
||||
if bRegPortIn.Data(kRadioClkMmcmResetSet) = '1' then
|
||||
bRadioClkMmcmResetInt <= '1';
|
||||
elsif bRegPortIn.Data(kRadioClkMmcmResetClear) = '1' then
|
||||
bRadioClkMmcmResetInt <= '0';
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if RegWrite(kRadioClkEnables, bRegPortIn) then
|
||||
bRadioClk1xEnabledInt <= bRegPortIn.Data(kRadioClk1xEnabled);
|
||||
bRadioClk2xEnabledInt <= bRegPortIn.Data(kRadioClk2xEnabled);
|
||||
bRadioClk3xEnabledInt <= bRegPortIn.Data(kRadioClk3xEnabled);
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end process WriteRegisters;
|
||||
|
||||
|
||||
DoubleSyncs : process (aReset, BusClk)
|
||||
begin
|
||||
if aReset then
|
||||
bRadioClksValid_ms <= '0';
|
||||
bRadioClksValid <= '0';
|
||||
pPsDoneDs_ms <= '0';
|
||||
pPsDoneDs <= '0';
|
||||
elsif rising_edge(BusClk) then
|
||||
-- No sync reset on double-syncs (however there are default assignments above)!
|
||||
bRadioClksValid_ms <= aRadioClksValid;
|
||||
bRadioClksValid <= bRadioClksValid_ms;
|
||||
pPsDoneDs_ms <= pPsDone;
|
||||
pPsDoneDs <= pPsDoneDs_ms;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
-- Read Registers : -------------------------------------------------------------------
|
||||
-- ------------------------------------------------------------------------------------
|
||||
ReadRegisters: process(aReset, BusClk)
|
||||
begin
|
||||
if aReset then
|
||||
bRegPortOutLcl <= kRegPortOutZero;
|
||||
bPsDone <= '0';
|
||||
elsif rising_edge(BusClk) then
|
||||
|
||||
if bReset then
|
||||
bRegPortOutLcl <= kRegPortOutZero;
|
||||
bPsDone <= '0';
|
||||
else
|
||||
-- Deassert strobes
|
||||
bRegPortOutLcl.Data <= kRegPortDataZero;
|
||||
|
||||
-- All of these transactions only take one clock cycle, so we do not have to
|
||||
-- de-assert the Ready signal (ever).
|
||||
bRegPortOutLcl.Ready <= true;
|
||||
|
||||
-- Process the returned data from the phase shifter in the MMCM. Note that even
|
||||
-- though the prefixes are different (p and b), we drive the PsClk from the BusClk
|
||||
-- so this "crossing" is actually safe. Whenever the Done signal asserts (pPsDone -
|
||||
-- pay attention to the prefix!) from the MMCM, we set a sticky bit to tell SW
|
||||
-- that the shift operation is complete.
|
||||
--
|
||||
-- However, if pPsDone asserts at the same time that SW tries to read the register,
|
||||
-- we should accurately report that the operation is indeed complete and then NOT
|
||||
-- store the sticky (since it has already been read by SW). If a read does not come
|
||||
-- through at the same time pPsDone is asserted, then we store the done state as a
|
||||
-- sticky, bPsDone, which is only cleared by a read to this register.
|
||||
if RegRead(kPhaseShiftControl, bRegPortIn) then
|
||||
-- The phase shift is always enabled for the feedback clock in RadioClocking.vhd
|
||||
bRegPortOutLcl.Data(kPsEnabledForFdbClk) <= '1';
|
||||
bRegPortOutLcl.Data(kPsDone) <= bPsDone or pPsDoneDs;
|
||||
bPsDone <= '0';
|
||||
elsif pPsDoneDs = '1' then
|
||||
bPsDone <= '1';
|
||||
end if;
|
||||
|
||||
if RegRead(kRadioClkMmcm, bRegPortIn) then
|
||||
bRegPortOutLcl.Data(kRadioClkMmcmLocked) <= bRadioClksValid;
|
||||
end if;
|
||||
|
||||
if RegRead(kRadioClkEnables, bRegPortIn) then
|
||||
bRegPortOutLcl.Data(kRadioClk1xEnabled) <= bRadioClk1xEnabledInt;
|
||||
bRegPortOutLcl.Data(kRadioClk2xEnabled) <= bRadioClk2xEnabledInt;
|
||||
bRegPortOutLcl.Data(kRadioClk3xEnabled) <= bRadioClk3xEnabledInt;
|
||||
end if;
|
||||
|
||||
if RegRead(kMgtRefClkStatus, bRegPortIn) then
|
||||
bRegPortOutLcl.Data(kJesdRefClkPresent) <= bJesdRefClkPresent;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end process ReadRegisters;
|
||||
|
||||
-- Local to output
|
||||
bRegPortOut <= bRegPortOutLcl;
|
||||
|
||||
|
||||
end RTL;
|
||||
|
||||
|
||||
--XmlParse xml_on
|
||||
--<regmap name="ClockingRegMap">
|
||||
-- <group name="ClockingRegs">
|
||||
--
|
||||
-- <register name="RadioClkMmcm" size="32" offset="0x20" attributes="Readable|Writable">
|
||||
-- <info>
|
||||
-- </info>
|
||||
-- <bitfield name="RadioClkMmcmLocked" range="4">
|
||||
-- <info>
|
||||
-- Reflects the locked status of the MMCM. '1' = locked. This bit is only valid
|
||||
-- when the MMCM reset is de-asserted. Read-only.
|
||||
-- </info>
|
||||
-- </bitfield>
|
||||
-- <bitfield name="RadioClkMmcmResetClear" range="1" attributes="Strobe">
|
||||
-- <info>
|
||||
-- Controls the reset to the Radio Clock MMCM. Strobe this bit to de-assert the
|
||||
-- reset to the MMCM. Default is reset asserted. Write-only.
|
||||
-- </info>
|
||||
-- </bitfield>
|
||||
-- <bitfield name="RadioClkMmcmResetSet" range="0" attributes="Strobe">
|
||||
-- <info>
|
||||
-- Controls the reset to the Radio Clock MMCM. Strobe this bit to assert the
|
||||
-- reset to the MMCM. Default is reset asserted. Write-only.
|
||||
-- </info>
|
||||
-- </bitfield>
|
||||
-- </register>
|
||||
--
|
||||
-- <register name="PhaseShiftControl" size="32" offset="0x24" attributes="Readable|Writable">
|
||||
-- <info>
|
||||
-- Phase Shift for RadioClkMmcm.
|
||||
-- </info>
|
||||
-- <bitfield name="PsDone" range="28">
|
||||
-- <info>
|
||||
-- This bit should set after a shift operation successfully completes.
|
||||
-- Reading this register will clear this bit. Read-only.
|
||||
-- </info>
|
||||
-- </bitfield>
|
||||
-- <bitfield name="PsInc" range="0" attributes="Strobe">
|
||||
-- <info>
|
||||
-- Strobe this bit to increment the phase. This bit is self-clearing and will
|
||||
-- always return '0' when read. If PsInc and PsDec are asserted together,
|
||||
-- the phase will increment.
|
||||
-- </info>
|
||||
-- </bitfield>
|
||||
-- <bitfield name="PsDec" range="4" attributes="Strobe">
|
||||
-- <info>
|
||||
-- Strobe this bit to decrement the phase. This bit is self-clearing and will
|
||||
-- always return '0' when read. If PsInc and PsDec are asserted together,
|
||||
-- the phase will increment.
|
||||
-- </info>
|
||||
-- </bitfield>
|
||||
-- <bitfield name="PsEnabledForFdbClk" range="16">
|
||||
-- <info>
|
||||
-- Read-only.
|
||||
-- </info>
|
||||
-- </bitfield>
|
||||
-- </register>
|
||||
--
|
||||
-- <register name="RadioClkEnables" size="32" offset="0x28" attributes="Readable|Writable">
|
||||
-- <info>
|
||||
-- </info>
|
||||
-- <bitfield name="RadioClk3xEnabled" range="8">
|
||||
-- <info>
|
||||
-- Set to '1' to enable the clock. Default disabled = '0'.
|
||||
-- Do so ONLY after the MMCM is out of reset and locked!
|
||||
-- </info>
|
||||
-- </bitfield>
|
||||
-- <bitfield name="RadioClk2xEnabled" range="4">
|
||||
-- <info>
|
||||
-- Set to '1' to enable the clock. Default disabled = '0'.
|
||||
-- Do so ONLY after the MMCM is out of reset and locked!
|
||||
-- </info>
|
||||
-- </bitfield>
|
||||
-- <bitfield name="RadioClk1xEnabled" range="0">
|
||||
-- <info>
|
||||
-- Set to '1' to enable the clock. Default disabled = '0'.
|
||||
-- Do so ONLY after the MMCM is out of reset and locked!
|
||||
-- </info>
|
||||
-- </bitfield>
|
||||
-- </register>
|
||||
--
|
||||
-- <register name="MgtRefClkStatus" size="32" offset="0x30" attributes="Readable">
|
||||
-- <info>
|
||||
-- </info>
|
||||
-- <bitfield name="JesdRefClkPresent" range="0">
|
||||
-- <info>
|
||||
-- Live indicator of the MGT Reference Clock toggling and within expected
|
||||
-- frequency limits. If this bit is de-asserted, then the JESD204b core will
|
||||
-- not function correctly!
|
||||
-- </info>
|
||||
-- </bitfield>
|
||||
-- </register>
|
||||
--
|
||||
-- </group>
|
||||
--
|
||||
--</regmap>
|
||||
--XmlParse xml_off
|
||||
@@ -0,0 +1,116 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- File: DaughterboardRegs.vhd
|
||||
-- Author: Daniel Jepson; mods by Humberto Jimenez
|
||||
-- Original Project: N310; N32x
|
||||
-- Date: 27 April 2016
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
-- Copyright 2016-2018 Ettus Research, A National Instruments Company
|
||||
-- SPDX-License-Identifier: LGPL-3.0
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Purpose:
|
||||
--
|
||||
-- Register interface to the semi-static control lines for the Mg
|
||||
-- Daughterboard.
|
||||
--
|
||||
-- XML register definition is included below the module.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
library work;
|
||||
use work.PkgDaughterboardRegMap.all;
|
||||
use work.PkgRegs.all;
|
||||
|
||||
|
||||
entity DaughterboardRegs is
|
||||
port(
|
||||
-- Async reset. Can be tied low if desired.
|
||||
aReset : in boolean;
|
||||
-- Sync reset... used in the same places as the async one.
|
||||
bReset : in boolean;
|
||||
BusClk : in std_logic;
|
||||
|
||||
bRegPortOut : out RegPortOut_t;
|
||||
bRegPortIn : in RegPortIn_t;
|
||||
|
||||
-- Slot and DB ID values. These should be tied to constants!
|
||||
kDbId : in std_logic_vector(15 downto 0);
|
||||
kSlotId : in std_logic
|
||||
|
||||
);
|
||||
end DaughterboardRegs;
|
||||
|
||||
|
||||
architecture RTL of DaughterboardRegs is
|
||||
|
||||
--vhook_sigstart
|
||||
--vhook_sigend
|
||||
|
||||
signal bRegPortOutLcl : RegPortOut_t := kRegPortOutZero;
|
||||
|
||||
begin
|
||||
|
||||
|
||||
-- Read Registers : -------------------------------------------------------------------
|
||||
-- ------------------------------------------------------------------------------------
|
||||
ReadRegisters: process(aReset, BusClk)
|
||||
begin
|
||||
if aReset then
|
||||
bRegPortOutLcl <= kRegPortOutZero;
|
||||
elsif rising_edge(BusClk) then
|
||||
if bReset then
|
||||
bRegPortOutLcl <= kRegPortOutZero;
|
||||
else
|
||||
-- De-assert strobes
|
||||
bRegPortOutLcl.Data <= kRegPortDataZero;
|
||||
|
||||
-- All of these transactions only take one clock cycle, so we do not have to
|
||||
-- de-assert the Ready signal (ever).
|
||||
bRegPortOutLcl.Ready <= true;
|
||||
|
||||
if RegRead(kDaughterboardId, bRegPortIn) then
|
||||
bRegPortOutLcl.Data(kDbIdValMsb downto kDbIdVal) <= kDbId;
|
||||
bRegPortOutLcl.Data(kSlotIdVal) <= kSlotId;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end if;
|
||||
end process ReadRegisters;
|
||||
|
||||
-- Local to output
|
||||
bRegPortOut <= bRegPortOutLcl;
|
||||
|
||||
|
||||
end RTL;
|
||||
|
||||
|
||||
--XmlParse xml_on
|
||||
--<regmap name="DaughterboardRegMap">
|
||||
-- <group name="StaticControl" order="1">
|
||||
--
|
||||
-- <register name="DaughterboardId" size="32" offset="0x30" attributes="Readable">
|
||||
-- <info>
|
||||
-- </info>
|
||||
-- <bitfield name="DbIdVal" range="15..0">
|
||||
-- <info>
|
||||
-- ID for the DB with which this file is designed to communicate. Matches the DB
|
||||
-- EEPROM ID.
|
||||
-- </info>
|
||||
-- </bitfield>
|
||||
-- <bitfield name="SlotIdVal" range="16">
|
||||
-- <info>
|
||||
-- ID for the Slot this module controls. Options are 0 and 1 for the N310 MB.
|
||||
-- </info>
|
||||
-- </bitfield>
|
||||
-- </register>
|
||||
--
|
||||
-- </group>
|
||||
--
|
||||
--
|
||||
--</regmap>
|
||||
--XmlParse xml_off
|
||||
@@ -0,0 +1,563 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- File: DbCore.vhd
|
||||
-- Author: Daniel Jepson; mods by Humberto Jimenez
|
||||
-- Original Project: N310; N320
|
||||
-- Date: 12 April 2017
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
-- Copyright 2017-2018 Ettus Research, A National Instruments Company
|
||||
-- SPDX-License-Identifier: LGPL-3.0
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Purpose:
|
||||
--
|
||||
-- Wrapper file for Daughterboard Control. This includes the semi-static control
|
||||
-- and status registers, clocking, synchronization, and JESD204B cores.
|
||||
--
|
||||
-- There is no version register for the plain-text files here.
|
||||
-- Version control for the Sync and JESD204B cores is internal to the netlists.
|
||||
--
|
||||
-- The resets for this core are almost entirely local and/or synchronous.
|
||||
-- bBusReset is a Synchronous reset on the BusClk domain that resets all of the
|
||||
-- registers connected to the RegPort, as well as any other stray registers
|
||||
-- connected to the BusClk. All other resets are local to the modules they touch.
|
||||
-- No other reset drives all modules universally.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.PkgRhPersonality.all;
|
||||
use work.PkgRegs.all;
|
||||
use work.PkgJesdConfig.all;
|
||||
use work.PkgAdcDacInterfaceTypes.all;
|
||||
|
||||
|
||||
entity DbCore is
|
||||
generic(
|
||||
-- Set to '1' to include the White Rabbit TDC.
|
||||
kInclWhiteRabbitTdc : std_logic := '0'
|
||||
);
|
||||
port(
|
||||
|
||||
-- Resets --
|
||||
-- Synchronous Reset for the BusClk domain (mainly for the RegPort)
|
||||
bBusReset : in std_logic;
|
||||
|
||||
-- Clocks --
|
||||
-- Register Bus Clock (any frequency)
|
||||
BusClk : in std_logic;
|
||||
-- Always-on at 40 MHz
|
||||
Clk40 : in std_logic;
|
||||
-- Super secret crazy awesome measurement clock at weird frequencies.
|
||||
MeasClk : in std_logic;
|
||||
-- FPGA Sample Clock from DB LMK
|
||||
FpgaClk_p : in std_logic;
|
||||
FpgaClk_n : in std_logic;
|
||||
|
||||
-- Sample Clock Sharing. The clocks generated in this module are exported out to the
|
||||
-- top level so they can be shared amongst daughterboards. Therefore they must be
|
||||
-- driven back into the SampleClk*x inputs at a higher level in order for this module
|
||||
-- to work correctly. There are a few isolated cases where SampleClk*xOut is used
|
||||
-- directly in this module, and those are documented below.
|
||||
SampleClk1xOut : out std_logic;
|
||||
SampleClk1x : in std_logic;
|
||||
SampleClk2xOut : out std_logic;
|
||||
SampleClk2x : in std_logic;
|
||||
|
||||
|
||||
-- Register Ports --
|
||||
--
|
||||
-- Only synchronous resets can be used for these ports!
|
||||
bRegPortInFlat : in std_logic_vector(49 downto 0);
|
||||
bRegPortOutFlat : out std_logic_vector(33 downto 0);
|
||||
|
||||
-- Slot ID value. This should be tied to a constant!
|
||||
kSlotId : in std_logic;
|
||||
|
||||
|
||||
-- SYSREF --
|
||||
--
|
||||
-- SYSREF direct from the LMK
|
||||
sSysRefFpgaLvds_p,
|
||||
sSysRefFpgaLvds_n : in std_logic;
|
||||
-- SYNC directly to the LMK
|
||||
aLmkSync : out std_logic;
|
||||
|
||||
|
||||
-- JESD Signals --
|
||||
--
|
||||
-- GTX Sample Clock Reference Input. Direct connect to FPGA pins.
|
||||
JesdRefClk_p,
|
||||
JesdRefClk_n : in std_logic;
|
||||
|
||||
-- ADC JESD PHY Interface. Direct connect to FPGA pins.
|
||||
aAdcRx_p,
|
||||
aAdcRx_n : in std_logic_vector(3 downto 0);
|
||||
aSyncAdcOut_n : out std_logic;
|
||||
|
||||
-- DAC JESD PHY Interface. Direct connect to FPGA pins.
|
||||
aDacTx_p,
|
||||
aDacTx_n : out std_logic_vector(3 downto 0);
|
||||
aSyncDacIn_n : in std_logic;
|
||||
|
||||
|
||||
-- Data Pipes to/from the DACs/ADCs --
|
||||
--
|
||||
-- - Data is presented as two samples per cycle.
|
||||
-- - sAdcDataValid asserts when ADC data is valid.
|
||||
-- - sDacReadyForInput asserts when DAC data is ready to be received.
|
||||
--
|
||||
-- Reset Crossings:
|
||||
-- The ADC data and valid outputs are synchronously cleared before the asynchronous
|
||||
-- reset is asserted--preventing any reset crossing issues here between the RX
|
||||
-- (internal to the core) reset and the no-reset domain of RFNoC.
|
||||
--
|
||||
-- The DAC samples should be zeros on reset de-assertion due to RFI being de-asserted
|
||||
-- in reset. If they are not zeros, then it is still OK because data is ignored until
|
||||
-- RFI is asserted. DAC RFI is double-synchronized to protect against the reset
|
||||
-- crossing. This is safe to do because it simply delays the output of RFI by two
|
||||
-- cycles on the assertion edge, and as long as reset is held for more than two
|
||||
-- cycles, the de-assertion edge of RFI should come long before the TX module is
|
||||
-- taken out of reset.
|
||||
|
||||
-- Supporting 2 samples per clk cycle.
|
||||
sAdcDataValid : out std_logic;
|
||||
sAdcDataSample0I : out std_logic_vector(15 downto 0);
|
||||
sAdcDataSample0Q : out std_logic_vector(15 downto 0);
|
||||
sAdcDataSample1I : out std_logic_vector(15 downto 0);
|
||||
sAdcDataSample1Q : out std_logic_vector(15 downto 0);
|
||||
--
|
||||
sDacReadyForInput : out std_logic;
|
||||
sDacDataSample0I : in std_logic_vector(15 downto 0);
|
||||
sDacDataSample0Q : in std_logic_vector(15 downto 0);
|
||||
sDacDataSample1I : in std_logic_vector(15 downto 0);
|
||||
sDacDataSample1Q : in std_logic_vector(15 downto 0);
|
||||
|
||||
|
||||
-- RefClk & Timing & Sync --
|
||||
RefClk : in std_logic;
|
||||
rPpsPulse : in std_logic;
|
||||
rGatedPulseToPin : inout std_logic; -- straight to pin
|
||||
sGatedPulseToPin : inout std_logic; -- straight to pin
|
||||
sPps : out std_logic;
|
||||
sPpsToIob : out std_logic;
|
||||
|
||||
-- White Rabbit Timing & Sync --
|
||||
WrRefClk : in std_logic;
|
||||
rWrPpsPulse : in std_logic;
|
||||
rWrGatedPulseToPin : inout std_logic; -- straight to pin
|
||||
sWrGatedPulseToPin : inout std_logic; -- straight to pin
|
||||
aPpsSfpSel : in std_logic_vector(1 downto 0);
|
||||
|
||||
-- Debug for JESD
|
||||
sAdcSync : out std_logic;
|
||||
sDacSync : out std_logic;
|
||||
sSysRef : out std_logic;
|
||||
|
||||
-- Debug for Timing & Sync
|
||||
rRpTransfer : out std_logic;
|
||||
sSpTransfer : out std_logic;
|
||||
rWrRpTransfer : out std_logic;
|
||||
sWrSpTransfer : out std_logic
|
||||
);
|
||||
|
||||
end DbCore;
|
||||
|
||||
|
||||
architecture RTL of DbCore is
|
||||
|
||||
component Jesd204bXcvrCore
|
||||
port (
|
||||
bBusReset : in STD_LOGIC;
|
||||
BusClk : in STD_LOGIC;
|
||||
ReliableClk40 : in STD_LOGIC;
|
||||
FpgaClk1x : in STD_LOGIC;
|
||||
FpgaClk2x : in STD_LOGIC;
|
||||
bFpgaClksStable : in STD_LOGIC;
|
||||
JesdRefClk_p : in STD_LOGIC;
|
||||
JesdRefClk_n : in STD_LOGIC;
|
||||
bJesdRefClkPresent : out STD_LOGIC;
|
||||
aLmkSync : out STD_LOGIC;
|
||||
bRegPortInFlat : in STD_LOGIC_VECTOR(49 downto 0);
|
||||
bRegPortOutFlat : out STD_LOGIC_VECTOR(33 downto 0);
|
||||
CaptureSysRefClk : in STD_LOGIC;
|
||||
cSysRefFpgaLvds_p : in STD_LOGIC;
|
||||
cSysRefFpgaLvds_n : in STD_LOGIC;
|
||||
fSysRef : out STD_LOGIC;
|
||||
aAdcRx_p : in STD_LOGIC_VECTOR(3 downto 0);
|
||||
aAdcRx_n : in STD_LOGIC_VECTOR(3 downto 0);
|
||||
aSyncAdcOut_n : out STD_LOGIC;
|
||||
aDacTx_p : out STD_LOGIC_VECTOR(3 downto 0);
|
||||
aDacTx_n : out STD_LOGIC_VECTOR(3 downto 0);
|
||||
aSyncDacIn_n : in STD_LOGIC;
|
||||
fAdcDataFlatter : out STD_LOGIC_VECTOR(63 downto 0);
|
||||
fDacDataFlatter : in STD_LOGIC_VECTOR(63 downto 0);
|
||||
fAdcDataValid : out STD_LOGIC;
|
||||
fDacReadyForInput : out STD_LOGIC;
|
||||
aDacSync : out STD_LOGIC;
|
||||
aAdcSync : out STD_LOGIC);
|
||||
end component;
|
||||
|
||||
function to_Boolean (s : std_ulogic) return boolean is
|
||||
begin
|
||||
return (To_X01(s)='1');
|
||||
end to_Boolean;
|
||||
|
||||
function to_StdLogic(b : boolean) return std_ulogic is
|
||||
begin
|
||||
if b then
|
||||
return '1';
|
||||
else
|
||||
return '0';
|
||||
end if;
|
||||
end to_StdLogic;
|
||||
|
||||
--vhook_sigstart
|
||||
signal aAdcSync: STD_LOGIC;
|
||||
signal aDacSync: STD_LOGIC;
|
||||
signal bClockingRegPortOut: RegPortOut_t;
|
||||
signal bDbRegPortOut: RegPortOut_t;
|
||||
signal bFpgaClksStable: STD_LOGIC;
|
||||
signal bJesdCoreRegPortInFlat: STD_LOGIC_VECTOR(49 downto 0);
|
||||
signal bJesdCoreRegPortOutFlat: STD_LOGIC_VECTOR(33 downto 0);
|
||||
signal bJesdRefClkPresent: STD_LOGIC;
|
||||
signal bRadioClk1xEnabled: std_logic;
|
||||
signal bRadioClk2xEnabled: std_logic;
|
||||
signal bRadioClk3xEnabled: std_logic;
|
||||
signal bRadioClkMmcmReset: std_logic;
|
||||
signal bRadioClksValid: std_logic;
|
||||
signal pPsDone: std_logic;
|
||||
signal pPsEn: std_logic;
|
||||
signal pPsInc: std_logic;
|
||||
signal PsClk: std_logic;
|
||||
signal sAdcDataFlatter: STD_LOGIC_VECTOR(63 downto 0);
|
||||
signal SampleClk1xOutLcl: std_logic;
|
||||
signal sDacDataFlatter: STD_LOGIC_VECTOR(63 downto 0);
|
||||
signal sDacReadyForInputAsyncReset: STD_LOGIC;
|
||||
signal sRegPps: std_logic;
|
||||
signal sSysRefAsyncReset: STD_LOGIC;
|
||||
signal sWrPps: std_logic;
|
||||
--vhook_sigend
|
||||
|
||||
signal bJesdRegPortInGrp, bSyncRegPortIn, bWrSyncRegPortIn, bRegPortIn : RegPortIn_t;
|
||||
signal bJesdRegPortOut, bSyncRegPortOut, bWrSyncRegPortOut, bRegPortOut : RegPortOut_t;
|
||||
|
||||
signal sDacReadyForInput_ms, sDacReadyForInputLcl,
|
||||
sDacSync_ms, sDacSyncLcl,
|
||||
sAdcSync_ms, sAdcSyncLcl,
|
||||
sSysRef_ms, sSysRefLcl : std_logic := '0';
|
||||
|
||||
signal sAdcDataAry : AdcDataAry_t;
|
||||
signal sDacDataAry : DacDataAry_t;
|
||||
|
||||
signal sPpsSfpSel_ms, sPpsSfpSel : std_logic_vector(1 downto 0) := (others => '0');
|
||||
signal sUseWrTdcPps : boolean := false;
|
||||
signal sPpsInt, sPpsMuxed : std_logic := '0';
|
||||
|
||||
attribute ASYNC_REG : string;
|
||||
attribute ASYNC_REG of sDacReadyForInput_ms : signal is "true";
|
||||
attribute ASYNC_REG of sDacReadyForInputLcl : signal is "true";
|
||||
attribute ASYNC_REG of sDacSync_ms : signal is "true";
|
||||
attribute ASYNC_REG of sDacSyncLcl : signal is "true";
|
||||
attribute ASYNC_REG of sAdcSync_ms : signal is "true";
|
||||
attribute ASYNC_REG of sAdcSyncLcl : signal is "true";
|
||||
attribute ASYNC_REG of sSysRef_ms : signal is "true";
|
||||
attribute ASYNC_REG of sSysRefLcl : signal is "true";
|
||||
attribute ASYNC_REG of sPpsSfpSel_ms : signal is "true";
|
||||
attribute ASYNC_REG of sPpsSfpSel : signal is "true";
|
||||
|
||||
begin
|
||||
|
||||
bRegPortOutFlat <= Flatten(bRegPortOut);
|
||||
bRegPortIn <= Unflatten(bRegPortInFlat);
|
||||
|
||||
|
||||
-- Combine return RegPorts.
|
||||
bRegPortOut <= bJesdRegPortOut
|
||||
+ bClockingRegPortOut
|
||||
+ bSyncRegPortOut + bWrSyncRegPortOut
|
||||
+ bDbRegPortOut;
|
||||
|
||||
|
||||
-- Clocking : -------------------------------------------------------------------------
|
||||
-- Automatically export the Sample Clocks and only use the incoming clocks in the
|
||||
-- remainder of the logic. For a single module, the clocks must be looped back
|
||||
-- in at a higher level!
|
||||
-- ------------------------------------------------------------------------------------
|
||||
|
||||
--vhook_e RadioClocking
|
||||
--vhook_a aReset false
|
||||
--vhook_a bReset to_boolean(bBusReset)
|
||||
--vhook_a RadioClk1x SampleClk1xOutLcl
|
||||
--vhook_a RadioClk2x SampleClk2xOut
|
||||
--vhook_a RadioClk3x open
|
||||
RadioClockingx: entity work.RadioClocking (rtl)
|
||||
port map (
|
||||
aReset => false, --in boolean
|
||||
bReset => to_boolean(bBusReset), --in boolean
|
||||
BusClk => BusClk, --in std_logic
|
||||
bRadioClkMmcmReset => bRadioClkMmcmReset, --in std_logic
|
||||
bRadioClksValid => bRadioClksValid, --out std_logic
|
||||
bRadioClk1xEnabled => bRadioClk1xEnabled, --in std_logic
|
||||
bRadioClk2xEnabled => bRadioClk2xEnabled, --in std_logic
|
||||
bRadioClk3xEnabled => bRadioClk3xEnabled, --in std_logic
|
||||
pPsInc => pPsInc, --in std_logic
|
||||
pPsEn => pPsEn, --in std_logic
|
||||
PsClk => PsClk, --in std_logic
|
||||
pPsDone => pPsDone, --out std_logic
|
||||
FpgaClk_n => FpgaClk_n, --in std_logic
|
||||
FpgaClk_p => FpgaClk_p, --in std_logic
|
||||
RadioClk1x => SampleClk1xOutLcl, --out std_logic
|
||||
RadioClk2x => SampleClk2xOut, --out std_logic
|
||||
RadioClk3x => open); --out std_logic
|
||||
|
||||
-- We need an internal copy of SampleClk1x for the TDC, since we don't want to try
|
||||
-- and align the other DB's clock accidentally.
|
||||
SampleClk1xOut <= SampleClk1xOutLcl;
|
||||
|
||||
--vhook_e ClockingRegs
|
||||
--vhook_a aReset false
|
||||
--vhook_a bReset to_boolean(bBusReset)
|
||||
--vhook_a bRegPortOut bClockingRegPortOut
|
||||
--vhook_a aRadioClksValid bRadioClksValid
|
||||
ClockingRegsx: entity work.ClockingRegs (RTL)
|
||||
port map (
|
||||
aReset => false, --in boolean
|
||||
bReset => to_boolean(bBusReset), --in boolean
|
||||
BusClk => BusClk, --in std_logic
|
||||
bRegPortOut => bClockingRegPortOut, --out RegPortOut_t
|
||||
bRegPortIn => bRegPortIn, --in RegPortIn_t
|
||||
pPsInc => pPsInc, --out std_logic
|
||||
pPsEn => pPsEn, --out std_logic
|
||||
pPsDone => pPsDone, --in std_logic
|
||||
PsClk => PsClk, --out std_logic
|
||||
bRadioClkMmcmReset => bRadioClkMmcmReset, --out std_logic
|
||||
aRadioClksValid => bRadioClksValid, --in std_logic
|
||||
bRadioClk1xEnabled => bRadioClk1xEnabled, --out std_logic
|
||||
bRadioClk2xEnabled => bRadioClk2xEnabled, --out std_logic
|
||||
bRadioClk3xEnabled => bRadioClk3xEnabled, --out std_logic
|
||||
bJesdRefClkPresent => bJesdRefClkPresent); --in std_logic
|
||||
|
||||
|
||||
|
||||
-- JESD204B : -------------------------------------------------------------------------
|
||||
-- ------------------------------------------------------------------------------------
|
||||
|
||||
bJesdRegPortInGrp <= Mask(RegPortIn => bRegPortIn,
|
||||
kRegisterOffset => kJesdRegGroupInDbRegs); -- 0x2000 to 0x3FFC
|
||||
|
||||
-- Expand/compress the RegPort for moving through the netlist boundary.
|
||||
bJesdRegPortOut <= Unflatten(bJesdCoreRegPortOutFlat);
|
||||
bJesdCoreRegPortInFlat <= Flatten(bJesdRegPortInGrp);
|
||||
|
||||
|
||||
--vhook Jesd204bXcvrCore
|
||||
--vhook_a bRegPortInFlat bJesdCoreRegPortInFlat
|
||||
--vhook_a bRegPortOutFlat bJesdCoreRegPortOutFlat
|
||||
--vhook_a FpgaClk1x SampleClk1x
|
||||
--vhook_a FpgaClk2x SampleClk2x
|
||||
--vhook_a ReliableClk40 Clk40
|
||||
--vhook_a CaptureSysRefClk SampleClk1xOutLcl
|
||||
--vhook_a cSysRefFpgaLvds_p sSysRefFpgaLvds_p
|
||||
--vhook_a cSysRefFpgaLvds_n sSysRefFpgaLvds_n
|
||||
--vhook_a fSysRef sSysRefAsyncReset
|
||||
--vhook_a fDacReadyForInput sDacReadyForInputAsyncReset
|
||||
--vhook_a {^f(.*)} s$1
|
||||
Jesd204bXcvrCorex: Jesd204bXcvrCore
|
||||
port map (
|
||||
bBusReset => bBusReset, --in STD_LOGIC
|
||||
BusClk => BusClk, --in STD_LOGIC
|
||||
ReliableClk40 => Clk40, --in STD_LOGIC
|
||||
FpgaClk1x => SampleClk1x, --in STD_LOGIC
|
||||
FpgaClk2x => SampleClk2x, --in STD_LOGIC
|
||||
bFpgaClksStable => bFpgaClksStable, --in STD_LOGIC
|
||||
JesdRefClk_p => JesdRefClk_p, --in STD_LOGIC
|
||||
JesdRefClk_n => JesdRefClk_n, --in STD_LOGIC
|
||||
bJesdRefClkPresent => bJesdRefClkPresent, --out STD_LOGIC
|
||||
aLmkSync => aLmkSync, --out STD_LOGIC
|
||||
bRegPortInFlat => bJesdCoreRegPortInFlat, --in STD_LOGIC_VECTOR(49:0)
|
||||
bRegPortOutFlat => bJesdCoreRegPortOutFlat, --out STD_LOGIC_VECTOR(33:0)
|
||||
CaptureSysRefClk => SampleClk1xOutLcl, --in STD_LOGIC
|
||||
cSysRefFpgaLvds_p => sSysRefFpgaLvds_p, --in STD_LOGIC
|
||||
cSysRefFpgaLvds_n => sSysRefFpgaLvds_n, --in STD_LOGIC
|
||||
fSysRef => sSysRefAsyncReset, --out STD_LOGIC
|
||||
aAdcRx_p => aAdcRx_p, --in STD_LOGIC_VECTOR(3:0)
|
||||
aAdcRx_n => aAdcRx_n, --in STD_LOGIC_VECTOR(3:0)
|
||||
aSyncAdcOut_n => aSyncAdcOut_n, --out STD_LOGIC
|
||||
aDacTx_p => aDacTx_p, --out STD_LOGIC_VECTOR(3:0)
|
||||
aDacTx_n => aDacTx_n, --out STD_LOGIC_VECTOR(3:0)
|
||||
aSyncDacIn_n => aSyncDacIn_n, --in STD_LOGIC
|
||||
fAdcDataFlatter => sAdcDataFlatter, --out STD_LOGIC_VECTOR(63:0)
|
||||
fDacDataFlatter => sDacDataFlatter, --in STD_LOGIC_VECTOR(63:0)
|
||||
fAdcDataValid => sAdcDataValid, --out STD_LOGIC
|
||||
fDacReadyForInput => sDacReadyForInputAsyncReset, --out STD_LOGIC
|
||||
aDacSync => aDacSync, --out STD_LOGIC
|
||||
aAdcSync => aAdcSync); --out STD_LOGIC
|
||||
|
||||
|
||||
JesdDoubleSyncToNoResetSampleClk : process (SampleClk1x)
|
||||
begin
|
||||
if rising_edge(SampleClk1x) then
|
||||
sDacReadyForInput_ms <= sDacReadyForInputAsyncReset;
|
||||
sDacReadyForInputLcl <= sDacReadyForInput_ms;
|
||||
-- No clock crossing here -- just reset, although the prefix declares otherwise...
|
||||
sDacSync_ms <= aDacSync;
|
||||
sDacSyncLcl <= sDacSync_ms;
|
||||
sAdcSync_ms <= aAdcSync;
|
||||
sAdcSyncLcl <= sAdcSync_ms;
|
||||
sSysRef_ms <= sSysRefAsyncReset;
|
||||
sSysRefLcl <= sSysRef_ms;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Locals to outputs.
|
||||
sDacReadyForInput <= sDacReadyForInputLcl;
|
||||
sDacSync <= sDacSyncLcl;
|
||||
sAdcSync <= sAdcSyncLcl;
|
||||
sSysRef <= sSysRefLcl;
|
||||
|
||||
-- Just combine the first two enables, since they're the ones that are used for JESD.
|
||||
-- No reset crossing here, since bFpgaClksStable is only received by a no-reset domain
|
||||
-- and the MGTs directly.
|
||||
bFpgaClksStable <= bRadioClksValid and bRadioClk1xEnabled and bRadioClk2xEnabled;
|
||||
|
||||
-- Compress/expand the flat data types from the netlist and route to top level.
|
||||
sAdcDataAry <= Unflatten(sAdcDataFlatter);
|
||||
sDacDataFlatter <= Flatten(sDacDataAry);
|
||||
|
||||
-- Data mapping using the array types.
|
||||
sAdcDataSample0I <= (sAdcDataAry(0).Data.I & sAdcDataAry(0).Over.I & sAdcDataAry(0).CBit1.I);
|
||||
sAdcDataSample0Q <= (sAdcDataAry(0).Data.Q & sAdcDataAry(0).Over.Q & sAdcDataAry(0).CBit1.Q);
|
||||
sAdcDataSample1I <= (sAdcDataAry(1).Data.I & sAdcDataAry(1).Over.I & sAdcDataAry(1).CBit1.I);
|
||||
sAdcDataSample1Q <= (sAdcDataAry(1).Data.Q & sAdcDataAry(1).Over.Q & sAdcDataAry(1).CBit1.Q);
|
||||
--
|
||||
sDacDataAry(0).Data.I <= sDacDataSample0I;
|
||||
sDacDataAry(0).Data.Q <= sDacDataSample0Q;
|
||||
sDacDataAry(1).Data.I <= sDacDataSample1I;
|
||||
sDacDataAry(1).Data.Q <= sDacDataSample1Q;
|
||||
|
||||
|
||||
-- Timing and Sync : ------------------------------------------------------------------
|
||||
-- ------------------------------------------------------------------------------------
|
||||
|
||||
bSyncRegPortIn <= Mask(RegPortIn => bRegPortIn,
|
||||
kRegisterOffset => kTdc0OffsetsInEndpoint); -- 0x0200
|
||||
|
||||
--vhook_e TdcWrapper
|
||||
--vhook_# Use the local copy of the SampleClock, since we want the TDC to measure the
|
||||
--vhook_# clock offset for this daughterboard, not the global SampleClock.
|
||||
--vhook_a SampleClk SampleClk1xOutLcl
|
||||
--vhook_a sPpsPulse sRegPps
|
||||
TdcWrapperx: entity work.TdcWrapper (struct)
|
||||
port map (
|
||||
BusClk => BusClk, --in std_logic
|
||||
bBusReset => bBusReset, --in std_logic
|
||||
RefClk => RefClk, --in std_logic
|
||||
SampleClk => SampleClk1xOutLcl, --in std_logic
|
||||
MeasClk => MeasClk, --in std_logic
|
||||
bSyncRegPortOut => bSyncRegPortOut, --out RegPortOut_t
|
||||
bSyncRegPortIn => bSyncRegPortIn, --in RegPortIn_t
|
||||
rPpsPulse => rPpsPulse, --in std_logic
|
||||
sPpsPulse => sRegPps, --out std_logic
|
||||
rRpTransfer => rRpTransfer, --out std_logic
|
||||
sSpTransfer => sSpTransfer, --out std_logic
|
||||
rGatedPulseToPin => rGatedPulseToPin, --inout std_logic
|
||||
sGatedPulseToPin => sGatedPulseToPin); --inout std_logic
|
||||
|
||||
WrTdcGen: if kInclWhiteRabbitTdc = '1' generate
|
||||
bWrSyncRegPortIn <= Mask(RegPortIn => bRegPortIn,
|
||||
kRegisterOffset => kTdc1OffsetsInEndpoint); -- 0x0400
|
||||
|
||||
--vhook_e TdcWrapper WrTdcWrapperx
|
||||
--vhook_# Use the local copy of the SampleClock, since we want the TDC to measure the
|
||||
--vhook_# clock offset for this daughterboard, not the global SampleClock.
|
||||
--vhook_a bSyncRegPortIn bWrSyncRegPortIn
|
||||
--vhook_a bSyncRegPortOut bWrSyncRegPortOut
|
||||
--vhook_a SampleClk SampleClk1xOutLcl
|
||||
--vhook_a RefClk WrRefClk
|
||||
--vhook_a rPpsPulse rWrPpsPulse
|
||||
--vhook_a sPpsPulse sWrPps
|
||||
--vhook_a rRpTransfer rWrRpTransfer
|
||||
--vhook_a sSpTransfer sWrSpTransfer
|
||||
--vhook_a rGatedPulseToPin rWrGatedPulseToPin
|
||||
--vhook_a sGatedPulseToPin sWrGatedPulseToPin
|
||||
WrTdcWrapperx: entity work.TdcWrapper (struct)
|
||||
port map (
|
||||
BusClk => BusClk, --in std_logic
|
||||
bBusReset => bBusReset, --in std_logic
|
||||
RefClk => WrRefClk, --in std_logic
|
||||
SampleClk => SampleClk1xOutLcl, --in std_logic
|
||||
MeasClk => MeasClk, --in std_logic
|
||||
bSyncRegPortOut => bWrSyncRegPortOut, --out RegPortOut_t
|
||||
bSyncRegPortIn => bWrSyncRegPortIn, --in RegPortIn_t
|
||||
rPpsPulse => rWrPpsPulse, --in std_logic
|
||||
sPpsPulse => sWrPps, --out std_logic
|
||||
rRpTransfer => rWrRpTransfer, --out std_logic
|
||||
sSpTransfer => sWrSpTransfer, --out std_logic
|
||||
rGatedPulseToPin => rWrGatedPulseToPin, --inout std_logic
|
||||
sGatedPulseToPin => sWrGatedPulseToPin); --inout std_logic
|
||||
end generate WrTdcGen;
|
||||
|
||||
WrTdcNotGen: if kInclWhiteRabbitTdc = '0' generate
|
||||
bWrSyncRegPortOut <= kRegPortOutZero;
|
||||
sWrPps <= '0';
|
||||
rWrRpTransfer <= '0';
|
||||
sWrSpTransfer <= '0';
|
||||
rWrGatedPulseToPin <= '0';
|
||||
sWrGatedPulseToPin <= '0';
|
||||
end generate WrTdcNotGen;
|
||||
|
||||
-- Mux the output PPS based on the SFP selection bits. Encoding is one-hot, with zero
|
||||
-- also a valid state. Regardless of whether the user selects SFP0 or SFP1 as the time
|
||||
-- source, there is only one White Rabbit TDC, so '01' and '10' are equivalent.
|
||||
-- '00': Use the PPS output from the "regular" TDC.
|
||||
-- '01': Use the PPS output from the "white rabbit" TDC.
|
||||
-- '10': Use the PPS output from the "white rabbit" TDC.
|
||||
PpsOutputMux : process (SampleClk1xOutLcl)
|
||||
begin
|
||||
if rising_edge(SampleClk1xOutLcl) then
|
||||
-- Double-sync the control bits to the Sample Clock domain.
|
||||
sPpsSfpSel_ms <= aPpsSfpSel;
|
||||
sPpsSfpSel <= sPpsSfpSel_ms;
|
||||
|
||||
-- OR the control bits together to produce a single override enable for the WR TDC.
|
||||
sUseWrTdcPps <= to_boolean(sPpsSfpSel(0) or sPpsSfpSel(1));
|
||||
|
||||
-- Flop the outputs. One flop for the PPS output IOB, the other for use internally.
|
||||
sPpsInt <= sPpsMuxed;
|
||||
end if;
|
||||
end process PpsOutputMux;
|
||||
|
||||
sPpsMuxed <= sWrPps when sUseWrTdcPps else sRegPps;
|
||||
sPps <= sPpsInt;
|
||||
sPpsToIob <= sPpsMuxed; -- No added flop here since there's an IOB outside this module.
|
||||
|
||||
|
||||
-- Daughterboard Control : ------------------------------------------------------------
|
||||
-- ------------------------------------------------------------------------------------
|
||||
|
||||
--vhook_e DaughterboardRegs
|
||||
--vhook_# Tying this low is safe because the sync reset is used inside DaughterboardRegs.
|
||||
--vhook_a aReset false
|
||||
--vhook_a bReset to_boolean(bBusReset)
|
||||
--vhook_a bRegPortOut bDbRegPortOut
|
||||
--vhook_a kDbId std_logic_vector(to_unsigned(kDbId,kDbIdSize))
|
||||
DaughterboardRegsx: entity work.DaughterboardRegs (RTL)
|
||||
port map (
|
||||
aReset => false, --in boolean
|
||||
bReset => to_boolean(bBusReset), --in boolean
|
||||
BusClk => BusClk, --in std_logic
|
||||
bRegPortOut => bDbRegPortOut, --out RegPortOut_t
|
||||
bRegPortIn => bRegPortIn, --in RegPortIn_t
|
||||
kDbId => std_logic_vector(to_unsigned(kDbId,kDbIdSize)), --in std_logic_vector(15:0)
|
||||
kSlotId => kSlotId); --in std_logic
|
||||
|
||||
|
||||
|
||||
|
||||
end RTL;
|
||||
Binary file not shown.
@@ -0,0 +1,54 @@
|
||||
-- Copyright 1986-2017 Xilinx, Inc. All Rights Reserved.
|
||||
-- --------------------------------------------------------------------------------
|
||||
-- Tool Version: Vivado v.2017.4 (win64) Build 2086221 Fri Dec 15 20:55:39 MST 2017
|
||||
-- Date : Fri Nov 9 16:19:51 2018
|
||||
-- Host : hjimenez running 64-bit major release (build 9200)
|
||||
-- Command : write_vhdl -mode synth_stub -force -file ./Jesd204bXcvrCore_stub.vhd
|
||||
-- Design : Jesd204bXcvrCore
|
||||
-- Purpose : Stub declaration of top-level module interface
|
||||
-- Device : xc7z100ffg900-2
|
||||
-- --------------------------------------------------------------------------------
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
|
||||
entity Jesd204bXcvrCore is
|
||||
Port (
|
||||
bBusReset : in STD_LOGIC;
|
||||
BusClk : in STD_LOGIC;
|
||||
ReliableClk40 : in STD_LOGIC;
|
||||
FpgaClk1x : in STD_LOGIC;
|
||||
FpgaClk2x : in STD_LOGIC;
|
||||
bFpgaClksStable : in STD_LOGIC;
|
||||
JesdRefClk_p : in STD_LOGIC;
|
||||
JesdRefClk_n : in STD_LOGIC;
|
||||
bJesdRefClkPresent : out STD_LOGIC;
|
||||
aLmkSync : out STD_LOGIC;
|
||||
bRegPortInFlat : in STD_LOGIC_VECTOR ( 49 downto 0 );
|
||||
bRegPortOutFlat : out STD_LOGIC_VECTOR ( 33 downto 0 );
|
||||
CaptureSysRefClk : in STD_LOGIC;
|
||||
cSysRefFpgaLvds_p : in STD_LOGIC;
|
||||
cSysRefFpgaLvds_n : in STD_LOGIC;
|
||||
fSysRef : out STD_LOGIC;
|
||||
aAdcRx_p : in STD_LOGIC_VECTOR ( 3 downto 0 );
|
||||
aAdcRx_n : in STD_LOGIC_VECTOR ( 3 downto 0 );
|
||||
aSyncAdcOut_n : out STD_LOGIC;
|
||||
aDacTx_p : out STD_LOGIC_VECTOR ( 3 downto 0 );
|
||||
aDacTx_n : out STD_LOGIC_VECTOR ( 3 downto 0 );
|
||||
aSyncDacIn_n : in STD_LOGIC;
|
||||
fAdcDataFlatter : out STD_LOGIC_VECTOR ( 63 downto 0 );
|
||||
fDacDataFlatter : in STD_LOGIC_VECTOR ( 63 downto 0 );
|
||||
fAdcDataValid : out STD_LOGIC;
|
||||
fDacReadyForInput : out STD_LOGIC;
|
||||
aDacSync : out STD_LOGIC;
|
||||
aAdcSync : out STD_LOGIC
|
||||
);
|
||||
|
||||
end Jesd204bXcvrCore;
|
||||
|
||||
architecture stub of Jesd204bXcvrCore is
|
||||
attribute syn_black_box : boolean;
|
||||
attribute black_box_pad_pin : string;
|
||||
attribute syn_black_box of stub : architecture is true;
|
||||
attribute black_box_pad_pin of stub : architecture is "bBusReset,BusClk,ReliableClk40,FpgaClk1x,FpgaClk2x,bFpgaClksStable,JesdRefClk_p,JesdRefClk_n,bJesdRefClkPresent,aLmkSync,bRegPortInFlat[49:0],bRegPortOutFlat[33:0],CaptureSysRefClk,cSysRefFpgaLvds_p,cSysRefFpgaLvds_n,fSysRef,aAdcRx_p[3:0],aAdcRx_n[3:0],aSyncAdcOut_n,aDacTx_p[3:0],aDacTx_n[3:0],aSyncDacIn_n,fAdcDataFlatter[63:0],fDacDataFlatter[63:0],fAdcDataValid,fDacReadyForInput,aDacSync,aAdcSync";
|
||||
begin
|
||||
end;
|
||||
@@ -0,0 +1,302 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- File: PkgAdcDacInterfaceTypes.vhd
|
||||
-- Author: National Instruments
|
||||
-- Original Project: USRP N32x
|
||||
-- Date: 15 Dec 2017
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
-- (c) 2018 Copyright National Instruments Corporation
|
||||
-- All Rights Reserved
|
||||
-- National Instruments Internal Information
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Purpose: Contains types for ADC and DAC data so they can more easily be
|
||||
-- passed through the design.
|
||||
--
|
||||
-- vreview_group JesdCoreN32x
|
||||
-- vreview_reviewers djepson wfife
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.PkgJesdConfig.all;
|
||||
|
||||
|
||||
package PkgAdcDacInterfaceTypes is
|
||||
|
||||
-- Data type for the DACs.
|
||||
type DacData_t is record
|
||||
I : std_logic_vector(kDacDataWidth - 1 downto 0);
|
||||
Q : std_logic_vector(kDacDataWidth - 1 downto 0);
|
||||
end record;
|
||||
|
||||
-- Data type for the ADCs.
|
||||
type AdcData_t is record
|
||||
I : std_logic_vector(kAdcDataWidth - 1 downto 0);
|
||||
Q : std_logic_vector(kAdcDataWidth - 1 downto 0);
|
||||
end record;
|
||||
|
||||
-- Type has two bits that correspond to I and Q; example usage: overrange flags.
|
||||
type IQFlags_t is record
|
||||
I : std_logic;
|
||||
Q : std_logic;
|
||||
end record;
|
||||
|
||||
-- Single data type for all information from the ADCs.
|
||||
type AdcSamples_t is record
|
||||
Data : AdcData_t;
|
||||
Over : IQFlags_t;
|
||||
CBit1 : IQFlags_t;
|
||||
end record;
|
||||
|
||||
-- Single data type for all information to the DACs.
|
||||
type DacSamples_t is record
|
||||
Data : DacData_t;
|
||||
end record;
|
||||
|
||||
-- To support multiple data values per clock cycle, these types
|
||||
-- are arrays of the ADC and DAC data types where the size of the array
|
||||
-- corresponds to the number of samples per cycle.
|
||||
type AdcDataAry_t is array (kSamplesPerCycle - 1 downto 0) of AdcSamples_t;
|
||||
type DacDataAry_t is array (kSamplesPerCycle - 1 downto 0) of DacSamples_t;
|
||||
|
||||
-- Zero/default constant
|
||||
constant kAdcDataAryZero : AdcDataAry_t :=
|
||||
(others => (Data => (others => (others => '0')),
|
||||
Over => (others => '0'),
|
||||
CBit1 => (others => '0'))
|
||||
);
|
||||
|
||||
-- Zero/default constant
|
||||
constant kDacDataAryZero : DacDataAry_t :=
|
||||
(others => (Data => (others => (others => '0')))
|
||||
);
|
||||
|
||||
-- Flattened type that converts the ADC data into std_logic_vector types. This type is
|
||||
-- not suitable for use in the port maps of components that are presynthesized (into EDF
|
||||
-- or NGC files) but is useful for passing data to the top level.
|
||||
type AdcDataAryFlat_t is record
|
||||
DataI : std_logic_vector(kSamplesPerCycle*kAdcDataWidth - 1 downto 0);
|
||||
DataQ : std_logic_vector(kSamplesPerCycle*kAdcDataWidth - 1 downto 0);
|
||||
OverI : std_logic_vector(kSamplesPerCycle - 1 downto 0);
|
||||
OverQ : std_logic_vector(kSamplesPerCycle - 1 downto 0);
|
||||
CBit1I : std_logic_vector(kSamplesPerCycle - 1 downto 0);
|
||||
CBit1Q : std_logic_vector(kSamplesPerCycle - 1 downto 0);
|
||||
end record;
|
||||
|
||||
-- Fully flattened ADC data for passing into and out of presynthesized components.
|
||||
subtype AdcDataAryFlatter_t is std_logic_vector(2*(kSamplesPerCycle*(kAdcDataWidth + 2)) - 1 downto 0);
|
||||
|
||||
-- Flattened type that converts the DAC data into std_logic_vector types. This type is
|
||||
-- not suitable for use in the port maps of components that are presynthesized (into EDF
|
||||
-- or NGC files) but is useful for passing data from the top level.
|
||||
type DacDataAryFlat_t is record
|
||||
DataI : std_logic_vector(kSamplesPerCycle*kDacDataWidth - 1 downto 0);
|
||||
DataQ : std_logic_vector(kSamplesPerCycle*kDacDataWidth - 1 downto 0);
|
||||
end record;
|
||||
|
||||
-- Fully flattened DAC data for passing into and out of presynthesized components.
|
||||
subtype DacDataAryFlatter_t is std_logic_vector(2*(kSamplesPerCycle*kDacDataWidth) - 1 downto 0);
|
||||
|
||||
-- Function to convert types defined above for the ADC data
|
||||
function Flatten (AdcData : AdcDataAry_t) return AdcDataAryFlat_t;
|
||||
function Flatten (AdcData : AdcDataAryFlat_t) return AdcDataAryFlatter_t;
|
||||
function Flatten (AdcData : AdcDataAry_t) return AdcDataAryFlatter_t;
|
||||
function Unflatten(AdcData : AdcDataAryFlatter_t) return AdcDataAryFlat_t;
|
||||
function Unflatten(AdcData : AdcDataAryFlat_t) return AdcDataAry_t;
|
||||
function Unflatten(AdcData : AdcDataAryFlatter_t) return AdcDataAry_t;
|
||||
|
||||
|
||||
-- Function to convert types defined above for the DAC data
|
||||
function Flatten (DacData : DacDataAry_t) return DacDataAryFlat_t;
|
||||
function Flatten (DacData : DacDataAryFlat_t) return DacDataAryFlatter_t;
|
||||
function Flatten (DacData : DacDataAry_t) return DacDataAryFlatter_t;
|
||||
function Unflatten(DacData : DacDataAryFlatter_t) return DacDataAryFlat_t;
|
||||
function UnFlatten(DacData : DacDataAryFlat_t) return DacDataAry_t;
|
||||
function Unflatten(DacData : DacDataAryFlatter_t) return DacDataAry_t;
|
||||
|
||||
|
||||
end package PkgAdcDacInterfaceTypes;
|
||||
|
||||
|
||||
package body PkgAdcDacInterfaceTypes is
|
||||
|
||||
-- Flattens AdcDataAry_t to AdcDataAryFlat_t
|
||||
function Flatten(AdcData : AdcDataAry_t) return AdcDataAryFlat_t
|
||||
is
|
||||
variable ReturnVar : AdcDataAryFlat_t;
|
||||
begin
|
||||
ReturnVar := (DataI => (others => '0'), -- Note (others => (others => '0')) does not work here
|
||||
DataQ => (others => '0'), -- since DataX and OverX/CBit1X are of different lengths (ModelSim error)
|
||||
OverI => (others => '0'),
|
||||
OverQ => (others => '0'),
|
||||
CBit1I => (others => '0'),
|
||||
CBit1Q => (others => '0'));
|
||||
|
||||
-- The upstream logic puts the 0th element of an array in the MSBs of its data word
|
||||
for i in 0 to kSamplesPerCycle - 1 loop
|
||||
ReturnVar.DataI((kSamplesPerCycle - i)*kAdcDataWidth - 1 downto (kSamplesPerCycle - 1 - i)*kAdcDataWidth) := AdcData(i).Data.I; -- Input Data 0 to MSB
|
||||
ReturnVar.DataQ((kSamplesPerCycle - i)*kAdcDataWidth - 1 downto (kSamplesPerCycle - 1 - i)*kAdcDataWidth) := AdcData(i).Data.Q;
|
||||
ReturnVar.OverI (kSamplesPerCycle - 1 - i) := AdcData(i).Over.I; -- Input Data 0 to MSB
|
||||
ReturnVar.OverQ (kSamplesPerCycle - 1 - i) := AdcData(i).Over.Q;
|
||||
ReturnVar.CBit1I(kSamplesPerCycle - 1 - i) := AdcData(i).CBit1.I;
|
||||
ReturnVar.CBit1Q(kSamplesPerCycle - 1 - i) := AdcData(i).CBit1.Q;
|
||||
end loop;
|
||||
|
||||
return ReturnVar;
|
||||
end function Flatten;
|
||||
|
||||
|
||||
-- UnFlattens AdcDataAryFlat_t to AdcDataAry_t
|
||||
function Unflatten(AdcData : AdcDataAryFlat_t) return AdcDataAry_t
|
||||
is
|
||||
variable ReturnVar : AdcDataAry_t;
|
||||
begin
|
||||
ReturnVar := (others => (Data => (others => (others => '0')), Over => (others => '0'), CBit1 => (others => '0')));
|
||||
for i in 0 to kSamplesPerCycle - 1 loop
|
||||
-- MSB of flattened word = 0th element of ADC data array - this corresponds to how TheWindow
|
||||
-- expects data arrays to be transferred.
|
||||
ReturnVar(kSamplesPerCycle - 1 - i).Data.I := AdcData.DataI((i+1)*kAdcDataWidth - 1 downto i*kAdcDataWidth);
|
||||
ReturnVar(kSamplesPerCycle - 1 - i).Data.Q := AdcData.DataQ((i+1)*kAdcDataWidth - 1 downto i*kAdcDataWidth);
|
||||
ReturnVar(kSamplesPerCycle - 1 - i).Over.I := AdcData.OverI(i);
|
||||
ReturnVar(kSamplesPerCycle - 1 - i).Over.Q := AdcData.OverQ(i);
|
||||
ReturnVar(kSamplesPerCycle - 1 - i).CBit1.I := AdcData.CBit1I(i);
|
||||
ReturnVar(kSamplesPerCycle - 1 - i).CBit1.Q := AdcData.CBit1Q(i);
|
||||
end loop;
|
||||
return ReturnVar;
|
||||
end function Unflatten;
|
||||
|
||||
|
||||
|
||||
|
||||
-- Flattens AdcDataAryFlat_t to AdcDataAryFlatter_t
|
||||
function Flatten(AdcData : AdcDataAryFlat_t) return AdcDataAryFlatter_t
|
||||
is
|
||||
variable ReturnVar : AdcDataAryFlatter_t;
|
||||
begin
|
||||
ReturnVar := AdcData.OverQ & AdcData.CBit1Q & AdcData.OverI & AdcData.CBit1I & AdcData.DataQ & AdcData.DataI;
|
||||
return ReturnVar;
|
||||
end function Flatten;
|
||||
|
||||
-- UnFlattens AdcDataAryFlatter_t to AdcDataAryFlat_t
|
||||
function Unflatten(AdcData : AdcDataAryFlatter_t) return AdcDataAryFlat_t
|
||||
is
|
||||
variable ReturnVar : AdcDataAryFlat_t;
|
||||
begin
|
||||
ReturnVar.DataI := AdcData(1*kSamplesPerCycle*kAdcDataWidth + 0*kSamplesPerCycle - 1 downto 0*kSamplesPerCycle*kAdcDataWidth + 0*kSamplesPerCycle);
|
||||
ReturnVar.DataQ := AdcData(2*kSamplesPerCycle*kAdcDataWidth + 0*kSamplesPerCycle - 1 downto 1*kSamplesPerCycle*kAdcDataWidth + 0*kSamplesPerCycle);
|
||||
ReturnVar.CBit1I := AdcData(2*kSamplesPerCycle*kAdcDataWidth + 1*kSamplesPerCycle - 1 downto 2*kSamplesPerCycle*kAdcDataWidth + 0*kSamplesPerCycle);
|
||||
ReturnVar.OverI := AdcData(2*kSamplesPerCycle*kAdcDataWidth + 2*kSamplesPerCycle - 1 downto 2*kSamplesPerCycle*kAdcDataWidth + 1*kSamplesPerCycle);
|
||||
ReturnVar.CBit1Q := AdcData(2*kSamplesPerCycle*kAdcDataWidth + 3*kSamplesPerCycle - 1 downto 2*kSamplesPerCycle*kAdcDataWidth + 2*kSamplesPerCycle);
|
||||
ReturnVar.OverQ := AdcData(2*kSamplesPerCycle*kAdcDataWidth + 4*kSamplesPerCycle - 1 downto 2*kSamplesPerCycle*kAdcDataWidth + 3*kSamplesPerCycle);
|
||||
return ReturnVar;
|
||||
end function Unflatten;
|
||||
|
||||
|
||||
-- Flattens AdcDataAry_t to AdcDataAryFlatter_t
|
||||
function Flatten(AdcData : AdcDataAry_t) return AdcDataAryFlatter_t
|
||||
is
|
||||
variable TempVar : AdcDataAryFlat_t;
|
||||
variable ReturnVar : AdcDataAryFlatter_t;
|
||||
begin
|
||||
TempVar := Flatten(AdcData);
|
||||
ReturnVar := Flatten(TempVar);
|
||||
return ReturnVar;
|
||||
end function Flatten;
|
||||
|
||||
-- UnFlattens AdcDataAryFlatter_t to AdcDataAry_t
|
||||
function Unflatten(AdcData : AdcDataAryFlatter_t) return AdcDataAry_t
|
||||
is
|
||||
variable TempVar : AdcDataAryFlat_t;
|
||||
variable ReturnVar : AdcDataAry_t;
|
||||
begin
|
||||
TempVar := Unflatten(AdcData);
|
||||
ReturnVar := Unflatten(TempVar);
|
||||
return ReturnVar;
|
||||
end function Unflatten;
|
||||
|
||||
|
||||
|
||||
-- Flattens DacDataAry_t to DacDataAryFlat_t
|
||||
function Flatten(DacData : DacDataAry_t) return DacDataAryFlat_t
|
||||
is
|
||||
variable ReturnVar : DacDataAryFlat_t;
|
||||
begin
|
||||
ReturnVar := (others => (others => '0'));
|
||||
for i in 0 to kSamplesPerCycle - 1 loop
|
||||
-- MSB of flattened word = 0th element of ADC data array - this corresponds to how TheWindow
|
||||
-- expects data arrays to be transferred.
|
||||
ReturnVar.DataI((i+1)*kDacDataWidth - 1 downto i*kDacDataWidth) := DacData(kSamplesPerCycle - 1 - i).Data.I;
|
||||
ReturnVar.DataQ((i+1)*kDacDataWidth - 1 downto i*kDacDataWidth) := DacData(kSamplesPerCycle - 1 - i).Data.Q;
|
||||
end loop;
|
||||
return ReturnVar;
|
||||
end function Flatten;
|
||||
|
||||
|
||||
-- UnFlattens DacDataAryFlat_t to DacDataAry_t
|
||||
function UnFlatten(DacData : DacDataAryFlat_t) return DacDataAry_t
|
||||
is
|
||||
variable ReturnVar : DacDataAry_t;
|
||||
begin
|
||||
ReturnVar := (others => (Data => (others => (others => '0'))));
|
||||
|
||||
-- The upstream logic puts the 0th element of an array in the MSBs of its data word
|
||||
for i in 0 to kSamplesPerCycle - 1 loop
|
||||
ReturnVar(kSamplesPerCycle - 1 - i).Data.I := DacData.DataI(kDacDataWidth*(i+1) - 1 downto kDacDataWidth*i);
|
||||
ReturnVar(kSamplesPerCycle - 1 - i).Data.Q := DacData.DataQ(kDacDataWidth*(i+1) - 1 downto kDacDataWidth*i);
|
||||
end loop;
|
||||
|
||||
return ReturnVar;
|
||||
end function UnFlatten;
|
||||
|
||||
|
||||
|
||||
-- Flattens DacDataAryFlat_t to DacDataAryFlatter_t
|
||||
function Flatten(DacData : DacDataAryFlat_t) return DacDataAryFlatter_t
|
||||
is
|
||||
variable ReturnVar : DacDataAryFlatter_t;
|
||||
begin
|
||||
ReturnVar := DacData.DataQ & DacData.DataI;
|
||||
return ReturnVar;
|
||||
end function Flatten;
|
||||
|
||||
|
||||
-- UnFlattens DacDataAryFlatter_t to DacDataAryFlat_t
|
||||
function Unflatten(DacData : DacDataAryFlatter_t) return DacDataAryFlat_t
|
||||
is
|
||||
variable ReturnVar : DacDataAryFlat_t;
|
||||
begin
|
||||
ReturnVar.DataI := DacData(1*kSamplesPerCycle*kDacDataWidth - 1 downto 0*kSamplesPerCycle*kDacDataWidth);
|
||||
ReturnVar.DataQ := DacData(2*kSamplesPerCycle*kDacDataWidth - 1 downto 1*kSamplesPerCycle*kDacDataWidth);
|
||||
return ReturnVar;
|
||||
end function Unflatten;
|
||||
|
||||
|
||||
-- Flattens DacDataAry_t to DacDataAryFlatter_t
|
||||
function Flatten(DacData : DacDataAry_t) return DacDataAryFlatter_t
|
||||
is
|
||||
variable TempVar : DacDataAryFlat_t;
|
||||
variable ReturnVar : DacDataAryFlatter_t;
|
||||
begin
|
||||
TempVar := Flatten(DacData);
|
||||
ReturnVar := Flatten(TempVar);
|
||||
return ReturnVar;
|
||||
end function Flatten;
|
||||
|
||||
-- UnFlattens DacDataAryFlatter_t to DacDataAry_t
|
||||
function Unflatten(DacData : DacDataAryFlatter_t) return DacDataAry_t
|
||||
is
|
||||
variable TempVar : DacDataAryFlat_t;
|
||||
variable ReturnVar : DacDataAry_t;
|
||||
begin
|
||||
TempVar := Unflatten(DacData);
|
||||
ReturnVar := Unflatten(TempVar);
|
||||
return ReturnVar;
|
||||
end function Unflatten;
|
||||
|
||||
|
||||
end package body;
|
||||
@@ -0,0 +1,107 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- File: PkgClockingRegMap.vhd
|
||||
-- Author: Autogenerated by XmlParse
|
||||
-- Original Project: --
|
||||
-- Date: --
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
-- Copyright 2017 Ettus Research, A National Instruments Company
|
||||
-- SPDX-License-Identifier: LGPL-3.0
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Purpose:
|
||||
-- The constants in this file are autogenerated by XmlParse and should
|
||||
-- be used by testbench code to access specific register fields.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
package PkgClockingRegMap is
|
||||
|
||||
--===============================================================================
|
||||
-- A numerically ordered list of registers and their VHDL source files
|
||||
--===============================================================================
|
||||
|
||||
-- RadioClkMmcm : 0x20 (ClockingRegs.vhd)
|
||||
-- PhaseShiftControl : 0x24 (ClockingRegs.vhd)
|
||||
-- RadioClkEnables : 0x28 (ClockingRegs.vhd)
|
||||
-- MgtRefClkStatus : 0x30 (ClockingRegs.vhd)
|
||||
|
||||
--===============================================================================
|
||||
-- RegTypes
|
||||
--===============================================================================
|
||||
|
||||
--===============================================================================
|
||||
-- Register Group ClockingRegs
|
||||
--===============================================================================
|
||||
|
||||
-- RadioClkMmcm Register (from ClockingRegs.vhd)
|
||||
constant kRadioClkMmcm : integer := 16#20#; -- Register Offset
|
||||
constant kRadioClkMmcmSize: integer := 32; -- register width in bits
|
||||
constant kRadioClkMmcmMask : std_logic_vector(31 downto 0) := X"00000013";
|
||||
constant kRadioClkMmcmResetSetSize : integer := 1; --RadioClkMmcm:RadioClkMmcmResetSet
|
||||
constant kRadioClkMmcmResetSetMsb : integer := 0; --RadioClkMmcm:RadioClkMmcmResetSet
|
||||
constant kRadioClkMmcmResetSet : integer := 0; --RadioClkMmcm:RadioClkMmcmResetSet
|
||||
constant kRadioClkMmcmResetClearSize : integer := 1; --RadioClkMmcm:RadioClkMmcmResetClear
|
||||
constant kRadioClkMmcmResetClearMsb : integer := 1; --RadioClkMmcm:RadioClkMmcmResetClear
|
||||
constant kRadioClkMmcmResetClear : integer := 1; --RadioClkMmcm:RadioClkMmcmResetClear
|
||||
constant kRadioClkMmcmLockedSize : integer := 1; --RadioClkMmcm:RadioClkMmcmLocked
|
||||
constant kRadioClkMmcmLockedMsb : integer := 4; --RadioClkMmcm:RadioClkMmcmLocked
|
||||
constant kRadioClkMmcmLocked : integer := 4; --RadioClkMmcm:RadioClkMmcmLocked
|
||||
|
||||
-- PhaseShiftControl Register (from ClockingRegs.vhd)
|
||||
constant kPhaseShiftControl : integer := 16#24#; -- Register Offset
|
||||
constant kPhaseShiftControlSize: integer := 32; -- register width in bits
|
||||
constant kPhaseShiftControlMask : std_logic_vector(31 downto 0) := X"10010011";
|
||||
constant kPsIncSize : integer := 1; --PhaseShiftControl:PsInc
|
||||
constant kPsIncMsb : integer := 0; --PhaseShiftControl:PsInc
|
||||
constant kPsInc : integer := 0; --PhaseShiftControl:PsInc
|
||||
constant kPsDecSize : integer := 1; --PhaseShiftControl:PsDec
|
||||
constant kPsDecMsb : integer := 4; --PhaseShiftControl:PsDec
|
||||
constant kPsDec : integer := 4; --PhaseShiftControl:PsDec
|
||||
constant kPsEnabledForFdbClkSize : integer := 1; --PhaseShiftControl:PsEnabledForFdbClk
|
||||
constant kPsEnabledForFdbClkMsb : integer := 16; --PhaseShiftControl:PsEnabledForFdbClk
|
||||
constant kPsEnabledForFdbClk : integer := 16; --PhaseShiftControl:PsEnabledForFdbClk
|
||||
constant kPsDoneSize : integer := 1; --PhaseShiftControl:PsDone
|
||||
constant kPsDoneMsb : integer := 28; --PhaseShiftControl:PsDone
|
||||
constant kPsDone : integer := 28; --PhaseShiftControl:PsDone
|
||||
|
||||
-- RadioClkEnables Register (from ClockingRegs.vhd)
|
||||
constant kRadioClkEnables : integer := 16#28#; -- Register Offset
|
||||
constant kRadioClkEnablesSize: integer := 32; -- register width in bits
|
||||
constant kRadioClkEnablesMask : std_logic_vector(31 downto 0) := X"00000111";
|
||||
constant kRadioClk1xEnabledSize : integer := 1; --RadioClkEnables:RadioClk1xEnabled
|
||||
constant kRadioClk1xEnabledMsb : integer := 0; --RadioClkEnables:RadioClk1xEnabled
|
||||
constant kRadioClk1xEnabled : integer := 0; --RadioClkEnables:RadioClk1xEnabled
|
||||
constant kRadioClk2xEnabledSize : integer := 1; --RadioClkEnables:RadioClk2xEnabled
|
||||
constant kRadioClk2xEnabledMsb : integer := 4; --RadioClkEnables:RadioClk2xEnabled
|
||||
constant kRadioClk2xEnabled : integer := 4; --RadioClkEnables:RadioClk2xEnabled
|
||||
constant kRadioClk3xEnabledSize : integer := 1; --RadioClkEnables:RadioClk3xEnabled
|
||||
constant kRadioClk3xEnabledMsb : integer := 8; --RadioClkEnables:RadioClk3xEnabled
|
||||
constant kRadioClk3xEnabled : integer := 8; --RadioClkEnables:RadioClk3xEnabled
|
||||
|
||||
-- MgtRefClkStatus Register (from ClockingRegs.vhd)
|
||||
constant kMgtRefClkStatus : integer := 16#30#; -- Register Offset
|
||||
constant kMgtRefClkStatusSize: integer := 32; -- register width in bits
|
||||
constant kMgtRefClkStatusMask : std_logic_vector(31 downto 0) := X"00000001";
|
||||
constant kJesdRefClkPresentSize : integer := 1; --MgtRefClkStatus:JesdRefClkPresent
|
||||
constant kJesdRefClkPresentMsb : integer := 0; --MgtRefClkStatus:JesdRefClkPresent
|
||||
constant kJesdRefClkPresent : integer := 0; --MgtRefClkStatus:JesdRefClkPresent
|
||||
|
||||
end package;
|
||||
|
||||
package body PkgClockingRegMap is
|
||||
|
||||
-- function kRadioClkMmcmRec not implemented because PkgXReg in this project does not support XReg2_t.
|
||||
|
||||
-- function kPhaseShiftControlRec not implemented because PkgXReg in this project does not support XReg2_t.
|
||||
|
||||
-- function kRadioClkEnablesRec not implemented because PkgXReg in this project does not support XReg2_t.
|
||||
|
||||
-- function kMgtRefClkStatusRec not implemented because PkgXReg in this project does not support XReg2_t.
|
||||
|
||||
end package body;
|
||||
@@ -0,0 +1,56 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- File: PkgDaughterboardRegMap.vhd
|
||||
-- Author: Autogenerated by XmlParse
|
||||
-- Original Project: --
|
||||
-- Date: --
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
-- Copyright 2017 Ettus Research, A National Instruments Company
|
||||
-- SPDX-License-Identifier: LGPL-3.0
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Purpose:
|
||||
-- The constants in this file are autogenerated by XmlParse and should
|
||||
-- be used by testbench code to access specific register fields.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
package PkgDaughterboardRegMap is
|
||||
|
||||
--===============================================================================
|
||||
-- A numerically ordered list of registers and their VHDL source files
|
||||
--===============================================================================
|
||||
|
||||
-- DaughterboardId : 0x630 (DaughterboardRegs.vhd)
|
||||
|
||||
--===============================================================================
|
||||
-- RegTypes
|
||||
--===============================================================================
|
||||
|
||||
--===============================================================================
|
||||
-- Register Group StaticControl
|
||||
--===============================================================================
|
||||
|
||||
-- DaughterboardId Register (from DaughterboardRegs.vhd)
|
||||
constant kDaughterboardId : integer := 16#630#; -- Register Offset
|
||||
constant kDaughterboardIdSize: integer := 32; -- register width in bits
|
||||
constant kDaughterboardIdMask : std_logic_vector(31 downto 0) := X"0001ffff";
|
||||
constant kDbIdValSize : integer := 16; --DaughterboardId:DbIdVal
|
||||
constant kDbIdValMsb : integer := 15; --DaughterboardId:DbIdVal
|
||||
constant kDbIdVal : integer := 0; --DaughterboardId:DbIdVal
|
||||
constant kSlotIdValSize : integer := 1; --DaughterboardId:SlotIdVal
|
||||
constant kSlotIdValMsb : integer := 16; --DaughterboardId:SlotIdVal
|
||||
constant kSlotIdVal : integer := 16; --DaughterboardId:SlotIdVal
|
||||
|
||||
end package;
|
||||
|
||||
package body PkgDaughterboardRegMap is
|
||||
|
||||
-- function kDaughterboardIdRec not implemented because PkgXReg in this project does not support XReg2_t.
|
||||
|
||||
end package body;
|
||||
@@ -0,0 +1,165 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- File: PkgJesdConfig.vhd
|
||||
-- Author: National Instruments
|
||||
-- Original Project: N32x
|
||||
-- Date: 15 Dec 2017
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
-- Copyright 2016-2018 Ettus Research, A National Instruments Company
|
||||
-- SPDX-License-Identifier: LGPL-3.0
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Purpose: JESD204B setup constants and functions. These constants are shared
|
||||
-- between RX and TX JESD cores.
|
||||
--
|
||||
-- vreview_group JesdCoreN32x
|
||||
-- vreview_reviewers djepson wfife
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.PkgRegs.all;
|
||||
|
||||
|
||||
package PkgJesdConfig is
|
||||
|
||||
-- "JESD" in ASCII - with the core number 0 or 1 on the LSb.
|
||||
constant kJesdSignature : std_logic_vector(31 downto 0) := x"4a455344";
|
||||
|
||||
-- Register endpoints
|
||||
constant kJesdDrpRegsInEndpoint : RegOffset_t := (kOffset => 16#0800#, -- 0x2800 to
|
||||
kWidth => 16#0800#); -- 0x2FFF
|
||||
|
||||
-- Selects the UsrClk2 for the transceivers. For 64-bit wide transceivers, the
|
||||
-- UsrClk = 2*UserClk2 frequency. For 32-bit wide transceivers, UsrClk = UserClk2
|
||||
-- frequency. This is a generalization, the clock ratio should be confirmed based on
|
||||
-- the transceiver configuration.
|
||||
-- The N310 transceivers use the single rate reference, hence = false.
|
||||
constant kDoubleRateUsrClk : boolean := false;
|
||||
|
||||
-- For the N32x, all lanes are in one quad and we use the QPLL.
|
||||
constant kJesdUseQpll : boolean := true;
|
||||
|
||||
constant kAdcDataWidth : integer := 14; -- ADC data width in bits
|
||||
constant kDacDataWidth : integer := 16; -- DAC data width in bits
|
||||
constant kSamplesPerCycle : integer := 2; -- Number of samples per SampleClk1x
|
||||
|
||||
constant kGtxDrpAddrWidth : natural := 9;
|
||||
constant kGtxAddrLsbPosition : natural := 2;
|
||||
constant kQpllDrpAddrWidth : natural := 8;
|
||||
constant kGtxDrpDataWidth : natural := 16;
|
||||
|
||||
-- Max supported number of lanes
|
||||
constant kMaxNumLanes : natural := 4;
|
||||
-- Max supported number of quads (normally there is 1 quad per 4 lanes but disconnect
|
||||
-- the definitions to allow quad sharing)
|
||||
constant kMaxNumQuads : natural := 1;
|
||||
|
||||
-- Rhodium:
|
||||
-- JESD shared setup - LMFS = 4211, HD = 1 (Samples are split across multiple lanes).
|
||||
constant kNumLanes : natural := 4; -- L
|
||||
constant kNumConvs : positive := 2; -- M
|
||||
constant kOctetsPerFrame : natural := 1; -- F
|
||||
constant kDacJesdSamplesPerCycle : integer := 1; -- S
|
||||
constant kOctetsPerLane : natural := 2; -- MGT data is kOctetsPerLane*8 = 16 bits wide
|
||||
constant kNumQuads : natural := kNumLanes / 4; -- 4 lanes per quad
|
||||
constant kHighDensity : boolean := true; -- HD
|
||||
constant kConvResBits : positive := kDacDataWidth; -- Converter resolution in bits
|
||||
constant kConvSampleBits : positive := 16; -- Sample Length in bits
|
||||
constant kInitLaneAlignCnt : positive := 4;
|
||||
constant kFramesPerMulti : natural := 24; -- K
|
||||
|
||||
-- Rhodium:
|
||||
-- The converters are running at 400/491.52/500 MSPS (DeviceClk), and the sampling
|
||||
-- clock at the FPGA (UserClk) is 200/245.76/250 MHz; so UsrClk = (DeviceClk / 2).
|
||||
-- The frame rate = DeviceClk, and the Multiframe rate = (frame rate / kFramesPerMulti)
|
||||
-- Thus, kUserClksPerMulti = (UsrClk / Multiframe rate)
|
||||
-- = (UsrClk / (DeviceClk / kFramesPerMulti))
|
||||
-- since UsrClk = DeviceClk / 2 then,
|
||||
-- kUserClksPerMulti = ((DeviceClk / 2) / (DeviceClk / kFramesPerMulti))
|
||||
-- therefore,
|
||||
-- kUserClksPerMulti = kFramesPerMulti / 2
|
||||
constant kUserClksPerMulti : integer := kFramesPerMulti / 2;
|
||||
|
||||
|
||||
type NaturalVector is array ( natural range <>) of natural;
|
||||
|
||||
-- The PCB connections are are passed trough, any swapping is handled somewhere else.
|
||||
--
|
||||
-- Transceiver MGT Channel ADC Lane DAC Lane
|
||||
-- *********** *********** ******** ********
|
||||
-- GT0: X0Y8 0 0 0
|
||||
-- GT1: X0Y9 1 1 1
|
||||
-- GT2: X0Y10 2 2 2
|
||||
-- GT3: X0Y11 3 3 3
|
||||
constant kRxLaneIndices : NaturalVector(kNumLanes - 1 downto 0) :=
|
||||
(
|
||||
-- MGT => ADC (in above table)
|
||||
0 => 0,
|
||||
1 => 1,
|
||||
2 => 2,
|
||||
3 => 3
|
||||
);
|
||||
|
||||
constant kTxLaneIndices : NaturalVector(kNumLanes - 1 downto 0) :=
|
||||
(
|
||||
-- MGT => DAC lane
|
||||
0 => 0,
|
||||
1 => 1,
|
||||
2 => 2,
|
||||
3 => 3
|
||||
);
|
||||
|
||||
constant kLaneToQuadMap : NaturalVector(kNumLanes - 1 downto 0) :=
|
||||
(
|
||||
-- All lanes are in one quad
|
||||
0 => 0,
|
||||
1 => 0,
|
||||
2 => 0,
|
||||
3 => 0
|
||||
);
|
||||
|
||||
|
||||
-- The master transceiver channel for channel bonding. E(kMasterBondingChannel)
|
||||
-- must have the highest value decrementing to b"000" for that last channels to bond.
|
||||
constant kMasterBondingChannel : integer := 1;
|
||||
|
||||
-- Channel bonding occurs when a master detects a K-char sequence and aligns its
|
||||
-- internal FIFO to the start of this sequence. A signal is then generated to other
|
||||
-- slave transceivers that cause them to bond to the sequence - this bonding signal is
|
||||
-- cascaded from master to slave to slave to slave, etc where each slave must know how
|
||||
-- many levels to the master there are. The last slave to bond must be at level b"000"
|
||||
-- and the master is at the highest level; the number of levels in the sequence is
|
||||
-- governed by the size of the transceiver FIFO (see the Xilinx user guides for more
|
||||
-- information).
|
||||
type BondLevels_t is array(0 to kNumLanes - 1) of std_logic_vector(2 downto 0);
|
||||
constant kBondLevel : BondLevels_t := (
|
||||
0 => b"000", -- Control from 1
|
||||
1 => b"001", -- Master
|
||||
2 => b"000", -- Control from 1
|
||||
3 => b"000" -- Control from 1
|
||||
);
|
||||
|
||||
|
||||
-- User Rx Data
|
||||
-- ADC Word data width: 14 sample bits + 2 tails bits
|
||||
constant kAdcWordWidth : integer := 16;
|
||||
subtype AdcWord_t is std_logic_vector(kAdcWordWidth - 1 downto 0);
|
||||
type AdcWordArray_t is array(kSamplesPerCycle*2 - 1 downto 0) of AdcWord_t; -- The *2 is because there are two samples (I and Q) per "sample"
|
||||
|
||||
-- Constants to specify the contents of the AdcWord_t vector.
|
||||
constant kAdcWordDataMsb : integer := 15;
|
||||
constant kAdcWordDataLsb : integer := 2;
|
||||
constant kAdcWordOver : integer := 1;
|
||||
constant kAdcWordCBit1 : integer := 0;
|
||||
|
||||
|
||||
-- Option to pipeline stages to improve timing, if needed
|
||||
constant kPipelineDetectCharsStage : boolean := false;
|
||||
constant kPipelineCharReplStage : boolean := false;
|
||||
|
||||
end package;
|
||||
@@ -0,0 +1,62 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- File: PkgRhPersonality.vhd
|
||||
-- Author: National Instruments
|
||||
-- Original Project: N32x
|
||||
-- Date: 15 Dec 2017
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
-- Copyright 2017 Ettus Research, A National Instruments Company
|
||||
-- SPDX-License-Identifier: GPL-3.0
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Purpose: This package contains constants and helpful functions that enable
|
||||
-- the FPGA to be compiled with different features.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.PkgRegs.all;
|
||||
|
||||
|
||||
package PkgRhPersonality is
|
||||
|
||||
-- Rhodium daughterboard ID definition.
|
||||
constant kDbId : integer := 16#152#;
|
||||
constant kDbIdSize : integer := 16;
|
||||
|
||||
|
||||
-- RegPort Address Definitions : ------------------------------------------------------
|
||||
--
|
||||
-- DB Regs ...
|
||||
--
|
||||
-- Clocking Offset: 0x 000 Width: 0x 200
|
||||
-- Tdco0 Offset: 0x 200 Width: 0x 200
|
||||
-- Tdco1 Offset: 0x 400 Width: 0x 200
|
||||
-- Daughterboard Ctrl Offset: 0x 600 Width: 0x 200
|
||||
-- Total: 0x2000
|
||||
-- JESD 2x - A Offset: 0x2000 Width: 0x1000
|
||||
-- JESD 2x - B Offset: 0x3000 Width: 0x1000
|
||||
-- Total: 0x4000
|
||||
-- Total: 0x8000 for two DBs
|
||||
-- ------------------------------------------------------------------------------------
|
||||
|
||||
-- A single RegPort runs to the JESD204B Core.
|
||||
constant kJesdRegGroupInDbRegs : RegOffset_t := (kOffset => 16#2000#, -- 0x2000 to
|
||||
kWidth => 16#1000#); -- 0x2FFF
|
||||
|
||||
-- DB Regs : --------------------------------------------------------------------------
|
||||
constant kClockingOffsetInEndpoint : RegOffset_t := (kOffset => 16#0000#, -- 0x0000 to
|
||||
kWidth => 16#0200#); -- 0x01FF
|
||||
constant kTdc0OffsetsInEndpoint : RegOffset_t := (kOffset => 16#0200#, -- 0x0200 to
|
||||
kWidth => 16#0200#); -- 0x03FF
|
||||
constant kTdc1OffsetsInEndpoint : RegOffset_t := (kOffset => 16#0400#, -- 0x0400 to
|
||||
kWidth => 16#0200#); -- 0x05FF
|
||||
constant kDaughterboardOffsetInEndpoint : RegOffset_t := (kOffset => 16#0600#, -- 0x0600 to
|
||||
kWidth => 16#0200#); -- 0x07FF
|
||||
|
||||
end package PkgRhPersonality;
|
||||
@@ -0,0 +1,305 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- File: RadioClocking.vhd
|
||||
-- Author: Daniel Jepson
|
||||
-- Original Project: N310
|
||||
-- Date: 22 February 2016
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
-- Copyright 2016-2018 Ettus Research, A National Instruments Company
|
||||
-- SPDX-License-Identifier: LGPL-3.0
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Purpose:
|
||||
--
|
||||
-- Instantiates a MMCM to produce 1x, 2x, and 3x versions of the Radio Clock
|
||||
-- coming from the FPGA input pin. Handles all the buffering for the input clock.
|
||||
-- Additionally allows the clocks to be turned on and off, and phase shifted.
|
||||
--
|
||||
-- NOTE: This module hard-codes the MMCM settings for a SPECIFIC clock rate!
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
library unisim;
|
||||
use unisim.vcomponents.all;
|
||||
|
||||
|
||||
entity RadioClocking is
|
||||
port (
|
||||
-- Async reset. Can be tied low if desired.
|
||||
aReset : in boolean;
|
||||
-- Sync reset... used in the same places as the async one.
|
||||
bReset : in boolean;
|
||||
|
||||
-- Should be a always-on clock
|
||||
BusClk : in std_logic;
|
||||
|
||||
-- Sync reset to the RadioClkMmcm.
|
||||
bRadioClkMmcmReset : in std_logic;
|
||||
|
||||
-- Locked indication from the RadioClkMmcm in BusClk and aReset domains.
|
||||
bRadioClksValid : out std_logic;
|
||||
|
||||
bRadioClk1xEnabled : in std_logic;
|
||||
bRadioClk2xEnabled : in std_logic;
|
||||
bRadioClk3xEnabled : in std_logic;
|
||||
|
||||
-- Phase shift interface for the RadioClkMmcm. PsClk must be <= 200 MHz.
|
||||
pPsInc : in std_logic;
|
||||
pPsEn : in std_logic;
|
||||
PsClk : in std_logic;
|
||||
pPsDone : out std_logic;
|
||||
|
||||
-- Straight from pins. Buffer included in here.
|
||||
FpgaClk_n : in std_logic;
|
||||
FpgaClk_p : in std_logic;
|
||||
|
||||
RadioClk1x : out std_logic;
|
||||
RadioClk2x : out std_logic;
|
||||
RadioClk3x : out std_logic
|
||||
|
||||
);
|
||||
end RadioClocking;
|
||||
|
||||
|
||||
architecture rtl of RadioClocking is
|
||||
|
||||
--vhook_sigstart
|
||||
signal RadioClk1xLcl: std_logic;
|
||||
signal RadioClk1xPll: std_logic;
|
||||
signal RadioClk2xLcl: std_logic;
|
||||
signal RadioClk2xPll: std_logic;
|
||||
signal RadioClk3xLcl: std_logic;
|
||||
signal RadioClk3xPll: std_logic;
|
||||
--vhook_sigend
|
||||
|
||||
signal RadioClkMmcmFeedbackIn,
|
||||
RadioClkMmcmFeedbackOut,
|
||||
FpgaClkSE,
|
||||
aRadioClkMmcmLocked : std_logic;
|
||||
|
||||
signal bRadioClkMmcmLocked_ms,
|
||||
bRadioClkMmcmLocked,
|
||||
bEnableRadioClkBufgOutputs,
|
||||
bEnableRadioClk1xBufgOutput,
|
||||
bEnableRadioClk2xBufgOutput,
|
||||
bEnableRadioClk3xBufgOutput : std_logic := '0';
|
||||
|
||||
signal aRadioClkMmcmResetInternal : std_logic := '1';
|
||||
|
||||
attribute ASYNC_REG : string;
|
||||
attribute ASYNC_REG of bRadioClkMmcmLocked_ms : signal is "true";
|
||||
attribute ASYNC_REG of bRadioClkMmcmLocked : signal is "true";
|
||||
|
||||
begin
|
||||
|
||||
-- Radio Clock Buffering : ------------------------------------------------------------
|
||||
--
|
||||
-- ------------------------------------------------------------------------------------
|
||||
--vhook_i IBUFDS FpgaClkIbufg hidegeneric=true
|
||||
--vhook_a I FpgaClk_p
|
||||
--vhook_a IB FpgaClk_n
|
||||
--vhook_a O FpgaClkSE
|
||||
FpgaClkIbufg: IBUFDS
|
||||
port map (
|
||||
O => FpgaClkSE, --out std_ulogic
|
||||
I => FpgaClk_p, --in std_ulogic
|
||||
IB => FpgaClk_n); --in std_ulogic
|
||||
|
||||
|
||||
ResetDelay : process(aReset, BusClk)
|
||||
begin
|
||||
if aReset then
|
||||
aRadioClkMmcmResetInternal <= '1';
|
||||
elsif rising_edge(BusClk) then
|
||||
if bReset then
|
||||
aRadioClkMmcmResetInternal <= '1';
|
||||
else
|
||||
-- Delay by 1 to allow the BUFGs to turn off before the MMCM is reset.
|
||||
aRadioClkMmcmResetInternal <= bRadioClkMmcmReset;
|
||||
end if;
|
||||
end if;
|
||||
end process ResetDelay;
|
||||
|
||||
|
||||
RadioClkMmcm: MMCME2_ADV
|
||||
generic map(
|
||||
COMPENSATION => "ZHOLD",
|
||||
BANDWIDTH => "OPTIMIZED",
|
||||
CLKFBOUT_MULT_F => 4.000, -- Feedback
|
||||
CLKOUT0_DIVIDE_F => 4.000, -- Data Clock 1x, RadioClk1xPll
|
||||
CLKOUT1_DIVIDE => 2, -- Data Clock 2x, RadioClk2xPll
|
||||
CLKOUT2_DIVIDE => 2, -- Data Clock 3x, RadioClk3xPll
|
||||
CLKOUT3_DIVIDE => 1, -- unused
|
||||
CLKOUT4_DIVIDE => 1, -- unused
|
||||
CLKOUT5_DIVIDE => 1, -- unused
|
||||
CLKOUT6_DIVIDE => 1, -- unused
|
||||
CLKFBOUT_PHASE => 0.000, -- Feedback
|
||||
CLKOUT0_PHASE => 0.000, -- Data Clock 1x
|
||||
CLKOUT1_PHASE => 0.000, -- Data Clock 2x
|
||||
CLKOUT2_PHASE => 0.000, -- Data Clock 3x
|
||||
CLKOUT3_PHASE => 0.000, -- unused
|
||||
CLKOUT4_PHASE => 0.000, -- unused
|
||||
CLKOUT5_PHASE => 0.000, -- unused
|
||||
CLKOUT6_PHASE => 0.000, -- unused
|
||||
CLKOUT0_DUTY_CYCLE => 0.500,
|
||||
CLKOUT1_DUTY_CYCLE => 0.500,
|
||||
CLKOUT2_DUTY_CYCLE => 0.500,
|
||||
CLKOUT3_DUTY_CYCLE => 0.500,
|
||||
CLKOUT4_DUTY_CYCLE => 0.500,
|
||||
CLKOUT5_DUTY_CYCLE => 0.500,
|
||||
CLKOUT6_DUTY_CYCLE => 0.500,
|
||||
DIVCLK_DIVIDE => 1,
|
||||
REF_JITTER1 => 0.010,
|
||||
CLKIN1_PERIOD => 4.069, -- 245.76 MHz max
|
||||
CLKFBOUT_USE_FINE_PS => true,
|
||||
CLKOUT0_USE_FINE_PS => false,
|
||||
CLKOUT1_USE_FINE_PS => false,
|
||||
CLKOUT2_USE_FINE_PS => false,
|
||||
CLKOUT3_USE_FINE_PS => false,
|
||||
CLKOUT4_USE_FINE_PS => false,
|
||||
CLKOUT5_USE_FINE_PS => false,
|
||||
CLKOUT6_USE_FINE_PS => false,
|
||||
STARTUP_WAIT => false,
|
||||
CLKOUT4_CASCADE => false)
|
||||
port map (
|
||||
CLKINSEL => '1',
|
||||
CLKIN1 => FpgaClkSE,
|
||||
CLKIN2 => '0',
|
||||
CLKFBIN => RadioClkMmcmFeedbackIn,
|
||||
RST => aRadioClkMmcmResetInternal,
|
||||
PWRDWN => '0',
|
||||
DADDR => (others => '0'),
|
||||
DI => (others => '0'),
|
||||
DWE => '0',
|
||||
DEN => '0',
|
||||
DCLK => '0',
|
||||
DO => open,
|
||||
DRDY => open,
|
||||
PSINCDEC => pPsInc,
|
||||
PSEN => pPsEn,
|
||||
PSCLK => PsClk,
|
||||
PSDONE => pPsDone,
|
||||
CLKOUT0 => RadioClk1xPll,
|
||||
CLKOUT0B => open,
|
||||
CLKOUT1 => RadioClk2xPll,
|
||||
CLKOUT1B => open,
|
||||
CLKOUT2 => RadioClk3xPll,
|
||||
CLKOUT2B => open,
|
||||
CLKOUT3 => open,
|
||||
CLKOUT3B => open,
|
||||
CLKOUT4 => open,
|
||||
CLKOUT5 => open,
|
||||
CLKOUT6 => open,
|
||||
CLKFBOUT => RadioClkMmcmFeedbackOut,
|
||||
CLKFBOUTB => open,
|
||||
LOCKED => aRadioClkMmcmLocked,
|
||||
CLKINSTOPPED => open,
|
||||
CLKFBSTOPPED => open);
|
||||
|
||||
RadioClkMmcmFeedbackBufg: BUFG
|
||||
port map (
|
||||
I => RadioClkMmcmFeedbackOut,
|
||||
O => RadioClkMmcmFeedbackIn
|
||||
);
|
||||
|
||||
|
||||
-- Only enable the WRAPBUFGs when the MMCM is locked. If the MMCM is ever placed in
|
||||
-- reset, we turn off the clocks one cycle before the asynchronous version
|
||||
-- (aRadioClkMmcmResetInternal) reaches the MMCM inputs in order to prevent
|
||||
-- output glitches.
|
||||
CombineEnablesForBuffers : process(aReset, BusClk)
|
||||
begin
|
||||
if aReset then
|
||||
bRadioClkMmcmLocked_ms <= '0';
|
||||
bRadioClkMmcmLocked <= '0';
|
||||
bEnableRadioClk1xBufgOutput <= '0';
|
||||
bEnableRadioClk2xBufgOutput <= '0';
|
||||
bEnableRadioClk3xBufgOutput <= '0';
|
||||
bEnableRadioClkBufgOutputs <= '0';
|
||||
elsif rising_edge(BusClk) then
|
||||
if bReset then
|
||||
bRadioClkMmcmLocked_ms <= '0';
|
||||
bRadioClkMmcmLocked <= '0';
|
||||
bEnableRadioClk1xBufgOutput <= '0';
|
||||
bEnableRadioClk2xBufgOutput <= '0';
|
||||
bEnableRadioClk3xBufgOutput <= '0';
|
||||
bEnableRadioClkBufgOutputs <= '0';
|
||||
else
|
||||
bRadioClkMmcmLocked_ms <= aRadioClkMmcmLocked;
|
||||
bRadioClkMmcmLocked <= bRadioClkMmcmLocked_ms;
|
||||
|
||||
bEnableRadioClkBufgOutputs <= bRadioClkMmcmLocked and
|
||||
not bRadioClkMmcmReset;
|
||||
bEnableRadioClk1xBufgOutput <= bRadioClk1xEnabled and bEnableRadioClkBufgOutputs;
|
||||
bEnableRadioClk2xBufgOutput <= bRadioClk2xEnabled and bEnableRadioClkBufgOutputs;
|
||||
bEnableRadioClk3xBufgOutput <= bRadioClk3xEnabled and bEnableRadioClkBufgOutputs;
|
||||
end if;
|
||||
end if;
|
||||
end process CombineEnablesForBuffers;
|
||||
|
||||
bRadioClksValid <= bEnableRadioClkBufgOutputs;
|
||||
|
||||
--vhook_e WrapBufg RadioClk1xBuf
|
||||
--vhook_a kEnableByDefault false
|
||||
--vhook_a kIgnore false
|
||||
--vhook_a kEnableIsAsync true
|
||||
--vhook_a ClkIn RadioClk1xPll
|
||||
--vhook_a aCe bEnableRadioClk1xBufgOutput
|
||||
--vhook_a ClkOut RadioClk1xLcl
|
||||
RadioClk1xBuf: entity work.WrapBufg (rtl)
|
||||
generic map (
|
||||
kEnableByDefault => false, --boolean:=false
|
||||
kIgnore => false, --boolean:=false
|
||||
kEnableIsAsync => true) --boolean:=false
|
||||
port map (
|
||||
ClkIn => RadioClk1xPll, --in std_logic
|
||||
aCe => bEnableRadioClk1xBufgOutput, --in std_logic
|
||||
ClkOut => RadioClk1xLcl); --out std_logic
|
||||
|
||||
--vhook_e WrapBufg RadioClk2xBuf
|
||||
--vhook_a kEnableByDefault false
|
||||
--vhook_a kIgnore false
|
||||
--vhook_a kEnableIsAsync true
|
||||
--vhook_a ClkIn RadioClk2xPll
|
||||
--vhook_a aCe bEnableRadioClk2xBufgOutput
|
||||
--vhook_a ClkOut RadioClk2xLcl
|
||||
RadioClk2xBuf: entity work.WrapBufg (rtl)
|
||||
generic map (
|
||||
kEnableByDefault => false, --boolean:=false
|
||||
kIgnore => false, --boolean:=false
|
||||
kEnableIsAsync => true) --boolean:=false
|
||||
port map (
|
||||
ClkIn => RadioClk2xPll, --in std_logic
|
||||
aCe => bEnableRadioClk2xBufgOutput, --in std_logic
|
||||
ClkOut => RadioClk2xLcl); --out std_logic
|
||||
|
||||
--vhook_e WrapBufg RadioClk3xBuf
|
||||
--vhook_a kEnableByDefault false
|
||||
--vhook_a kIgnore false
|
||||
--vhook_a kEnableIsAsync true
|
||||
--vhook_a ClkIn RadioClk3xPll
|
||||
--vhook_a aCe bEnableRadioClk3xBufgOutput
|
||||
--vhook_a ClkOut RadioClk3xLcl
|
||||
RadioClk3xBuf: entity work.WrapBufg (rtl)
|
||||
generic map (
|
||||
kEnableByDefault => false, --boolean:=false
|
||||
kIgnore => false, --boolean:=false
|
||||
kEnableIsAsync => true) --boolean:=false
|
||||
port map (
|
||||
ClkIn => RadioClk3xPll, --in std_logic
|
||||
aCe => bEnableRadioClk3xBufgOutput, --in std_logic
|
||||
ClkOut => RadioClk3xLcl); --out std_logic
|
||||
|
||||
|
||||
-- Assign outputs from locals.
|
||||
RadioClk1x <= RadioClk1xLcl;
|
||||
RadioClk2x <= RadioClk2xLcl;
|
||||
RadioClk3x <= RadioClk3xLcl;
|
||||
|
||||
|
||||
|
||||
end rtl;
|
||||
@@ -0,0 +1,280 @@
|
||||
## TDC : ################################################################################
|
||||
## Bank 10, 2.5V (DB A)
|
||||
#########################################################################################
|
||||
|
||||
set_property PACKAGE_PIN AB15 [get_ports {UNUSED_PIN_TDCA_0}]
|
||||
set_property PACKAGE_PIN AB14 [get_ports {UNUSED_PIN_TDCA_1}]
|
||||
set_property PACKAGE_PIN AB16 [get_ports {UNUSED_PIN_TDCA_2}]
|
||||
set_property PACKAGE_PIN AB17 [get_ports {UNUSED_PIN_TDCA_3}]
|
||||
set_property IOSTANDARD LVCMOS25 [get_ports {UNUSED_PIN_TDCA_*}]
|
||||
set_property IOB TRUE [get_ports {UNUSED_PIN_TDCA_*}]
|
||||
|
||||
|
||||
## TDC : ################################################################################
|
||||
## Bank 11, 2.5V (DB B)
|
||||
#########################################################################################
|
||||
|
||||
set_property PACKAGE_PIN W21 [get_ports {UNUSED_PIN_TDCB_0}]
|
||||
set_property PACKAGE_PIN Y21 [get_ports {UNUSED_PIN_TDCB_1}]
|
||||
set_property PACKAGE_PIN Y22 [get_ports {UNUSED_PIN_TDCB_2}]
|
||||
set_property PACKAGE_PIN Y23 [get_ports {UNUSED_PIN_TDCB_3}]
|
||||
set_property IOSTANDARD LVCMOS25 [get_ports {UNUSED_PIN_TDCB_*}]
|
||||
set_property IOB TRUE [get_ports {UNUSED_PIN_TDCB_*}]
|
||||
|
||||
|
||||
## USRP IO A : ##########################################################################
|
||||
# DBA
|
||||
#########################################################################################
|
||||
|
||||
set_property PACKAGE_PIN G1 [get_ports DBA_MODULE_PWR_ENABLE]
|
||||
set_property PACKAGE_PIN E5 [get_ports DBA_RF_PWR_ENABLE]
|
||||
|
||||
set_property PACKAGE_PIN AF14 [get_ports DBA_FPGA_CLK_P]
|
||||
set_property PACKAGE_PIN AG14 [get_ports DBA_FPGA_CLK_N]
|
||||
|
||||
set_property PACKAGE_PIN N8 [get_ports DBA_MGTCLK_P]
|
||||
set_property PACKAGE_PIN N7 [get_ports DBA_MGTCLK_N]
|
||||
|
||||
set_property PACKAGE_PIN AG17 [get_ports DBA_FPGA_SYSREF_P]
|
||||
set_property PACKAGE_PIN AG16 [get_ports DBA_FPGA_SYSREF_N]
|
||||
set_property IOB TRUE [get_ports DBA_FPGA_SYSREF_*]
|
||||
|
||||
|
||||
# set_property PACKAGE_PIN AD10 [get_ports NET2CLK_P]
|
||||
# set_property PACKAGE_PIN AD9 [get_ports NET2CLK_N]
|
||||
|
||||
set_property PACKAGE_PIN C2 [get_ports DBA_CPLD_PL_SPI_SCLK]
|
||||
set_property PACKAGE_PIN B1 [get_ports DBA_TXLO_SPI_CS_B]; # DBA_CPLD_PL_SPI_LE
|
||||
set_property PACKAGE_PIN B2 [get_ports DBA_CPLD_PL_SPI_CS_B]; # DBA_CPLD_PL_SPI_ADDR[0]
|
||||
set_property PACKAGE_PIN F4 [get_ports DBA_RXLO_SPI_CS_B]; # DBA_CPLD_PL_SPI_ADDR[1]
|
||||
set_property PACKAGE_PIN F3 [get_ports DBA_LODIS_SPI_CS_B]; # DBA_CPLD_PL_SPI_ADDR[2]
|
||||
set_property PACKAGE_PIN C1 [get_ports DBA_CPLD_PL_SPI_MISO]
|
||||
set_property PACKAGE_PIN A3 [get_ports DBA_CPLD_PL_SPI_MOSI]
|
||||
|
||||
set_property PACKAGE_PIN AC16 [get_ports DBA_CPLD_PS_SPI_SCLK]; # DBA_CPLD_PS_SPI_ADDR[0]
|
||||
set_property PACKAGE_PIN AE15 [get_ports DBA_CPLD_PS_SPI_CS_B]; # DBA_CPLD_PS_SPI_ADDR[1]
|
||||
set_property PACKAGE_PIN AE16 [get_ports DBA_PHDAC_SPI_CS_B]; # DBA_CPLD_PS_SPI_LE
|
||||
set_property PACKAGE_PIN AF17 [get_ports DBA_CLKDIS_SPI_CS_B]
|
||||
set_property PACKAGE_PIN AK16 [get_ports DBA_ADC_SPI_CS_B]; # DBA_CPLD_UNUSED[12]
|
||||
set_property PACKAGE_PIN AJ16 [get_ports DBA_DAC_SPI_CS_B]; # DBA_CPLD_UNUSED[13]
|
||||
set_property PACKAGE_PIN AC17 [get_ports DBA_CPLD_PS_SPI_MISO]
|
||||
set_property PACKAGE_PIN AF18 [get_ports DBA_CPLD_PS_SPI_MOSI]
|
||||
|
||||
set_property PACKAGE_PIN AH13 [get_ports DBA_CPLD_JTAG_TDI]
|
||||
set_property PACKAGE_PIN AH14 [get_ports DBA_CPLD_JTAG_TDO]
|
||||
set_property PACKAGE_PIN AE13 [get_ports DBA_CPLD_JTAG_TMS]
|
||||
set_property PACKAGE_PIN AF13 [get_ports DBA_CPLD_JTAG_TCK]
|
||||
|
||||
set_property PACKAGE_PIN E1 [get_ports DBA_CLKDIST_SYNC]
|
||||
|
||||
set_property PACKAGE_PIN A2 [get_ports DBA_ATR_TX]
|
||||
set_property PACKAGE_PIN E3 [get_ports DBA_ATR_RX]
|
||||
|
||||
set_property PACKAGE_PIN E2 [get_ports DBA_TXRX_SW_CTRL_1]
|
||||
set_property PACKAGE_PIN F5 [get_ports DBA_TXRX_SW_CTRL_2]
|
||||
|
||||
set_property PACKAGE_PIN AE12 [get_ports DBA_ADC_SYNCB_P]
|
||||
set_property PACKAGE_PIN AF12 [get_ports DBA_ADC_SYNCB_N]
|
||||
set_property PACKAGE_PIN AD14 [get_ports DBA_DAC_SYNCB_P]; # Layout swapped, RTL is negated.
|
||||
set_property PACKAGE_PIN AD13 [get_ports DBA_DAC_SYNCB_N]; # Layout swapped, RTL is negated.
|
||||
|
||||
# This mapping uses the TX pins as the "master" and mimics RX off of them so Vivado
|
||||
# places the transceivers in the correct places. The mixup in lanes is accounted for
|
||||
# in the AD9695 and the DAC37J82 crossbar settings.
|
||||
set_property PACKAGE_PIN V6 [get_ports DBA_RX_P[0]]
|
||||
set_property PACKAGE_PIN V5 [get_ports DBA_RX_N[0]]
|
||||
set_property PACKAGE_PIN U4 [get_ports DBA_RX_P[1]]
|
||||
set_property PACKAGE_PIN U3 [get_ports DBA_RX_N[1]]
|
||||
set_property PACKAGE_PIN T6 [get_ports DBA_RX_P[2]]
|
||||
set_property PACKAGE_PIN T5 [get_ports DBA_RX_N[2]]
|
||||
set_property PACKAGE_PIN P6 [get_ports DBA_RX_P[3]]
|
||||
set_property PACKAGE_PIN P5 [get_ports DBA_RX_N[3]]
|
||||
|
||||
set_property PACKAGE_PIN T2 [get_ports DBA_TX_P[0]]
|
||||
set_property PACKAGE_PIN T1 [get_ports DBA_TX_N[0]]
|
||||
set_property PACKAGE_PIN R4 [get_ports DBA_TX_P[1]]
|
||||
set_property PACKAGE_PIN R3 [get_ports DBA_TX_N[1]]
|
||||
set_property PACKAGE_PIN P2 [get_ports DBA_TX_P[2]]
|
||||
set_property PACKAGE_PIN P1 [get_ports DBA_TX_N[2]]
|
||||
set_property PACKAGE_PIN N4 [get_ports DBA_TX_P[3]]
|
||||
set_property PACKAGE_PIN N3 [get_ports DBA_TX_N[3]]
|
||||
|
||||
set_property PACKAGE_PIN AG12 [get_ports DBA_LED_RX]
|
||||
set_property PACKAGE_PIN AH12 [get_ports DBA_LED_RX2]
|
||||
set_property PACKAGE_PIN AJ13 [get_ports DBA_LED_TX]
|
||||
|
||||
# Possibly need to be used. Connected to CPLD.
|
||||
# set_property PACKAGE_PIN C4 [get_ports DBA_CPLD_UNUSED[0]]
|
||||
# set_property PACKAGE_PIN C3 [get_ports DBA_CPLD_UNUSED[1]]
|
||||
# set_property PACKAGE_PIN K1 [get_ports DBA_CPLD_UNUSED[2]]
|
||||
# set_property PACKAGE_PIN L1 [get_ports DBA_CPLD_UNUSED[3]]
|
||||
# set_property PACKAGE_PIN D1 [get_ports DBA_CPLD_UNUSED[4]]
|
||||
# set_property PACKAGE_PIN AE17 [get_ports DBA_CPLD_UNUSED[5]]
|
||||
# set_property PACKAGE_PIN AE18 [get_ports DBA_CPLD_UNUSED[6]]
|
||||
# set_property PACKAGE_PIN AB12 [get_ports DBA_CPLD_UNUSED[7]]
|
||||
# set_property PACKAGE_PIN AC12 [get_ports DBA_CPLD_UNUSED[8]]
|
||||
# set_property PACKAGE_PIN AG17 [get_ports DBA_CPLD_UNUSED[9]]
|
||||
# set_property PACKAGE_PIN AK12 [get_ports DBA_CPLD_UNUSED[10]]
|
||||
# set_property PACKAGE_PIN AK13 [get_ports DBA_CPLD_UNUSED[11]]
|
||||
|
||||
set UsrpIoAHpPinsSe [get_ports {DBA_MODULE_PWR_ENABLE \
|
||||
DBA_RF_PWR_ENABLE \
|
||||
DBA_CPLD_PL_SPI_* \
|
||||
DBA_TXLO_SPI_CS_B \
|
||||
DBA_RXLO_SPI_CS_B \
|
||||
DBA_LODIS_SPI_CS_B \
|
||||
DBA_CLKDIST_SYNC \
|
||||
DBA_TXRX_SW_CTRL_* \
|
||||
DBA_ATR_*}]
|
||||
set_property IOSTANDARD LVCMOS18 $UsrpIoAHpPinsSe
|
||||
set_property DRIVE 6 $UsrpIoAHpPinsSe
|
||||
set_property SLEW SLOW $UsrpIoAHpPinsSe
|
||||
|
||||
set UsrpIoAHrPinsSeDr4 [get_ports {DBA_LED_* \
|
||||
DBA_CPLD_JTAG_*}]
|
||||
set_property IOSTANDARD LVCMOS25 $UsrpIoAHrPinsSeDr4
|
||||
set_property DRIVE 4 $UsrpIoAHrPinsSeDr4
|
||||
set_property SLEW SLOW $UsrpIoAHrPinsSeDr4
|
||||
|
||||
set UsrpIoAHrPinsSeDr8 [get_ports {DBA_CPLD_PS_SPI_* \
|
||||
DBA_PHDAC_SPI_CS_B \
|
||||
DBA_CLKDIS_SPI_CS_B \
|
||||
DBA_ADC_SPI_CS_B \
|
||||
DBA_DAC_SPI_CS_B}]
|
||||
set_property IOSTANDARD LVCMOS25 $UsrpIoAHrPinsSeDr8
|
||||
set_property DRIVE 8 $UsrpIoAHrPinsSeDr8
|
||||
set_property SLEW SLOW $UsrpIoAHrPinsSeDr8
|
||||
|
||||
set UsrpIoAHrPinsDiff [get_ports {DBA_ADC_SYNCB_* \
|
||||
DBA_DAC_SYNCB_* \
|
||||
DBA_FPGA_CLK_* \
|
||||
DBA_FPGA_SYSREF_*}]
|
||||
set_property IOSTANDARD LVDS_25 $UsrpIoAHrPinsDiff
|
||||
set_property DIFF_TERM TRUE $UsrpIoAHrPinsDiff
|
||||
|
||||
|
||||
## USRP IO B : ##########################################################################
|
||||
# DBB
|
||||
#########################################################################################
|
||||
|
||||
set_property PACKAGE_PIN J4 [get_ports DBB_MODULE_PWR_ENABLE]
|
||||
set_property PACKAGE_PIN G4 [get_ports DBB_RF_PWR_ENABLE]
|
||||
|
||||
set_property PACKAGE_PIN AG21 [get_ports DBB_FPGA_CLK_P]
|
||||
set_property PACKAGE_PIN AH21 [get_ports DBB_FPGA_CLK_N]
|
||||
|
||||
set_property PACKAGE_PIN W8 [get_ports DBB_MGTCLK_P]
|
||||
set_property PACKAGE_PIN W7 [get_ports DBB_MGTCLK_N]
|
||||
|
||||
set_property PACKAGE_PIN AE22 [get_ports DBB_FPGA_SYSREF_P]
|
||||
set_property PACKAGE_PIN AF22 [get_ports DBB_FPGA_SYSREF_N]
|
||||
set_property IOB TRUE [get_ports DBB_FPGA_SYSREF_*]
|
||||
|
||||
set_property PACKAGE_PIN K6 [get_ports DBB_CPLD_PL_SPI_SCLK]
|
||||
set_property PACKAGE_PIN F2 [get_ports DBB_TXLO_SPI_CS_B]; # DBB_CPLD_PL_SPI_LE
|
||||
set_property PACKAGE_PIN G2 [get_ports DBB_CPLD_PL_SPI_CS_B]; # DBB_CPLD_PL_SPI_ADDR[0]
|
||||
set_property PACKAGE_PIN H4 [get_ports DBB_RXLO_SPI_CS_B]; # DBB_CPLD_PL_SPI_ADDR[1]
|
||||
set_property PACKAGE_PIN H3 [get_ports DBB_LODIS_SPI_CS_B]; # DBB_CPLD_PL_SPI_ADDR[2]
|
||||
set_property PACKAGE_PIN J6 [get_ports DBB_CPLD_PL_SPI_MISO]
|
||||
set_property PACKAGE_PIN D5 [get_ports DBB_CPLD_PL_SPI_MOSI]
|
||||
|
||||
set_property PACKAGE_PIN AG22 [get_ports DBB_CPLD_PS_SPI_SCLK]
|
||||
set_property PACKAGE_PIN AD23 [get_ports DBB_CPLD_PS_SPI_CS_B]; # DBB_CPLD_PS_SPI_ADDR[0]
|
||||
set_property PACKAGE_PIN AE23 [get_ports DBB_PHDAC_SPI_CS_B]; # DBB_CPLD_PS_SPI_ADDR[1]
|
||||
set_property PACKAGE_PIN AB24 [get_ports DBB_CLKDIS_SPI_CS_B]; # DBB_CPLD_PS_SPI_LE
|
||||
set_property PACKAGE_PIN AJ23 [get_ports DBB_ADC_SPI_CS_B]; # DBB_CPLD_UNUSED[12]]
|
||||
set_property PACKAGE_PIN AJ24 [get_ports DBB_DAC_SPI_CS_B]; # DBB_CPLD_UNUSED[13]]
|
||||
set_property PACKAGE_PIN AH22 [get_ports DBB_CPLD_PS_SPI_MISO]
|
||||
set_property PACKAGE_PIN AA24 [get_ports DBB_CPLD_PS_SPI_MOSI]
|
||||
|
||||
set_property PACKAGE_PIN AH19 [get_ports DBB_CPLD_JTAG_TDI]
|
||||
set_property PACKAGE_PIN AJ19 [get_ports DBB_CPLD_JTAG_TDO]
|
||||
set_property PACKAGE_PIN AB21 [get_ports DBB_CPLD_JTAG_TMS]
|
||||
set_property PACKAGE_PIN AB22 [get_ports DBB_CPLD_JTAG_TCK]
|
||||
|
||||
set_property PACKAGE_PIN D3 [get_ports DBB_CLKDIST_SYNC]
|
||||
|
||||
set_property PACKAGE_PIN E6 [get_ports DBB_ATR_TX]
|
||||
set_property PACKAGE_PIN J5 [get_ports DBB_ATR_RX]
|
||||
|
||||
set_property PACKAGE_PIN K5 [get_ports DBB_TXRX_SW_CTRL_1]
|
||||
set_property PACKAGE_PIN G5 [get_ports DBB_TXRX_SW_CTRL_2]
|
||||
|
||||
set_property PACKAGE_PIN AF23 [get_ports DBB_ADC_SYNCB_P]
|
||||
set_property PACKAGE_PIN AF24 [get_ports DBB_ADC_SYNCB_N]
|
||||
set_property PACKAGE_PIN AD21 [get_ports DBB_DAC_SYNCB_P]
|
||||
set_property PACKAGE_PIN AE21 [get_ports DBB_DAC_SYNCB_N]
|
||||
|
||||
# This mapping uses the TX pins as the "master" and mimics RX off of them so Vivado
|
||||
# places the transceivers in the correct places. The mixup in lanes is accounted for
|
||||
# in the AD9695 and the DAC37J82 crossbar settings.
|
||||
set_property PACKAGE_PIN AC4 [get_ports DBB_RX_P[0]]
|
||||
set_property PACKAGE_PIN AC3 [get_ports DBB_RX_N[0]]
|
||||
set_property PACKAGE_PIN AB6 [get_ports DBB_RX_P[1]]
|
||||
set_property PACKAGE_PIN AB5 [get_ports DBB_RX_N[1]]
|
||||
set_property PACKAGE_PIN Y6 [get_ports DBB_RX_P[2]]
|
||||
set_property PACKAGE_PIN Y5 [get_ports DBB_RX_N[2]]
|
||||
set_property PACKAGE_PIN AA4 [get_ports DBB_RX_P[3]]
|
||||
set_property PACKAGE_PIN AA3 [get_ports DBB_RX_N[3]]
|
||||
|
||||
set_property PACKAGE_PIN AB2 [get_ports DBB_TX_P[0]]
|
||||
set_property PACKAGE_PIN AB1 [get_ports DBB_TX_N[0]]
|
||||
set_property PACKAGE_PIN Y2 [get_ports DBB_TX_P[1]]
|
||||
set_property PACKAGE_PIN Y1 [get_ports DBB_TX_N[1]]
|
||||
set_property PACKAGE_PIN W4 [get_ports DBB_TX_P[2]]
|
||||
set_property PACKAGE_PIN W3 [get_ports DBB_TX_N[2]]
|
||||
set_property PACKAGE_PIN V2 [get_ports DBB_TX_P[3]]
|
||||
set_property PACKAGE_PIN V1 [get_ports DBB_TX_N[3]]
|
||||
|
||||
set_property PACKAGE_PIN AK17 [get_ports DBB_LED_RX]
|
||||
set_property PACKAGE_PIN AK18 [get_ports DBB_LED_RX2]
|
||||
set_property PACKAGE_PIN AK21 [get_ports DBB_LED_TX]
|
||||
|
||||
# Possibly need to be used. Connected to CPLD.
|
||||
# set_property PACKAGE_PIN G6 [get_ports DBB_CPLD_UNUSED[0]]
|
||||
# set_property PACKAGE_PIN H6 [get_ports DBB_CPLD_UNUSED[1]]
|
||||
# set_property PACKAGE_PIN L3 [get_ports DBB_CPLD_UNUSED[2]]
|
||||
# set_property PACKAGE_PIN L2 [get_ports DBB_CPLD_UNUSED[3]]
|
||||
# set_property PACKAGE_PIN D4 [get_ports DBB_CPLD_UNUSED[4]]
|
||||
# set_property PACKAGE_PIN AC22 [get_ports DBB_CPLD_UNUSED[5]]
|
||||
# set_property PACKAGE_PIN AC23 [get_ports DBB_CPLD_UNUSED[6]]
|
||||
# set_property PACKAGE_PIN AC24 [get_ports DBB_CPLD_UNUSED[7]]
|
||||
# set_property PACKAGE_PIN AD24 [get_ports DBB_CPLD_UNUSED[8]]
|
||||
# set_property PACKAGE_PIN AE22 [get_ports DBB_CPLD_UNUSED[9]]
|
||||
# set_property PACKAGE_PIN AK20 [get_ports DBB_CPLD_UNUSED[10]]
|
||||
# set_property PACKAGE_PIN AJ20 [get_ports DBB_CPLD_UNUSED[11]]
|
||||
|
||||
set UsrpIoBHpPinsSe [get_ports {DBB_MODULE_PWR_ENABLE \
|
||||
DBB_RF_PWR_ENABLE \
|
||||
DBB_CPLD_PL_SPI_* \
|
||||
DBB_TXLO_SPI_CS_B \
|
||||
DBB_RXLO_SPI_CS_B \
|
||||
DBB_LODIS_SPI_CS_B \
|
||||
DBB_CLKDIST_SYNC \
|
||||
DBB_TXRX_SW_CTRL_* \
|
||||
DBB_ATR_*}]
|
||||
set_property IOSTANDARD LVCMOS18 $UsrpIoBHpPinsSe
|
||||
set_property DRIVE 6 $UsrpIoBHpPinsSe
|
||||
set_property SLEW SLOW $UsrpIoBHpPinsSe
|
||||
|
||||
set UsrpIoBHrPinsSeDr4 [get_ports {DBB_LED_* \
|
||||
DBB_CPLD_JTAG_*}]
|
||||
set_property IOSTANDARD LVCMOS25 $UsrpIoBHrPinsSeDr4
|
||||
set_property DRIVE 4 $UsrpIoBHrPinsSeDr4
|
||||
set_property SLEW SLOW $UsrpIoBHrPinsSeDr4
|
||||
|
||||
set UsrpIoBHrPinsSeDr8 [get_ports {DBB_CPLD_PS_SPI_* \
|
||||
DBB_PHDAC_SPI_CS_B \
|
||||
DBB_CLKDIS_SPI_CS_B \
|
||||
DBB_ADC_SPI_CS_B \
|
||||
DBB_DAC_SPI_CS_B}]
|
||||
set_property IOSTANDARD LVCMOS25 $UsrpIoBHrPinsSeDr8
|
||||
set_property DRIVE 8 $UsrpIoBHrPinsSeDr8
|
||||
set_property SLEW SLOW $UsrpIoBHrPinsSeDr8
|
||||
|
||||
set UsrpIoBHrPinsDiff [get_ports {DBB_ADC_SYNCB_* \
|
||||
DBB_DAC_SYNCB_* \
|
||||
DBB_FPGA_CLK_* \
|
||||
DBB_FPGA_SYSREF_*}]
|
||||
set_property IOSTANDARD LVDS_25 $UsrpIoBHrPinsDiff
|
||||
set_property DIFF_TERM TRUE $UsrpIoBHrPinsDiff
|
||||
@@ -0,0 +1,264 @@
|
||||
#
|
||||
# Copyright 2017 Ettus Research, A National Instruments Company
|
||||
# SPDX-License-Identifier: LGPL-3.0
|
||||
#
|
||||
# Timing analysis is performed in "usrp3/top/n3xx/dboards/rh/doc/rh_timing.xlsx".
|
||||
# See this spreadsheet for more details and explanations.
|
||||
|
||||
#*******************************************************************************
|
||||
## Asynchronous clock groups
|
||||
|
||||
# MGT reference clocks are also async to everything.
|
||||
set_clock_groups -asynchronous -group [get_clocks mgt_clk_dba -include_generated_clocks]
|
||||
set_clock_groups -asynchronous -group [get_clocks mgt_clk_dbb -include_generated_clocks]
|
||||
|
||||
# fpga_clk_a and fpga_clk_b are related to one another after synchronization.
|
||||
# However, we do need to declare that these clocks (both a and b) and their children
|
||||
# are async to the remainder of the design. Use the wildcard at the end to grab the
|
||||
# virtual clock as well as the real ones.
|
||||
set_clock_groups -asynchronous -group [get_clocks {fpga_clk_a* fpga_clk_b*} -include_generated_clocks]
|
||||
|
||||
# The SPI readback and write clocks cannot be active at the same time, as they
|
||||
# originate from the same pin.
|
||||
set_clock_groups -physically_exclusive \
|
||||
-group [get_clocks pl_spi_rb_clk_a] \
|
||||
-group [get_clocks pl_spi_clk_a]
|
||||
set_clock_groups -physically_exclusive \
|
||||
-group [get_clocks pl_spi_rb_clk_b] \
|
||||
-group [get_clocks pl_spi_clk_b]
|
||||
|
||||
#*******************************************************************************
|
||||
## PS SPI: since these lines all come from the PS and I don't have access to the
|
||||
# driving clock (or anything for that matter), I'm left with constraining the maximum
|
||||
# and minimum delay on these lines, per a Xilinx AR:
|
||||
# https://www.xilinx.com/support/answers/62122.html
|
||||
set CPLD_SPI_OUTS [get_ports {DB*_CPLD_PS_SPI_SCLK \
|
||||
DB*_CPLD_PS_SPI_MOSI \
|
||||
DB*_CPLD_PS_SPI_CS_B \
|
||||
DB*_CLKDIS_SPI_CS_B \
|
||||
DB*_PHDAC_SPI_CS_B \
|
||||
DB*_ADC_SPI_CS_B \
|
||||
DB*_DAC_SPI_CS_B}]
|
||||
|
||||
# The actual min and max path delays before applying constraints were (from report_timing):
|
||||
# 3.332 ns (Min at Fast Process Corner)
|
||||
# 10.596 ns (Max at Slow Process Corner)
|
||||
# Therefore, we round those number to their immediate succesor respectively.
|
||||
# After implementation, the tools were unable to meet timing when leaving a 11 ns max
|
||||
# delay value, so it was incremented.
|
||||
set MIN_OUT_DELAY 3.0
|
||||
set MAX_OUT_DELAY 12.0
|
||||
|
||||
set_max_delay $MAX_OUT_DELAY -to $CPLD_SPI_OUTS
|
||||
set_min_delay $MIN_OUT_DELAY -to $CPLD_SPI_OUTS
|
||||
|
||||
# report_timing -to $CPLD_SPI_OUTS -max_paths 20 -delay_type min_max -name CpldSpiOutTiming
|
||||
|
||||
# The actual min and max path delays before applying constraints were (from report_timing):
|
||||
# 2.733 ns (Min at Fast Process Corner)
|
||||
# 6.071 ns (Max at Slow Process Corner)
|
||||
# Therefore, we round those number to their immediate succesor respectively.
|
||||
set MIN_IN_DELAY 2.0
|
||||
set MAX_IN_DELAY 10.0
|
||||
|
||||
set PS_SPI_INPUTS_0 [get_pins -hierarchical -filter {NAME =~ "*/PS7_i/EMIOSPI0MI"}]
|
||||
set PS_SPI_INPUTS_1 [get_pins -hierarchical -filter {NAME =~ "*/PS7_i/EMIOSPI1MI"}]
|
||||
|
||||
set_max_delay $MAX_IN_DELAY -to $PS_SPI_INPUTS_0
|
||||
set_min_delay $MIN_IN_DELAY -to $PS_SPI_INPUTS_0
|
||||
set_max_delay $MAX_IN_DELAY -to $PS_SPI_INPUTS_1
|
||||
set_min_delay $MIN_IN_DELAY -to $PS_SPI_INPUTS_1
|
||||
|
||||
# report_timing -to $PS_SPI_INPUTS_0 -max_paths 30 -delay_type min_max -nworst 30 -name Spi0InTiming
|
||||
# report_timing -to $PS_SPI_INPUTS_1 -max_paths 30 -delay_type min_max -nworst 30 -name Spi1InTiming
|
||||
|
||||
|
||||
|
||||
#*******************************************************************************
|
||||
## PL SPI to the CPLD
|
||||
#
|
||||
# All of these lines are driven or received from flops in simple_spi_core. The CPLD
|
||||
# calculations assume the FPGA has less than 6 ns of skew between the SCK and
|
||||
# SDI/CS_n. Pretty easy constraint to write! See above for the clock definition.
|
||||
# Do this for DBA and DBB independently.
|
||||
set MAX_SKEW 6.0
|
||||
set SETUP_SKEW [expr {$MAX_SKEW / 2}]
|
||||
set HOLD_SKEW [expr {$MAX_SKEW / 2}]
|
||||
# Do not set the output delay constraint on the clock line!
|
||||
set PORT_LIST_A [get_ports {DBA_CPLD_PL_SPI_CS_B \
|
||||
DBA_CPLD_PL_SPI_MOSI \
|
||||
DBA_TXLO_SPI_CS_B \
|
||||
DBA_RXLO_SPI_CS_B \
|
||||
DBA_LODIS_SPI_CS_B }]
|
||||
set PORT_LIST_B [get_ports {DBB_CPLD_PL_SPI_CS_B \
|
||||
DBB_CPLD_PL_SPI_MOSI \
|
||||
DBB_TXLO_SPI_CS_B \
|
||||
DBB_RXLO_SPI_CS_B \
|
||||
DBB_LODIS_SPI_CS_B }]
|
||||
# Then add the output delay on each of the ports.
|
||||
set_output_delay -clock [get_clocks pl_spi_clk_a] -max -$SETUP_SKEW $PORT_LIST_A
|
||||
set_output_delay -add_delay -clock_fall -clock [get_clocks pl_spi_clk_a] -max -$SETUP_SKEW $PORT_LIST_A
|
||||
set_output_delay -clock [get_clocks pl_spi_clk_a] -min $HOLD_SKEW $PORT_LIST_A
|
||||
set_output_delay -add_delay -clock_fall -clock [get_clocks pl_spi_clk_a] -min $HOLD_SKEW $PORT_LIST_A
|
||||
set_output_delay -clock [get_clocks pl_spi_clk_b] -max -$SETUP_SKEW $PORT_LIST_B
|
||||
set_output_delay -add_delay -clock_fall -clock [get_clocks pl_spi_clk_b] -max -$SETUP_SKEW $PORT_LIST_B
|
||||
set_output_delay -clock [get_clocks pl_spi_clk_b] -min $HOLD_SKEW $PORT_LIST_B
|
||||
set_output_delay -add_delay -clock_fall -clock [get_clocks pl_spi_clk_b] -min $HOLD_SKEW $PORT_LIST_B
|
||||
# Finally, make both the setup and hold checks use the same launching and latching edges.
|
||||
set_multicycle_path -setup -from [get_clocks radio_clk] -to [get_clocks pl_spi_clk_a] -start 0
|
||||
set_multicycle_path -hold -from [get_clocks radio_clk] -to [get_clocks pl_spi_clk_a] -1
|
||||
set_multicycle_path -setup -from [get_clocks radio_clk] -to [get_clocks pl_spi_clk_b] -start 0
|
||||
set_multicycle_path -hold -from [get_clocks radio_clk] -to [get_clocks pl_spi_clk_b] -1
|
||||
|
||||
# For SDO input timing (MISO), we need to look at the CPLD's constraints on turnaround
|
||||
# time plus any board propagation delay.
|
||||
# CPLD clk-to-q is 20 ns, then add 1.2 ns for board delay (once for clock, once for data)
|
||||
# For hold time, assume zero delay (likely overconstraining here, due to board delays)
|
||||
set MISO_INPUT_A [get_ports DBA_CPLD_PL_SPI_MISO]
|
||||
set MISO_INPUT_B [get_ports DBB_CPLD_PL_SPI_MISO]
|
||||
set_input_delay -clock [get_clocks pl_spi_rb_clk_a] -clock_fall -max 22.400 $MISO_INPUT_A
|
||||
set_input_delay -clock [get_clocks pl_spi_rb_clk_a] -clock_fall -min 0.000 $MISO_INPUT_A
|
||||
set_input_delay -clock [get_clocks pl_spi_rb_clk_b] -clock_fall -max 22.400 $MISO_INPUT_B
|
||||
set_input_delay -clock [get_clocks pl_spi_rb_clk_b] -clock_fall -min 0.000 $MISO_INPUT_B
|
||||
|
||||
# Since the input delay span is clearly more than a period of the radio_clk, we need to
|
||||
# add a multicycle path here as well to define the clock divider ratio. The MISO data
|
||||
# is driven on the falling edge of the SPI clock and captured on the rising edge, so we
|
||||
# only have one half of a SPI clock cycle for our setup. Hold is left alone and is OK
|
||||
# as-is due to the delays in the CPLD and board.
|
||||
set SETUP_CYCLES [expr {$PL_SPI_RB_DIVIDE_VAL / 2}]
|
||||
set HOLD_CYCLES 0
|
||||
set_multicycle_path -setup -from [get_clocks pl_spi_rb_clk_a] -through $MISO_INPUT_A \
|
||||
$SETUP_CYCLES
|
||||
set_multicycle_path -hold -from [get_clocks pl_spi_rb_clk_a] -through $MISO_INPUT_A -end \
|
||||
[expr {$SETUP_CYCLES + $HOLD_CYCLES - 1}]
|
||||
set_multicycle_path -setup -from [get_clocks pl_spi_rb_clk_b] -through $MISO_INPUT_B \
|
||||
$SETUP_CYCLES
|
||||
set_multicycle_path -hold -from [get_clocks pl_spi_rb_clk_b] -through $MISO_INPUT_B -end \
|
||||
[expr {$SETUP_CYCLES + $HOLD_CYCLES - 1}]
|
||||
|
||||
#*******************************************************************************
|
||||
## SYSREF/SYNC JESD Timing
|
||||
#
|
||||
# SYNC is async, SYSREF is tightly timed.
|
||||
|
||||
# The SYNC output (to ADC) for both DBs is governed by the JESD cores, which are solely
|
||||
# driven by DB-A clock... but it is an asynchronous signal so we use the async_out_clk.
|
||||
set_output_delay -clock [get_clocks async_out_clk] 0.000 [get_ports DB*_ADC_SYNCB_P]
|
||||
set_max_delay -to [get_ports DB*_ADC_SYNCB_P] 50.000
|
||||
set_min_delay -to [get_ports DB*_ADC_SYNCB_P] 0.000
|
||||
|
||||
# The SYNC input (from DAC) for both DBs is received by the DB-A clock inside the JESD
|
||||
# cores... but again, it is asynchronous and therefore uses the async_in_clk.
|
||||
set_input_delay -clock [get_clocks async_in_clk] 0.000 [get_ports DB*_DAC_SYNCB_P]
|
||||
set_max_delay -from [get_ports DB*_DAC_SYNCB_P] 50.000
|
||||
set_min_delay -from [get_ports DB*_DAC_SYNCB_P] 0.000
|
||||
|
||||
# SYSREF is driven by the LMK directly to the FPGA. Timing analysis was performed once
|
||||
# for the worst-case numbers across both DBs to produce one set of numbers for both DBs.
|
||||
# Since we easily meet setup and hold in Vivado, then this is an acceptable approach.
|
||||
# SYSREF is captured by the local clock from each DB, so we have two sets of constraints.
|
||||
set_input_delay -clock fpga_clk_a_v -min -0.479 [get_ports DBA_FPGA_SYSREF_*]
|
||||
set_input_delay -clock fpga_clk_a_v -max 0.661 [get_ports DBA_FPGA_SYSREF_*]
|
||||
|
||||
set_input_delay -clock fpga_clk_b_v -min -0.479 [get_ports DBB_FPGA_SYSREF_*]
|
||||
set_input_delay -clock fpga_clk_b_v -max 0.661 [get_ports DBB_FPGA_SYSREF_*]
|
||||
|
||||
|
||||
#*******************************************************************************
|
||||
## PPS Timing
|
||||
|
||||
# Due to the N3xx synchronization and clocking structure, the PPS output is driven from
|
||||
# the Sample Clock domain instead of the input Reference Clock. Constrain the output as
|
||||
# tightly as possible to accurately mimic the internal Sample Clock timing.
|
||||
set SETUP_SKEW 2.0
|
||||
set HOLD_SKEW -0.5
|
||||
set_output_delay -clock [get_clocks fpga_clk_a_v] -max -$SETUP_SKEW [get_ports REF_1PPS_OUT]
|
||||
set_output_delay -clock [get_clocks fpga_clk_a_v] -min $HOLD_SKEW [get_ports REF_1PPS_OUT]
|
||||
set_multicycle_path -setup -to [get_ports REF_1PPS_OUT] -start 0
|
||||
set_multicycle_path -hold -to [get_ports REF_1PPS_OUT] -1
|
||||
|
||||
#*******************************************************************************
|
||||
### Async I/Os
|
||||
set DB_ASYNC_OUTPUTS [get_ports {
|
||||
DB*_MODULE_PWR_ENABLE
|
||||
DB*_RF_PWR_ENABLE
|
||||
DB*_CLKDIST_SYNC
|
||||
DB*_ATR_TX
|
||||
DB*_ATR_RX
|
||||
DB*_TXRX_SW_CTRL_1
|
||||
DB*_TXRX_SW_CTRL_2
|
||||
DB*_LED_RX
|
||||
DB*_LED_RX2
|
||||
DB*_LED_TX
|
||||
QSFP_I2C_*
|
||||
}]
|
||||
set_output_delay -clock [get_clocks async_out_clk] 0.000 $DB_ASYNC_OUTPUTS
|
||||
set_max_delay -to $DB_ASYNC_OUTPUTS 50.000
|
||||
set_min_delay -to $DB_ASYNC_OUTPUTS 0.000
|
||||
|
||||
set_input_delay -clock [get_clocks async_in_clk] 0.000 [get_ports QSFP_I2C_*]
|
||||
set_max_delay -from [get_ports QSFP_I2C_*] 50.000
|
||||
set_min_delay -from [get_ports QSFP_I2C_*] 0.000
|
||||
|
||||
#*******************************************************************************
|
||||
## JTAG
|
||||
|
||||
## MAX 10 JTAG TDI setup: 2 ns
|
||||
## MAX 10 JTAG TMS setup: 3 ns
|
||||
## MAX 10 JTAG hold: 10 ns
|
||||
## MAX 10 JTAG clk-to-q: 18 ns
|
||||
## Board delay: < 1.5 ns
|
||||
##
|
||||
## Setup time = Board delay + TMS setup = 3 ns + 1.5 ns = 4.5 ns
|
||||
## Hold time = Board delay + TMS hold = 1.5 ns + 10 ns = 11.5 ns
|
||||
## Overconstrain output delay and keep skew to +/- 8 ns
|
||||
##
|
||||
## Input delay = 2x Board delay + clk-to-q = 3 ns + 18 ns = 21 ns
|
||||
|
||||
# Constrain outputs for skew, with same latch/launch edge:
|
||||
set_output_delay -clock [get_clocks dba_jtag_tck] -max -4.0 \
|
||||
[get_ports {DBA_CPLD_JTAG_TDI DBA_CPLD_JTAG_TMS}]
|
||||
set_output_delay -add_delay -clock_fall -clock [get_clocks dba_jtag_tck] -max -4.0 \
|
||||
[get_ports {DBA_CPLD_JTAG_TDI DBA_CPLD_JTAG_TMS}]
|
||||
set_output_delay -clock [get_clocks dba_jtag_tck] -min 4.0 \
|
||||
[get_ports {DBA_CPLD_JTAG_TDI DBA_CPLD_JTAG_TMS}]
|
||||
set_output_delay -add_delay -clock_fall -clock [get_clocks dba_jtag_tck] -min 4.0 \
|
||||
[get_ports {DBA_CPLD_JTAG_TDI DBA_CPLD_JTAG_TMS}]
|
||||
set_output_delay -clock [get_clocks dbb_jtag_tck] -max -4.0 \
|
||||
[get_ports {DBB_CPLD_JTAG_TDI DBB_CPLD_JTAG_TMS}]
|
||||
set_output_delay -add_delay -clock_fall -clock [get_clocks dbb_jtag_tck] -max -4.0 \
|
||||
[get_ports {DBB_CPLD_JTAG_TDI DBB_CPLD_JTAG_TMS}]
|
||||
set_output_delay -clock [get_clocks dbb_jtag_tck] -min 4.0 \
|
||||
[get_ports {DBB_CPLD_JTAG_TDI DBB_CPLD_JTAG_TMS}]
|
||||
set_output_delay -add_delay -clock_fall -clock [get_clocks dbb_jtag_tck] -min 4.0 \
|
||||
[get_ports {DBB_CPLD_JTAG_TDI DBB_CPLD_JTAG_TMS}]
|
||||
# Finally, make both the setup and hold checks use the same launching and latching edges.
|
||||
set_multicycle_path -setup -from [get_clocks clk40] -to [get_clocks dba_jtag_tck] -start 0
|
||||
set_multicycle_path -hold -from [get_clocks clk40] -to [get_clocks dba_jtag_tck] -1
|
||||
set_multicycle_path -setup -from [get_clocks clk40] -to [get_clocks dbb_jtag_tck] -start 0
|
||||
set_multicycle_path -hold -from [get_clocks clk40] -to [get_clocks dbb_jtag_tck] -1
|
||||
|
||||
set_input_delay -clock [get_clocks dba_jtag_tck] -clock_fall -max 21 \
|
||||
[get_ports DBA_CPLD_JTAG_TDO]
|
||||
set_input_delay -clock [get_clocks dba_jtag_tck] -clock_fall -min 0 \
|
||||
[get_ports DBA_CPLD_JTAG_TDO]
|
||||
set_input_delay -clock [get_clocks dbb_jtag_tck] -clock_fall -max 21 \
|
||||
[get_ports DBB_CPLD_JTAG_TDO]
|
||||
set_input_delay -clock [get_clocks dbb_jtag_tck] -clock_fall -min 0 \
|
||||
[get_ports DBB_CPLD_JTAG_TDO]
|
||||
# Inputs have setup checks relative to half a period of TCK (launch on fall,
|
||||
# latch on rise). Actual latch clock is faster, so push back setup and hold
|
||||
# checks to match.
|
||||
set_multicycle_path -setup -from [get_clocks dba_jtag_tck] \
|
||||
-through [get_ports DBA_CPLD_JTAG_TDO] \
|
||||
[expr {$DB_JTAG_DIVISOR / 2}]
|
||||
set_multicycle_path -end -hold -from [get_clocks dba_jtag_tck] \
|
||||
-through [get_ports DBA_CPLD_JTAG_TDO] \
|
||||
[expr {$DB_JTAG_DIVISOR - 1}]
|
||||
set_multicycle_path -setup -from [get_clocks dbb_jtag_tck] \
|
||||
-through [get_ports DBB_CPLD_JTAG_TDO] \
|
||||
[expr {$DB_JTAG_DIVISOR / 2}]
|
||||
set_multicycle_path -end -hold -from [get_clocks dbb_jtag_tck] \
|
||||
-through [get_ports DBB_CPLD_JTAG_TDO] \
|
||||
[expr {$DB_JTAG_DIVISOR - 1}]
|
||||
Executable
BIN
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"warning": { "ignore": ["."]}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,588 @@
|
||||
/*
|
||||
* Copyright (c) 2017 National Instruments Corp
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0 OR X11
|
||||
*/
|
||||
|
||||
&fpga_full {
|
||||
tx_dma0: dma@43CA0000 {
|
||||
compatible = "adi,axi-dmac-1.00.a";
|
||||
reg = <0x43CA0000 0x10000>;
|
||||
interrupts = <0 53 4>;
|
||||
interrupt-parent = <&intc>;
|
||||
clocks = <&clkc 15>;
|
||||
#dma-cells = <1>;
|
||||
adi,channels {
|
||||
#size-cells = <0>;
|
||||
#address-cells = <1>;
|
||||
dma-channel@0 {
|
||||
reg = <0>;
|
||||
adi,source-bus-type = <0>;
|
||||
adi,source-bus-width = <0x20>;
|
||||
adi,destination-bus-type = <1>;
|
||||
adi,destination-bus-width = <0x20>;
|
||||
adi,length-width = <24>;
|
||||
};
|
||||
};
|
||||
};
|
||||
tx_dma1: dma@43CB0000 {
|
||||
compatible = "adi,axi-dmac-1.00.a";
|
||||
reg = <0x43CB0000 0x10000>;
|
||||
interrupts = <0 53 4>;
|
||||
interrupt-parent = <&intc>;
|
||||
clocks = <&clkc 15>;
|
||||
#dma-cells = <1>;
|
||||
adi,channels {
|
||||
#size-cells = <0>;
|
||||
#address-cells = <1>;
|
||||
dma-channel@0 {
|
||||
reg = <0>;
|
||||
adi,source-bus-type = <0>;
|
||||
adi,source-bus-width = <0x20>;
|
||||
adi,destination-bus-type = <1>;
|
||||
adi,destination-bus-width = <0x20>;
|
||||
adi,length-width = <24>;
|
||||
};
|
||||
};
|
||||
};
|
||||
tx_dma2: dma@43CC0000 {
|
||||
compatible = "adi,axi-dmac-1.00.a";
|
||||
reg = <0x43CC0000 0x10000>;
|
||||
interrupts = <0 53 4>;
|
||||
interrupt-parent = <&intc>;
|
||||
clocks = <&clkc 15>;
|
||||
#dma-cells = <1>;
|
||||
adi,channels {
|
||||
#size-cells = <0>;
|
||||
#address-cells = <1>;
|
||||
dma-channel@0 {
|
||||
reg = <0>;
|
||||
adi,source-bus-type = <0>;
|
||||
adi,source-bus-width = <0x20>;
|
||||
adi,destination-bus-type = <1>;
|
||||
adi,destination-bus-width = <0x20>;
|
||||
adi,length-width = <24>;
|
||||
};
|
||||
};
|
||||
};
|
||||
tx_dma3: dma@43CD0000 {
|
||||
compatible = "adi,axi-dmac-1.00.a";
|
||||
reg = <0x43CD0000 0x10000>;
|
||||
interrupts = <0 53 4>;
|
||||
interrupt-parent = <&intc>;
|
||||
clocks = <&clkc 15>;
|
||||
#dma-cells = <1>;
|
||||
adi,channels {
|
||||
#size-cells = <0>;
|
||||
#address-cells = <1>;
|
||||
dma-channel@0 {
|
||||
reg = <0>;
|
||||
adi,source-bus-type = <0>;
|
||||
adi,source-bus-width = <0x20>;
|
||||
adi,destination-bus-type = <1>;
|
||||
adi,destination-bus-width = <0x20>;
|
||||
adi,length-width = <24>;
|
||||
};
|
||||
};
|
||||
};
|
||||
tx_dma4: dma@43CE0000 {
|
||||
compatible = "adi,axi-dmac-1.00.a";
|
||||
reg = <0x43CE0000 0x10000>;
|
||||
interrupts = <0 53 4>;
|
||||
interrupt-parent = <&intc>;
|
||||
clocks = <&clkc 15>;
|
||||
#dma-cells = <1>;
|
||||
adi,channels {
|
||||
#size-cells = <0>;
|
||||
#address-cells = <1>;
|
||||
dma-channel@0 {
|
||||
reg = <0>;
|
||||
adi,source-bus-type = <0>;
|
||||
adi,source-bus-width = <0x20>;
|
||||
adi,destination-bus-type = <1>;
|
||||
adi,destination-bus-width = <0x20>;
|
||||
adi,length-width = <24>;
|
||||
};
|
||||
};
|
||||
};
|
||||
tx_dma5: dma@43CF0000 {
|
||||
compatible = "adi,axi-dmac-1.00.a";
|
||||
reg = <0x43CF0000 0x10000>;
|
||||
interrupts = <0 53 4>;
|
||||
interrupt-parent = <&intc>;
|
||||
clocks = <&clkc 15>;
|
||||
#dma-cells = <1>;
|
||||
adi,channels {
|
||||
#size-cells = <0>;
|
||||
#address-cells = <1>;
|
||||
dma-channel@0 {
|
||||
reg = <0>;
|
||||
adi,source-bus-type = <0>;
|
||||
adi,source-bus-width = <0x20>;
|
||||
adi,destination-bus-type = <1>;
|
||||
adi,destination-bus-width = <0x20>;
|
||||
adi,length-width = <24>;
|
||||
};
|
||||
};
|
||||
};
|
||||
tx_dma6: dma@43D00000 {
|
||||
compatible = "adi,axi-dmac-1.00.a";
|
||||
reg = <0x43D00000 0x10000>;
|
||||
interrupts = <0 53 4>;
|
||||
interrupt-parent = <&intc>;
|
||||
clocks = <&clkc 15>;
|
||||
#dma-cells = <1>;
|
||||
adi,channels {
|
||||
#size-cells = <0>;
|
||||
#address-cells = <1>;
|
||||
dma-channel@0 {
|
||||
reg = <0>;
|
||||
adi,source-bus-type = <0>;
|
||||
adi,source-bus-width = <0x20>;
|
||||
adi,destination-bus-type = <1>;
|
||||
adi,destination-bus-width = <0x20>;
|
||||
adi,length-width = <24>;
|
||||
};
|
||||
};
|
||||
};
|
||||
tx_dma7: dma@43D10000 {
|
||||
compatible = "adi,axi-dmac-1.00.a";
|
||||
reg = <0x43D10000 0x10000>;
|
||||
interrupts = <0 53 4>;
|
||||
interrupt-parent = <&intc>;
|
||||
clocks = <&clkc 15>;
|
||||
#dma-cells = <1>;
|
||||
adi,channels {
|
||||
#size-cells = <0>;
|
||||
#address-cells = <1>;
|
||||
dma-channel@0 {
|
||||
reg = <0>;
|
||||
adi,source-bus-type = <0>;
|
||||
adi,source-bus-width = <0x20>;
|
||||
adi,destination-bus-type = <1>;
|
||||
adi,destination-bus-width = <0x20>;
|
||||
adi,length-width = <24>;
|
||||
};
|
||||
};
|
||||
};
|
||||
tx_dma8: dma@43D20000 {
|
||||
compatible = "adi,axi-dmac-1.00.a";
|
||||
reg = <0x43D20000 0x10000>;
|
||||
interrupts = <0 53 4>;
|
||||
interrupt-parent = <&intc>;
|
||||
clocks = <&clkc 15>;
|
||||
#dma-cells = <1>;
|
||||
adi,channels {
|
||||
#size-cells = <0>;
|
||||
#address-cells = <1>;
|
||||
dma-channel@0 {
|
||||
reg = <0>;
|
||||
adi,source-bus-type = <0>;
|
||||
adi,source-bus-width = <0x20>;
|
||||
adi,destination-bus-type = <1>;
|
||||
adi,destination-bus-width = <0x20>;
|
||||
adi,length-width = <24>;
|
||||
};
|
||||
};
|
||||
};
|
||||
tx_dma9: dma@43D30000 {
|
||||
compatible = "adi,axi-dmac-1.00.a";
|
||||
reg = <0x43D30000 0x10000>;
|
||||
interrupts = <0 53 4>;
|
||||
interrupt-parent = <&intc>;
|
||||
clocks = <&clkc 15>;
|
||||
#dma-cells = <1>;
|
||||
adi,channels {
|
||||
#size-cells = <0>;
|
||||
#address-cells = <1>;
|
||||
dma-channel@0 {
|
||||
reg = <0>;
|
||||
adi,source-bus-type = <0>;
|
||||
adi,source-bus-width = <0x20>;
|
||||
adi,destination-bus-type = <1>;
|
||||
adi,destination-bus-width = <0x20>;
|
||||
adi,length-width = <24>;
|
||||
};
|
||||
};
|
||||
};
|
||||
rx_dma0: dma@43C00000 {
|
||||
compatible = "adi,axi-dmac-1.00.a";
|
||||
reg = <0x43C00000 0x10000>;
|
||||
interrupts = <0 52 4>;
|
||||
interrupt-parent = <&intc>;
|
||||
clocks = <&clkc 15>;
|
||||
#dma-cells = <1>;
|
||||
adi,channels {
|
||||
#size-cells = <0>;
|
||||
#address-cells = <1>;
|
||||
dma-channel@0 {
|
||||
reg = <0>;
|
||||
adi,source-bus-type = <1>;
|
||||
adi,source-bus-width = <0x20>;
|
||||
adi,destination-bus-type = <0>;
|
||||
adi,destination-bus-width = <0x20>;
|
||||
adi,length-width = <24>;
|
||||
};
|
||||
};
|
||||
};
|
||||
rx_dma1: dma@43C10000 {
|
||||
compatible = "adi,axi-dmac-1.00.a";
|
||||
reg = <0x43C10000 0x10000>;
|
||||
interrupts = <0 52 4>;
|
||||
interrupt-parent = <&intc>;
|
||||
clocks = <&clkc 15>;
|
||||
#dma-cells = <1>;
|
||||
adi,channels {
|
||||
#size-cells = <0>;
|
||||
#address-cells = <1>;
|
||||
dma-channel@0 {
|
||||
reg = <0>;
|
||||
adi,source-bus-type = <1>;
|
||||
adi,source-bus-width = <0x20>;
|
||||
adi,destination-bus-type = <0>;
|
||||
adi,destination-bus-width = <0x20>;
|
||||
adi,length-width = <24>;
|
||||
};
|
||||
};
|
||||
};
|
||||
rx_dma2: dma@43C20000 {
|
||||
compatible = "adi,axi-dmac-1.00.a";
|
||||
reg = <0x43C20000 0x10000>;
|
||||
interrupts = <0 52 4>;
|
||||
interrupt-parent = <&intc>;
|
||||
clocks = <&clkc 15>;
|
||||
#dma-cells = <1>;
|
||||
adi,channels {
|
||||
#size-cells = <0>;
|
||||
#address-cells = <1>;
|
||||
dma-channel@0 {
|
||||
reg = <0>;
|
||||
adi,source-bus-type = <1>;
|
||||
adi,source-bus-width = <0x20>;
|
||||
adi,destination-bus-type = <0>;
|
||||
adi,destination-bus-width = <0x20>;
|
||||
adi,length-width = <24>;
|
||||
};
|
||||
};
|
||||
};
|
||||
rx_dma3: dma@43C30000 {
|
||||
compatible = "adi,axi-dmac-1.00.a";
|
||||
reg = <0x43C30000 0x10000>;
|
||||
interrupts = <0 52 4>;
|
||||
interrupt-parent = <&intc>;
|
||||
clocks = <&clkc 15>;
|
||||
#dma-cells = <1>;
|
||||
adi,channels {
|
||||
#size-cells = <0>;
|
||||
#address-cells = <1>;
|
||||
dma-channel@0 {
|
||||
reg = <0>;
|
||||
adi,source-bus-type = <1>;
|
||||
adi,source-bus-width = <0x20>;
|
||||
adi,destination-bus-type = <0>;
|
||||
adi,destination-bus-width = <0x20>;
|
||||
adi,length-width = <24>;
|
||||
};
|
||||
};
|
||||
};
|
||||
rx_dma4: dma@43C40000 {
|
||||
compatible = "adi,axi-dmac-1.00.a";
|
||||
reg = <0x43C40000 0x10000>;
|
||||
interrupts = <0 52 4>;
|
||||
interrupt-parent = <&intc>;
|
||||
clocks = <&clkc 15>;
|
||||
#dma-cells = <1>;
|
||||
adi,channels {
|
||||
#size-cells = <0>;
|
||||
#address-cells = <1>;
|
||||
dma-channel@0 {
|
||||
reg = <0>;
|
||||
adi,source-bus-type = <1>;
|
||||
adi,source-bus-width = <0x20>;
|
||||
adi,destination-bus-type = <0>;
|
||||
adi,destination-bus-width = <0x20>;
|
||||
adi,length-width = <24>;
|
||||
};
|
||||
};
|
||||
};
|
||||
rx_dma5: dma@43C50000 {
|
||||
compatible = "adi,axi-dmac-1.00.a";
|
||||
reg = <0x43C50000 0x10000>;
|
||||
interrupts = <0 52 4>;
|
||||
interrupt-parent = <&intc>;
|
||||
clocks = <&clkc 15>;
|
||||
#dma-cells = <1>;
|
||||
adi,channels {
|
||||
#size-cells = <0>;
|
||||
#address-cells = <1>;
|
||||
dma-channel@0 {
|
||||
reg = <0>;
|
||||
adi,source-bus-type = <1>;
|
||||
adi,source-bus-width = <0x20>;
|
||||
adi,destination-bus-type = <0>;
|
||||
adi,destination-bus-width = <0x20>;
|
||||
adi,length-width = <24>;
|
||||
};
|
||||
};
|
||||
};
|
||||
rx_dma6: dma@43C60000 {
|
||||
compatible = "adi,axi-dmac-1.00.a";
|
||||
reg = <0x43C60000 0x10000>;
|
||||
interrupts = <0 52 4>;
|
||||
interrupt-parent = <&intc>;
|
||||
clocks = <&clkc 15>;
|
||||
#dma-cells = <1>;
|
||||
adi,channels {
|
||||
#size-cells = <0>;
|
||||
#address-cells = <1>;
|
||||
dma-channel@0 {
|
||||
reg = <0>;
|
||||
adi,source-bus-type = <1>;
|
||||
adi,source-bus-width = <0x20>;
|
||||
adi,destination-bus-type = <0>;
|
||||
adi,destination-bus-width = <0x20>;
|
||||
adi,length-width = <24>;
|
||||
};
|
||||
};
|
||||
};
|
||||
rx_dma7: dma@43C70000 {
|
||||
compatible = "adi,axi-dmac-1.00.a";
|
||||
reg = <0x43C70000 0x10000>;
|
||||
interrupts = <0 52 4>;
|
||||
interrupt-parent = <&intc>;
|
||||
clocks = <&clkc 15>;
|
||||
#dma-cells = <1>;
|
||||
adi,channels {
|
||||
#size-cells = <0>;
|
||||
#address-cells = <1>;
|
||||
dma-channel@0 {
|
||||
reg = <0>;
|
||||
adi,source-bus-type = <1>;
|
||||
adi,source-bus-width = <0x20>;
|
||||
adi,destination-bus-type = <0>;
|
||||
adi,destination-bus-width = <0x20>;
|
||||
adi,length-width = <24>;
|
||||
};
|
||||
};
|
||||
};
|
||||
rx_dma8: dma@43C80000 {
|
||||
compatible = "adi,axi-dmac-1.00.a";
|
||||
reg = <0x43C80000 0x10000>;
|
||||
interrupts = <0 52 4>;
|
||||
interrupt-parent = <&intc>;
|
||||
clocks = <&clkc 15>;
|
||||
#dma-cells = <1>;
|
||||
adi,channels {
|
||||
#size-cells = <0>;
|
||||
#address-cells = <1>;
|
||||
dma-channel@0 {
|
||||
reg = <0>;
|
||||
adi,source-bus-type = <1>;
|
||||
adi,source-bus-width = <0x20>;
|
||||
adi,destination-bus-type = <0>;
|
||||
adi,destination-bus-width = <0x20>;
|
||||
adi,length-width = <24>;
|
||||
};
|
||||
};
|
||||
};
|
||||
rx_dma9: dma@43C90000 {
|
||||
compatible = "adi,axi-dmac-1.00.a";
|
||||
reg = <0x43C90000 0x10000>;
|
||||
interrupts = <0 52 4>;
|
||||
interrupt-parent = <&intc>;
|
||||
clocks = <&clkc 15>;
|
||||
#dma-cells = <1>;
|
||||
adi,channels {
|
||||
#size-cells = <0>;
|
||||
#address-cells = <1>;
|
||||
dma-channel@0 {
|
||||
reg = <0>;
|
||||
adi,source-bus-type = <1>;
|
||||
adi,source-bus-width = <0x20>;
|
||||
adi,destination-bus-type = <0>;
|
||||
adi,destination-bus-width = <0x20>;
|
||||
adi,length-width = <24>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
usrp_rx_dma0: usrp-rx-dma@43c00000 {
|
||||
compatible = "ettus,usrp-rx-dma";
|
||||
dmas = <&rx_dma0 0>;
|
||||
dma-names = "dma";
|
||||
port-id = <0>;
|
||||
status = "okay";
|
||||
|
||||
regmap = <&dma_conf0>;
|
||||
offset = <0x0>;
|
||||
};
|
||||
|
||||
usrp_rx_dma1: usrp-rx-dma@43c10000 {
|
||||
compatible = "ettus,usrp-rx-dma";
|
||||
dmas = <&rx_dma1 0>;
|
||||
dma-names = "dma";
|
||||
port-id = <1>;
|
||||
|
||||
regmap = <&dma_conf0>;
|
||||
offset = <0x4>;
|
||||
};
|
||||
|
||||
usrp_rx_dma2: usrp-rx-dma@43c20000 {
|
||||
compatible = "ettus,usrp-rx-dma";
|
||||
dmas = <&rx_dma2 0>;
|
||||
dma-names = "dma";
|
||||
port-id = <2>;
|
||||
|
||||
regmap = <&dma_conf0>;
|
||||
offset = <0x8>;
|
||||
};
|
||||
|
||||
usrp_rx_dma3: usrp-rx-dma@43c30000 {
|
||||
compatible = "ettus,usrp-rx-dma";
|
||||
dmas = <&rx_dma3 0>;
|
||||
dma-names = "dma";
|
||||
port-id = <3>;
|
||||
|
||||
regmap = <&dma_conf0>;
|
||||
offset = <0xc>;
|
||||
};
|
||||
|
||||
usrp_rx_dma4: usrp-rx-dma@43c40000 {
|
||||
compatible = "ettus,usrp-rx-dma";
|
||||
dmas = <&rx_dma4 0>;
|
||||
dma-names = "dma";
|
||||
port-id = <4>;
|
||||
|
||||
regmap = <&dma_conf0>;
|
||||
offset = <0x10>;
|
||||
};
|
||||
|
||||
usrp_rx_dma5: usrp-rx-dma@43c50000 {
|
||||
compatible = "ettus,usrp-rx-dma";
|
||||
dmas = <&rx_dma5 0>;
|
||||
dma-names = "dma";
|
||||
port-id = <5>;
|
||||
|
||||
regmap = <&dma_conf0>;
|
||||
offset = <0x14>;
|
||||
};
|
||||
|
||||
usrp_rx_dma6: usrp-rx-dma@43c60000 {
|
||||
compatible = "ettus,usrp-rx-dma";
|
||||
dmas = <&rx_dma6 0>;
|
||||
dma-names = "dma";
|
||||
port-id = <6>;
|
||||
|
||||
regmap = <&dma_conf0>;
|
||||
offset = <0x18>;
|
||||
};
|
||||
|
||||
usrp_rx_dma7: usrp-rx-dma@43c70000 {
|
||||
compatible = "ettus,usrp-rx-dma";
|
||||
dmas = <&rx_dma7 0>;
|
||||
dma-names = "dma";
|
||||
port-id = <7>;
|
||||
|
||||
regmap = <&dma_conf0>;
|
||||
offset = <0x1c>;
|
||||
};
|
||||
|
||||
usrp_rx_dma8: usrp-rx-dma@43c80000 {
|
||||
compatible = "ettus,usrp-rx-dma";
|
||||
dmas = <&rx_dma8 0>;
|
||||
dma-names = "dma";
|
||||
port-id = <8>;
|
||||
|
||||
regmap = <&dma_conf0>;
|
||||
offset = <0x20>;
|
||||
};
|
||||
|
||||
usrp_rx_dma9: usrp-rx-dma@43c90000 {
|
||||
compatible = "ettus,usrp-rx-dma";
|
||||
dmas = <&rx_dma9 0>;
|
||||
dma-names = "dma";
|
||||
port-id = <9>;
|
||||
|
||||
regmap = <&dma_conf0>;
|
||||
offset = <0x24>;
|
||||
};
|
||||
|
||||
usrp_tx_dma0: usrp-tx-dma@43ca0000 {
|
||||
compatible = "ettus,usrp-tx-dma";
|
||||
dmas = <&tx_dma0 0>;
|
||||
dma-names = "dma";
|
||||
port-id = <0>;
|
||||
};
|
||||
|
||||
usrp_tx_dma1: usrp-tx-dma@43cb0000 {
|
||||
compatible = "ettus,usrp-tx-dma";
|
||||
dmas = <&tx_dma1 0>;
|
||||
dma-names = "dma";
|
||||
port-id = <1>;
|
||||
};
|
||||
|
||||
usrp_tx_dma2: usrp-tx-dma@43cc0000 {
|
||||
compatible = "ettus,usrp-tx-dma";
|
||||
dmas = <&tx_dma2 0>;
|
||||
dma-names = "dma";
|
||||
port-id = <2>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
usrp_tx_dma3: usrp-tx-dma@43cd0000 {
|
||||
compatible = "ettus,usrp-tx-dma";
|
||||
dmas = <&tx_dma3 0>;
|
||||
dma-names = "dma";
|
||||
port-id = <3>;
|
||||
};
|
||||
|
||||
usrp_tx_dma4: usrp-tx-dma@43ce0000 {
|
||||
compatible = "ettus,usrp-tx-dma";
|
||||
dmas = <&tx_dma4 0>;
|
||||
dma-names = "dma";
|
||||
port-id = <4>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
usrp_tx_dma5: usrp-tx-dma@43cf0000 {
|
||||
compatible = "ettus,usrp-tx-dma";
|
||||
dmas = <&tx_dma5 0>;
|
||||
dma-names = "dma";
|
||||
port-id = <5>;
|
||||
};
|
||||
|
||||
usrp_tx_dma6: usrp-tx-dma@43d00000 {
|
||||
compatible = "ettus,usrp-tx-dma";
|
||||
dmas = <&tx_dma6 0>;
|
||||
dma-names = "dma";
|
||||
port-id = <6>;
|
||||
};
|
||||
|
||||
usrp_tx_dma7: usrp-tx-dma@43d10000 {
|
||||
compatible = "ettus,usrp-tx-dma";
|
||||
dmas = <&tx_dma7 0>;
|
||||
dma-names = "dma";
|
||||
port-id = <7>;
|
||||
};
|
||||
|
||||
usrp_tx_dma8: usrp-tx-dma@43d20000 {
|
||||
compatible = "ettus,usrp-tx-dma";
|
||||
dmas = <&tx_dma8 0>;
|
||||
dma-names = "dma";
|
||||
port-id = <8>;
|
||||
};
|
||||
|
||||
usrp_tx_dma9: usrp-tx-dma@43d30000 {
|
||||
compatible = "ettus,usrp-tx-dma";
|
||||
dmas = <&tx_dma9 0>;
|
||||
dma-names = "dma";
|
||||
port-id = <9>;
|
||||
};
|
||||
|
||||
dma_conf0: dma_conf0@42080000 {
|
||||
compatible = "syscon";
|
||||
reg = <0x42080000 0x1000>;
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2017 National Instruments Corp
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0 OR X11
|
||||
*/
|
||||
|
||||
&fpga_full {
|
||||
uio@40010000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x40010000 0x2000>;
|
||||
reg-names = "mboard-regs";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
uio@40014000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x40014000 0x4000>;
|
||||
reg-names = "dboard-regs-0";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
uio@42100000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x42100000 0x1000>;
|
||||
reg-names = "dboard-jtag-0";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
&spi0 {
|
||||
status = "okay";
|
||||
|
||||
cs-gpios = <0>, <0>, <0>, <&gpio0 62 0>;
|
||||
|
||||
spidev0: spidev@0 {
|
||||
compatible = "rohm,dh2228fv";
|
||||
reg = <0>;
|
||||
status = "okay";
|
||||
spi-max-frequency = <1000000>;
|
||||
};
|
||||
|
||||
spidev1: spidev@1 {
|
||||
compatible = "rohm,dh2228fv";
|
||||
reg = <1>;
|
||||
status = "okay";
|
||||
spi-max-frequency = <1000000>;
|
||||
};
|
||||
|
||||
spidev2: spidev@2 {
|
||||
compatible = "rohm,dh2228fv";
|
||||
reg = <2>;
|
||||
status = "okay";
|
||||
spi-max-frequency = <1000000>;
|
||||
};
|
||||
|
||||
spidev3: spidev@3 {
|
||||
compatible = "rohm,dh2228fv";
|
||||
reg = <3>;
|
||||
status = "okay";
|
||||
spi-max-frequency = <1000000>;
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR X11
|
||||
/*
|
||||
* Copyright (c) 2017 National Instruments Corp
|
||||
*/
|
||||
|
||||
&fpga_full {
|
||||
firmware-name = "n300.bin";
|
||||
};
|
||||
@@ -0,0 +1,110 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR X11
|
||||
/*
|
||||
* Copyright (c) 2017 National Instruments Corp
|
||||
*/
|
||||
|
||||
&fpga_full {
|
||||
uio@40010000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x40010000 0x2000>;
|
||||
reg-names = "mboard-regs";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
uio@40014000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x40014000 0x4000>;
|
||||
reg-names = "dboard-regs-0";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
uio@40018000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x40018000 0x4000>;
|
||||
reg-names = "dboard-regs-1";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
uio@42100000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x42100000 0x1000>;
|
||||
reg-names = "dboard-jtag-0";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
uio@42200000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x42200000 0x1000>;
|
||||
reg-names = "dboard-jtag-1";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
&spi0 {
|
||||
status = "okay";
|
||||
|
||||
cs-gpios = <0>, <0>, <0>, <&gpio0 62 0>;
|
||||
|
||||
spidev0: spidev@0 {
|
||||
compatible = "rohm,dh2228fv";
|
||||
reg = <0>;
|
||||
status = "okay";
|
||||
spi-max-frequency = <1000000>;
|
||||
};
|
||||
|
||||
spidev1: spidev@1 {
|
||||
compatible = "rohm,dh2228fv";
|
||||
reg = <1>;
|
||||
status = "okay";
|
||||
spi-max-frequency = <1000000>;
|
||||
};
|
||||
|
||||
spidev2: spidev@2 {
|
||||
compatible = "rohm,dh2228fv";
|
||||
reg = <2>;
|
||||
status = "okay";
|
||||
spi-max-frequency = <1000000>;
|
||||
};
|
||||
|
||||
spidev3: spidev@3 {
|
||||
compatible = "rohm,dh2228fv";
|
||||
reg = <3>;
|
||||
status = "okay";
|
||||
spi-max-frequency = <1000000>;
|
||||
};
|
||||
};
|
||||
|
||||
&spi1 {
|
||||
status = "okay";
|
||||
|
||||
cs-gpios = <0>, <0>, <0>, <&gpio0 63 0>;
|
||||
|
||||
spidev4: spidev@0 {
|
||||
compatible = "rohm,dh2228fv";
|
||||
reg = <0>;
|
||||
status = "okay";
|
||||
spi-max-frequency = <1000000>;
|
||||
};
|
||||
|
||||
spidev5: spidev@1 {
|
||||
compatible = "rohm,dh2228fv";
|
||||
reg = <1>;
|
||||
status = "okay";
|
||||
spi-max-frequency = <1000000>;
|
||||
};
|
||||
|
||||
spidev6: spidev@2 {
|
||||
compatible = "rohm,dh2228fv";
|
||||
reg = <2>;
|
||||
status = "okay";
|
||||
spi-max-frequency = <1000000>;
|
||||
};
|
||||
|
||||
spidev7: spidev@3 {
|
||||
compatible = "rohm,dh2228fv";
|
||||
reg = <3>;
|
||||
status = "okay";
|
||||
spi-max-frequency = <1000000>;
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR X11
|
||||
/*
|
||||
* Copyright (c) 2017 National Instruments Corp
|
||||
*/
|
||||
|
||||
&fpga_full {
|
||||
firmware-name = "n310.bin";
|
||||
};
|
||||
@@ -0,0 +1,132 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR X11
|
||||
/*
|
||||
* Copyright (c) 2018 National Instruments Corp
|
||||
*/
|
||||
|
||||
&fpga_full {
|
||||
uio@40010000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x40010000 0x2000>;
|
||||
reg-names = "mboard-regs";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
uio@40014000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x40014000 0x4000>;
|
||||
reg-names = "dboard-regs-0";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
uio@40018000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x40018000 0x4000>;
|
||||
reg-names = "dboard-regs-1";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
uio@42100000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x42100000 0x1000>;
|
||||
reg-names = "dboard-jtag-0";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
uio@42200000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x42200000 0x1000>;
|
||||
reg-names = "dboard-jtag-1";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
&spi0 {
|
||||
status = "okay";
|
||||
|
||||
cs-gpios = <0>, <0>, <0>, <&gpio0 67 0>, <&gpio0 68 0>;
|
||||
|
||||
spidev0: spidev@0 {
|
||||
compatible = "rohm,dh2228fv";
|
||||
reg = <0>;
|
||||
status = "okay";
|
||||
spi-max-frequency = <1000000>;
|
||||
};
|
||||
|
||||
spidev1: spidev@1 {
|
||||
compatible = "rohm,dh2228fv";
|
||||
reg = <1>;
|
||||
status = "okay";
|
||||
spi-max-frequency = <1000000>;
|
||||
};
|
||||
|
||||
spidev2: spidev@2 {
|
||||
compatible = "rohm,dh2228fv";
|
||||
reg = <2>;
|
||||
status = "okay";
|
||||
spi-max-frequency = <1000000>;
|
||||
};
|
||||
|
||||
spidev3: spidev@3 {
|
||||
compatible = "rohm,dh2228fv";
|
||||
reg = <3>;
|
||||
status = "okay";
|
||||
spi-max-frequency = <1000000>;
|
||||
};
|
||||
|
||||
spidev4: spidev@4 {
|
||||
compatible = "rohm,dh2228fv";
|
||||
reg = <4>;
|
||||
status = "okay";
|
||||
spi-max-frequency = <1000000>;
|
||||
};
|
||||
};
|
||||
|
||||
&spi1 {
|
||||
status = "okay";
|
||||
|
||||
cs-gpios = <0>, <0>, <0>, <&gpio0 69 0>, <&gpio0 70 0>;
|
||||
|
||||
spidev5: spidev@0 {
|
||||
compatible = "rohm,dh2228fv";
|
||||
reg = <0>;
|
||||
status = "okay";
|
||||
spi-max-frequency = <1000000>;
|
||||
};
|
||||
|
||||
spidev6: spidev@1 {
|
||||
compatible = "rohm,dh2228fv";
|
||||
reg = <1>;
|
||||
status = "okay";
|
||||
spi-max-frequency = <1000000>;
|
||||
};
|
||||
|
||||
spidev7: spidev@2 {
|
||||
compatible = "rohm,dh2228fv";
|
||||
reg = <2>;
|
||||
status = "okay";
|
||||
spi-max-frequency = <1000000>;
|
||||
};
|
||||
|
||||
spidev8: spidev@3 {
|
||||
compatible = "rohm,dh2228fv";
|
||||
reg = <3>;
|
||||
status = "okay";
|
||||
spi-max-frequency = <1000000>;
|
||||
};
|
||||
|
||||
spidev9: spidev@4 {
|
||||
compatible = "rohm,dh2228fv";
|
||||
reg = <4>;
|
||||
status = "okay";
|
||||
spi-max-frequency = <1000000>;
|
||||
};
|
||||
};
|
||||
|
||||
&usrpio_i2c0 {
|
||||
rhodium_lodist_gpio: rhodium-lodist-gpio@22 {
|
||||
compatible = "nxp,tca6424";
|
||||
reg = <0x22>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR X11
|
||||
/*
|
||||
* Copyright (c) 2018 National Instruments Corp
|
||||
*/
|
||||
|
||||
&fpga_full {
|
||||
firmware-name = "n320.bin";
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR X11
|
||||
/*
|
||||
* Copyright (c) 2017 National Instruments Corp
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
#include "n300-fpga.dtsi"
|
||||
|
||||
&fpga_full {
|
||||
uio@40004000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x40004000 0x1000>;
|
||||
reg-names = "misc-auro-regs0";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
||||
uio@4000c000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x4000c000 0x1000>;
|
||||
reg-names = "misc-auro-regs1";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
#include "n300-common.dtsi"
|
||||
#include "dma-common.dtsi"
|
||||
@@ -0,0 +1,53 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR X11
|
||||
/*
|
||||
* Copyright (c) 2017 National Instruments Corp
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
#include "n300-fpga.dtsi"
|
||||
|
||||
&fpga_full {
|
||||
nixge0: ethernet@40000000 {
|
||||
compatible = "ni,xge-enet-2.00";
|
||||
reg = <0x40000000 0x6000>;
|
||||
|
||||
clocks = <&clkc 15>;
|
||||
clock-names = "bus_clk";
|
||||
|
||||
nvmem-cells = <ð1_addr>;
|
||||
nvmem-cell-names = "address";
|
||||
|
||||
interrupts = <0 29 4>, <0 30 4>;
|
||||
interrupt-names = "rx", "tx";
|
||||
interrupt-parent = <&intc>;
|
||||
status = "okay";
|
||||
|
||||
phy-mode = "xgmii";
|
||||
|
||||
fixed-link {
|
||||
speed = <1000>;
|
||||
full-duplex;
|
||||
/* 114 = 54 (MIOs) + 60 (EMIO 60) */
|
||||
link-gpios = <&gpio0 114 0>;
|
||||
};
|
||||
};
|
||||
|
||||
uio@40006000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x40006000 0x2000>;
|
||||
reg-names = "misc-enet-regs0";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
uio@4000c000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x4000c000 0x1000>;
|
||||
reg-names = "misc-auro-regs1";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
#include "n300-common.dtsi"
|
||||
#include "dma-common.dtsi"
|
||||
@@ -0,0 +1,80 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR X11
|
||||
/*
|
||||
* Copyright (c) 2017 National Instruments Corp
|
||||
*
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
#include "n300-fpga.dtsi"
|
||||
|
||||
&fpga_full {
|
||||
nixge0: ethernet@40000000 {
|
||||
compatible = "ni,xge-enet-2.00";
|
||||
reg = <0x40000000 0x6000>;
|
||||
|
||||
clocks = <&clkc 15>;
|
||||
clock-names = "bus_clk";
|
||||
|
||||
nvmem-cells = <ð1_addr>;
|
||||
nvmem-cell-names = "address";
|
||||
|
||||
interrupts = <0 29 4>, <0 30 4>;
|
||||
interrupt-names = "rx", "tx";
|
||||
interrupt-parent = <&intc>;
|
||||
status = "okay";
|
||||
|
||||
phy-mode = "xgmii";
|
||||
|
||||
fixed-link {
|
||||
speed = <1000>;
|
||||
full-duplex;
|
||||
/* 114 = 54 (MIOs) + 60 (EMIO 60) */
|
||||
link-gpios = <&gpio0 114 0>;
|
||||
};
|
||||
};
|
||||
|
||||
uio@40006000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x40006000 0x2000>;
|
||||
reg-names = "misc-enet-regs0";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
nixge1: ethernet@40008000 {
|
||||
compatible = "ni,xge-enet-2.00";
|
||||
reg = <0x40008000 0x6000>;
|
||||
|
||||
clocks = <&clkc 15>;
|
||||
clock-names = "bus_clk";
|
||||
|
||||
nvmem-cells = <ð2_addr>;
|
||||
nvmem-cell-names = "address";
|
||||
|
||||
interrupts = <0 31 4>, <0 32 4>;
|
||||
interrupt-names = "rx", "tx";
|
||||
interrupt-parent = <&intc>;
|
||||
status = "okay";
|
||||
|
||||
phy-mode = "xgmii";
|
||||
phy-handle = <ðernet_phy2>;
|
||||
|
||||
mdio {
|
||||
ethernet_phy2: ethernet-phy@4 {
|
||||
compatible = "ethernet-phy-ieee802.3-c45";
|
||||
reg = <4>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
uio@4000e000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x4000e000 0x2000>;
|
||||
reg-names = "misc-enet-regs1";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
#include "n300-common.dtsi"
|
||||
#include "dma-common.dtsi"
|
||||
@@ -0,0 +1,69 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR X11
|
||||
/*
|
||||
* Copyright (c) 2018 National Instruments Corp
|
||||
*
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
#include "n300-fpga.dtsi"
|
||||
|
||||
&fpga_full {
|
||||
uio@40006000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x40006000 0x2000>;
|
||||
reg-names = "misc-enet-regs0";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
nixge1: ethernet@40008000 {
|
||||
compatible = "ni,xge-enet-2.00";
|
||||
reg = <0x40008000 0x6000>;
|
||||
|
||||
clocks = <&clkc 15>;
|
||||
clock-names = "bus_clk";
|
||||
|
||||
nvmem-cells = <ð2_addr>;
|
||||
nvmem-cell-names = "address";
|
||||
|
||||
interrupts = <0 31 4>, <0 32 4>;
|
||||
interrupt-names = "rx", "tx";
|
||||
interrupt-parent = <&intc>;
|
||||
status = "okay";
|
||||
|
||||
phy-mode = "xgmii";
|
||||
phy-handle = <ðernet_phy2>;
|
||||
|
||||
mdio {
|
||||
ethernet_phy2: ethernet-phy@4 {
|
||||
compatible = "ethernet-phy-ieee802.3-c45";
|
||||
reg = <4>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
uio@4000e000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x4000e000 0x2000>;
|
||||
reg-names = "misc-enet-regs1";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
uio@43d40000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x43d40000 0x40000>;
|
||||
reg-names = "wr-regs";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
uart2@42c00000 {
|
||||
compatible = "xlnx,xps-uartlite-1.00.a";
|
||||
reg = <0x42c00000 0x1000>;
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <0 54 4>;
|
||||
};
|
||||
};
|
||||
|
||||
#include "n300-common.dtsi"
|
||||
#include "dma-common.dtsi"
|
||||
@@ -0,0 +1,54 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR X11
|
||||
/*
|
||||
* Copyright (c) 2017 National Instruments Corp
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
#include "n300-fpga.dtsi"
|
||||
|
||||
&fpga_full {
|
||||
nixge0: ethernet@40000000 {
|
||||
compatible = "ni,xge-enet-2.00";
|
||||
reg = <0x40000000 0x6000>;
|
||||
|
||||
clocks = <&clkc 15>;
|
||||
clock-names = "bus_clk";
|
||||
|
||||
nvmem-cells = <ð1_addr>;
|
||||
nvmem-cell-names = "address";
|
||||
|
||||
interrupts = <0 29 4>, <0 30 4>;
|
||||
interrupt-names = "rx", "tx";
|
||||
interrupt-parent = <&intc>;
|
||||
status = "okay";
|
||||
|
||||
phy-mode = "xgmii";
|
||||
phy-handle = <ðernet_phy1>;
|
||||
|
||||
mdio {
|
||||
ethernet_phy1: ethernet-phy@4 {
|
||||
compatible = "ethernet-phy-ieee802.3-c45";
|
||||
reg = <4>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
uio@40006000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x40006000 0x2000>;
|
||||
reg-names = "misc-enet-regs0";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
uio@4000c000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x4000c000 0x1000>;
|
||||
reg-names = "misc-auro-regs1";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
#include "n300-common.dtsi"
|
||||
#include "dma-common.dtsi"
|
||||
@@ -0,0 +1,80 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR X11
|
||||
/*
|
||||
* Copyright (c) 2017 National Instruments Corp
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
#include "n300-fpga.dtsi"
|
||||
|
||||
&fpga_full {
|
||||
nixge0: ethernet@40000000 {
|
||||
compatible = "ni,xge-enet-2.00";
|
||||
reg = <0x40000000 0x6000>;
|
||||
|
||||
clocks = <&clkc 15>;
|
||||
clock-names = "bus_clk";
|
||||
|
||||
nvmem-cells = <ð1_addr>;
|
||||
nvmem-cell-names = "address";
|
||||
|
||||
interrupts = <0 29 4>, <0 30 4>;
|
||||
interrupt-names = "rx", "tx";
|
||||
interrupt-parent = <&intc>;
|
||||
status = "okay";
|
||||
|
||||
phy-mode = "xgmii";
|
||||
phy-handle = <ðernet_phy1>;
|
||||
|
||||
mdio {
|
||||
ethernet_phy1: ethernet-phy@4 {
|
||||
compatible = "ethernet-phy-ieee802.3-c45";
|
||||
reg = <4>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
uio@40006000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x40006000 0x2000>;
|
||||
reg-names = "misc-enet-regs0";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
nixge1: ethernet@40008000 {
|
||||
compatible = "ni,xge-enet-2.00";
|
||||
reg = <0x40008000 0x6000>;
|
||||
|
||||
clocks = <&clkc 15>;
|
||||
clock-names = "bus_clk";
|
||||
|
||||
nvmem-cells = <ð2_addr>;
|
||||
nvmem-cell-names = "address";
|
||||
|
||||
interrupts = <0 31 4>, <0 32 4>;
|
||||
interrupt-names = "rx", "tx";
|
||||
interrupt-parent = <&intc>;
|
||||
status = "okay";
|
||||
|
||||
phy-mode = "xgmii";
|
||||
phy-handle = <ðernet_phy2>;
|
||||
|
||||
mdio {
|
||||
ethernet_phy2: ethernet-phy@4 {
|
||||
compatible = "ethernet-phy-ieee802.3-c45";
|
||||
reg = <4>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
uio@4000e000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x4000e000 0x2000>;
|
||||
reg-names = "misc-enet-regs1";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
#include "n300-common.dtsi"
|
||||
#include "dma-common.dtsi"
|
||||
@@ -0,0 +1,29 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR X11
|
||||
/*
|
||||
* Copyright (c) 2017 National Instruments Corp
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
#include "n310-fpga.dtsi"
|
||||
|
||||
&fpga_full {
|
||||
uio@40004000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x40004000 0x1000>;
|
||||
reg-names = "misc-auro-regs0";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
||||
uio@4000c000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x4000c000 0x1000>;
|
||||
reg-names = "misc-auro-regs1";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
#include "n310-common.dtsi"
|
||||
#include "dma-common.dtsi"
|
||||
@@ -0,0 +1,54 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR X11
|
||||
/*
|
||||
* Copyright (c) 2017 National Instruments Corp
|
||||
*
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
#include "n310-fpga.dtsi"
|
||||
|
||||
&fpga_full {
|
||||
nixge0: ethernet@40000000 {
|
||||
compatible = "ni,xge-enet-2.00";
|
||||
reg = <0x40000000 0x6000>;
|
||||
|
||||
clocks = <&clkc 15>;
|
||||
clock-names = "bus_clk";
|
||||
|
||||
nvmem-cells = <ð1_addr>;
|
||||
nvmem-cell-names = "address";
|
||||
|
||||
interrupts = <0 29 4>, <0 30 4>;
|
||||
interrupt-names = "rx", "tx";
|
||||
interrupt-parent = <&intc>;
|
||||
status = "okay";
|
||||
|
||||
phy-mode = "xgmii";
|
||||
|
||||
fixed-link {
|
||||
speed = <1000>;
|
||||
full-duplex;
|
||||
/* 114 = 54 (MIOs) + 60 (EMIO 60) */
|
||||
link-gpios = <&gpio0 114 0>;
|
||||
};
|
||||
};
|
||||
|
||||
uio@40006000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x40006000 0x2000>;
|
||||
reg-names = "misc-enet-regs0";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
uio@4000c000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x4000c000 0x1000>;
|
||||
reg-names = "misc-auro-regs1";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
#include "n310-common.dtsi"
|
||||
#include "dma-common.dtsi"
|
||||
@@ -0,0 +1,81 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR X11
|
||||
/*
|
||||
* Copyright (c) 2017 National Instruments Corp
|
||||
*
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
#include "n310-fpga.dtsi"
|
||||
|
||||
&fpga_full{
|
||||
nixge0: ethernet@40000000 {
|
||||
compatible = "ni,xge-enet-2.00";
|
||||
reg = <0x40000000 0x6000>;
|
||||
|
||||
clocks = <&clkc 15>;
|
||||
clock-names = "bus_clk";
|
||||
|
||||
nvmem-cells = <ð1_addr>;
|
||||
nvmem-cell-names = "address";
|
||||
|
||||
interrupts = <0 29 4>, <0 30 4>;
|
||||
interrupt-names = "rx", "tx";
|
||||
interrupt-parent = <&intc>;
|
||||
status = "okay";
|
||||
|
||||
phy-mode = "xgmii";
|
||||
|
||||
fixed-link {
|
||||
speed = <1000>;
|
||||
full-duplex;
|
||||
/* 114 = 54 (MIOs) + 60 (EMIO 60) */
|
||||
link-gpios = <&gpio0 114 0>;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
uio@40006000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x40006000 0x2000>;
|
||||
reg-names = "misc-enet-regs0";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
nixge1: ethernet@40008000 {
|
||||
compatible = "ni,xge-enet-2.00";
|
||||
reg = <0x40008000 0x6000>;
|
||||
|
||||
clocks = <&clkc 15>;
|
||||
clock-names = "bus_clk";
|
||||
|
||||
nvmem-cells = <ð2_addr>;
|
||||
nvmem-cell-names = "address";
|
||||
|
||||
interrupts = <0 31 4>, <0 32 4>;
|
||||
interrupt-names = "rx", "tx";
|
||||
interrupt-parent = <&intc>;
|
||||
status = "okay";
|
||||
|
||||
phy-mode = "xgmii";
|
||||
phy-handle = <ðernet_phy2>;
|
||||
|
||||
mdio {
|
||||
ethernet_phy2: ethernet-phy@4 {
|
||||
compatible = "ethernet-phy-ieee802.3-c45";
|
||||
reg = <4>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
uio@4000e000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x4000e000 0x2000>;
|
||||
reg-names = "misc-enet-regs1";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
#include "n310-common.dtsi"
|
||||
#include "dma-common.dtsi"
|
||||
@@ -0,0 +1,68 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR X11
|
||||
/*
|
||||
* Copyright (c) 2018 National Instruments Corp
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
#include "n310-fpga.dtsi"
|
||||
|
||||
&fpga_full {
|
||||
uio@40006000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x40006000 0x2000>;
|
||||
reg-names = "misc-enet-regs0";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
nixge1: ethernet@40008000 {
|
||||
compatible = "ni,xge-enet-2.00";
|
||||
reg = <0x40008000 0x6000>;
|
||||
|
||||
clocks = <&clkc 15>;
|
||||
clock-names = "bus_clk";
|
||||
|
||||
nvmem-cells = <ð2_addr>;
|
||||
nvmem-cell-names = "address";
|
||||
|
||||
interrupts = <0 31 4>, <0 32 4>;
|
||||
interrupt-names = "rx", "tx";
|
||||
interrupt-parent = <&intc>;
|
||||
status = "okay";
|
||||
|
||||
phy-mode = "xgmii";
|
||||
phy-handle = <ðernet_phy2>;
|
||||
|
||||
mdio {
|
||||
ethernet_phy2: ethernet-phy@4 {
|
||||
compatible = "ethernet-phy-ieee802.3-c45";
|
||||
reg = <4>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
uio@4000e000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x4000e000 0x2000>;
|
||||
reg-names = "misc-enet-regs1";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
uio@43d40000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x43d40000 0x40000>;
|
||||
reg-names = "wr-regs";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
uart2@42c00000 {
|
||||
compatible = "xlnx,xps-uartlite-1.00.a";
|
||||
reg = <0x42c00000 0x1000>;
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <0 54 4>;
|
||||
};
|
||||
};
|
||||
|
||||
#include "n310-common.dtsi"
|
||||
#include "dma-common.dtsi"
|
||||
@@ -0,0 +1,55 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR X11
|
||||
/*
|
||||
* Copyright (c) 2017 National Instruments Corp
|
||||
*
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
#include "n310-fpga.dtsi"
|
||||
|
||||
&fpga_full {
|
||||
nixge0: ethernet@40000000 {
|
||||
compatible = "ni,xge-enet-2.00";
|
||||
reg = <0x40000000 0x6000>;
|
||||
|
||||
clocks = <&clkc 15>;
|
||||
clock-names = "bus_clk";
|
||||
|
||||
nvmem-cells = <ð1_addr>;
|
||||
nvmem-cell-names = "address";
|
||||
|
||||
interrupts = <0 29 4>, <0 30 4>;
|
||||
interrupt-names = "rx", "tx";
|
||||
interrupt-parent = <&intc>;
|
||||
status = "okay";
|
||||
|
||||
phy-mode = "xgmii";
|
||||
phy-handle = <ðernet_phy1>;
|
||||
|
||||
mdio {
|
||||
ethernet_phy1: ethernet-phy@4 {
|
||||
compatible = "ethernet-phy-ieee802.3-c45";
|
||||
reg = <4>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
uio@40006000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x40006000 0x2000>;
|
||||
reg-names = "misc-enet-regs0";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
uio@4000c000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x4000c000 0x1000>;
|
||||
reg-names = "misc-auro-regs1";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
#include "n310-common.dtsi"
|
||||
#include "dma-common.dtsi"
|
||||
@@ -0,0 +1,81 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR X11
|
||||
/*
|
||||
* Copyright (c) 2017 National Instruments Corp
|
||||
*
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
#include "n310-fpga.dtsi"
|
||||
|
||||
&fpga_full {
|
||||
nixge0: ethernet@40000000 {
|
||||
compatible = "ni,xge-enet-2.00";
|
||||
reg = <0x40000000 0x6000>;
|
||||
|
||||
clocks = <&clkc 15>;
|
||||
clock-names = "bus_clk";
|
||||
|
||||
nvmem-cells = <ð1_addr>;
|
||||
nvmem-cell-names = "address";
|
||||
|
||||
interrupts = <0 29 4>, <0 30 4>;
|
||||
interrupt-names = "rx", "tx";
|
||||
interrupt-parent = <&intc>;
|
||||
status = "okay";
|
||||
|
||||
phy-mode = "xgmii";
|
||||
phy-handle = <ðernet_phy1>;
|
||||
|
||||
mdio {
|
||||
ethernet_phy1: ethernet-phy@4 {
|
||||
compatible = "ethernet-phy-ieee802.3-c45";
|
||||
reg = <4>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
uio@40006000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x40006000 0x2000>;
|
||||
reg-names = "misc-enet-regs0";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
nixge1: ethernet@40008000 {
|
||||
compatible = "ni,xge-enet-2.00";
|
||||
reg = <0x40008000 0x6000>;
|
||||
|
||||
clocks = <&clkc 15>;
|
||||
clock-names = "bus_clk";
|
||||
|
||||
nvmem-cells = <ð2_addr>;
|
||||
nvmem-cell-names = "address";
|
||||
|
||||
interrupts = <0 31 4>, <0 32 4>;
|
||||
interrupt-names = "rx", "tx";
|
||||
interrupt-parent = <&intc>;
|
||||
status = "okay";
|
||||
|
||||
phy-mode = "xgmii";
|
||||
phy-handle = <ðernet_phy2>;
|
||||
|
||||
mdio {
|
||||
ethernet_phy2: ethernet-phy@4 {
|
||||
compatible = "ethernet-phy-ieee802.3-c45";
|
||||
reg = <4>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
uio@4000e000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x4000e000 0x2000>;
|
||||
reg-names = "misc-enet-regs1";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
#include "n310-common.dtsi"
|
||||
#include "dma-common.dtsi"
|
||||
@@ -0,0 +1,117 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR X11
|
||||
/*
|
||||
* Copyright (c) 2018 National Instruments Corp
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
#include "n320-fpga.dtsi"
|
||||
|
||||
&fpga_full {
|
||||
nixge0: ethernet@40000000 {
|
||||
compatible = "ni,xge-enet-2.00";
|
||||
reg = <0x40000000 0x6000>;
|
||||
|
||||
clocks = <&clkc 15>;
|
||||
clock-names = "bus_clk";
|
||||
|
||||
nvmem-cells = <ð1_addr>;
|
||||
nvmem-cell-names = "address";
|
||||
|
||||
interrupts = <0 29 4>, <0 30 4>;
|
||||
interrupt-names = "rx", "tx";
|
||||
interrupt-parent = <&intc>;
|
||||
status = "okay";
|
||||
|
||||
phy-mode = "xgmii";
|
||||
phy-handle = <ðernet_phy1>;
|
||||
|
||||
mdio {
|
||||
ethernet_phy1: ethernet-phy@4 {
|
||||
compatible = "ethernet-phy-ieee802.3-c45";
|
||||
reg = <4>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
uio@40006000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x40006000 0x2000>;
|
||||
reg-names = "misc-enet-regs0";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
nixge1: ethernet@40008000 {
|
||||
compatible = "ni,xge-enet-2.00";
|
||||
reg = <0x40008000 0x6000>;
|
||||
|
||||
clocks = <&clkc 15>;
|
||||
clock-names = "bus_clk";
|
||||
|
||||
nvmem-cells = <ð2_addr>;
|
||||
nvmem-cell-names = "address";
|
||||
|
||||
interrupts = <0 31 4>, <0 32 4>;
|
||||
interrupt-names = "rx", "tx";
|
||||
interrupt-parent = <&intc>;
|
||||
status = "okay";
|
||||
|
||||
phy-mode = "xgmii";
|
||||
phy-handle = <ðernet_phy2>;
|
||||
|
||||
mdio {
|
||||
ethernet_phy2: ethernet-phy@4 {
|
||||
compatible = "ethernet-phy-ieee802.3-c45";
|
||||
reg = <4>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
uio@4000e000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x4000e000 0x2000>;
|
||||
reg-names = "misc-enet-regs1";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
uio@40020000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x40020000 0x1000>;
|
||||
reg-names = "misc-auro-regs0";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
uio@40024000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x40024000 0x1000>;
|
||||
reg-names = "misc-auro-regs1";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
uio@40028000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x40028000 0x1000>;
|
||||
reg-names = "misc-auro-regs2";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
||||
uio@4002c000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x4002c000 0x1000>;
|
||||
reg-names = "misc-auro-regs3";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
qsfp_i2c: qsfp-i2c@43D80000 {
|
||||
compatible = "xlnx,xps-iic-2.00.a";
|
||||
clocks = <&clkc 15>;
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <0 55 4>;
|
||||
reg = <0x43D80000 0x10000>;
|
||||
};
|
||||
};
|
||||
|
||||
#include "n320-common.dtsi"
|
||||
#include "dma-common.dtsi"
|
||||
@@ -0,0 +1,79 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR X11
|
||||
/*
|
||||
* Copyright (c) 2018 National Instruments Corp
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
#include "n320-fpga.dtsi"
|
||||
|
||||
&fpga_full {
|
||||
nixge0: ethernet@40000000 {
|
||||
compatible = "ni,xge-enet-2.00";
|
||||
reg = <0x40000000 0x6000>;
|
||||
|
||||
clocks = <&clkc 15>;
|
||||
clock-names = "bus_clk";
|
||||
|
||||
nvmem-cells = <ð1_addr>;
|
||||
nvmem-cell-names = "address";
|
||||
|
||||
interrupts = <0 29 4>, <0 30 4>;
|
||||
interrupt-names = "rx", "tx";
|
||||
interrupt-parent = <&intc>;
|
||||
status = "okay";
|
||||
|
||||
phy-mode = "xgmii";
|
||||
|
||||
fixed-link {
|
||||
speed = <1000>;
|
||||
full-duplex;
|
||||
/* 114 = 54 (MIOs) + 60 (EMIO 60) */
|
||||
link-gpios = <&gpio0 114 0>;
|
||||
};
|
||||
};
|
||||
|
||||
uio@40006000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x40006000 0x2000>;
|
||||
reg-names = "misc-enet-regs0";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
nixge1: ethernet@40008000 {
|
||||
compatible = "ni,xge-enet-2.00";
|
||||
reg = <0x40008000 0x6000>;
|
||||
|
||||
clocks = <&clkc 15>;
|
||||
clock-names = "bus_clk";
|
||||
|
||||
nvmem-cells = <ð2_addr>;
|
||||
nvmem-cell-names = "address";
|
||||
|
||||
interrupts = <0 31 4>, <0 32 4>;
|
||||
interrupt-names = "rx", "tx";
|
||||
interrupt-parent = <&intc>;
|
||||
status = "okay";
|
||||
|
||||
phy-mode = "xgmii";
|
||||
phy-handle = <ðernet_phy2>;
|
||||
|
||||
mdio {
|
||||
ethernet_phy2: ethernet-phy@4 {
|
||||
compatible = "ethernet-phy-ieee802.3-c45";
|
||||
reg = <4>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
uio@4000e000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x4000e000 0x2000>;
|
||||
reg-names = "misc-enet-regs1";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
#include "n320-common.dtsi"
|
||||
#include "dma-common.dtsi"
|
||||
@@ -0,0 +1,69 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR X11
|
||||
/*
|
||||
* Copyright (c) 2018 National Instruments Corp
|
||||
*
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
#include "n320-fpga.dtsi"
|
||||
|
||||
&fpga_full {
|
||||
uio@40006000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x40006000 0x2000>;
|
||||
reg-names = "misc-enet-regs0";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
nixge1: ethernet@40008000 {
|
||||
compatible = "ni,xge-enet-2.00";
|
||||
reg = <0x40008000 0x6000>;
|
||||
|
||||
clocks = <&clkc 15>;
|
||||
clock-names = "bus_clk";
|
||||
|
||||
nvmem-cells = <ð2_addr>;
|
||||
nvmem-cell-names = "address";
|
||||
|
||||
interrupts = <0 31 4>, <0 32 4>;
|
||||
interrupt-names = "rx", "tx";
|
||||
interrupt-parent = <&intc>;
|
||||
status = "okay";
|
||||
|
||||
phy-mode = "xgmii";
|
||||
phy-handle = <ðernet_phy2>;
|
||||
|
||||
mdio {
|
||||
ethernet_phy2: ethernet-phy@4 {
|
||||
compatible = "ethernet-phy-ieee802.3-c45";
|
||||
reg = <4>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
uio@4000e000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x4000e000 0x2000>;
|
||||
reg-names = "misc-enet-regs1";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
uio@43d40000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x43d40000 0x40000>;
|
||||
reg-names = "wr-regs";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
uart2@42c00000 {
|
||||
compatible = "xlnx,xps-uartlite-1.00.a";
|
||||
reg = <0x42c00000 0x1000>;
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <0 54 4>;
|
||||
};
|
||||
};
|
||||
|
||||
#include "n320-common.dtsi"
|
||||
#include "dma-common.dtsi"
|
||||
@@ -0,0 +1,80 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR X11
|
||||
/*
|
||||
* Copyright (c) 2018 National Instruments Corp
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
#include "n320-fpga.dtsi"
|
||||
|
||||
&fpga_full {
|
||||
nixge0: ethernet@40000000 {
|
||||
compatible = "ni,xge-enet-2.00";
|
||||
reg = <0x40000000 0x6000>;
|
||||
|
||||
clocks = <&clkc 15>;
|
||||
clock-names = "bus_clk";
|
||||
|
||||
nvmem-cells = <ð1_addr>;
|
||||
nvmem-cell-names = "address";
|
||||
|
||||
interrupts = <0 29 4>, <0 30 4>;
|
||||
interrupt-names = "rx", "tx";
|
||||
interrupt-parent = <&intc>;
|
||||
status = "okay";
|
||||
|
||||
phy-mode = "xgmii";
|
||||
phy-handle = <ðernet_phy1>;
|
||||
|
||||
mdio {
|
||||
ethernet_phy1: ethernet-phy@4 {
|
||||
compatible = "ethernet-phy-ieee802.3-c45";
|
||||
reg = <4>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
uio@40006000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x40006000 0x2000>;
|
||||
reg-names = "misc-enet-regs0";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
nixge1: ethernet@40008000 {
|
||||
compatible = "ni,xge-enet-2.00";
|
||||
reg = <0x40008000 0x6000>;
|
||||
|
||||
clocks = <&clkc 15>;
|
||||
clock-names = "bus_clk";
|
||||
|
||||
nvmem-cells = <ð2_addr>;
|
||||
nvmem-cell-names = "address";
|
||||
|
||||
interrupts = <0 31 4>, <0 32 4>;
|
||||
interrupt-names = "rx", "tx";
|
||||
interrupt-parent = <&intc>;
|
||||
status = "okay";
|
||||
|
||||
phy-mode = "xgmii";
|
||||
phy-handle = <ðernet_phy2>;
|
||||
|
||||
mdio {
|
||||
ethernet_phy2: ethernet-phy@4 {
|
||||
compatible = "ethernet-phy-ieee802.3-c45";
|
||||
reg = <4>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
uio@4000e000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x4000e000 0x2000>;
|
||||
reg-names = "misc-enet-regs1";
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
#include "n320-common.dtsi"
|
||||
#include "dma-common.dtsi"
|
||||
@@ -0,0 +1,117 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR X11
|
||||
/*
|
||||
* Copyright (c) 2018 National Instruments Corp
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
/plugin/;
|
||||
|
||||
#include "n320-fpga.dtsi"
|
||||
|
||||
&fpga_full {
|
||||
nixge0: ethernet@40000000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "ni,xge-enet-3.00";
|
||||
reg = <0x40000000 0x4000
|
||||
0x40020000 0x2000>;
|
||||
reg-names = "dma", "ctrl";
|
||||
|
||||
clocks = <&clkc 15>;
|
||||
clock-names = "bus_clk";
|
||||
|
||||
nvmem-cells = <ð1_addr>;
|
||||
nvmem-cell-names = "address";
|
||||
|
||||
interrupts = <0 29 4>, <0 30 4>;
|
||||
interrupt-names = "rx", "tx";
|
||||
interrupt-parent = <&intc>;
|
||||
status = "okay";
|
||||
|
||||
phy-mode = "xgmii";
|
||||
phy-handle = <ðernet_phy1>;
|
||||
|
||||
mdio {
|
||||
ethernet_phy1: ethernet-phy@4 {
|
||||
compatible = "ethernet-phy-ieee802.3-c45";
|
||||
reg = <4>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
uio@40022000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x40022000 0x2000>;
|
||||
reg-names = "misc-enet-regs0";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
nixge1: ethernet@40008000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "ni,xge-enet-3.00";
|
||||
reg = <0x40008000 0x4000
|
||||
0x40024000 0x2000>;
|
||||
reg-names = "dma", "ctrl";
|
||||
|
||||
clocks = <&clkc 15>;
|
||||
clock-names = "bus_clk";
|
||||
|
||||
nvmem-cells = <ð2_addr>;
|
||||
nvmem-cell-names = "address";
|
||||
|
||||
interrupts = <0 31 4>, <0 32 4>;
|
||||
interrupt-names = "rx", "tx";
|
||||
interrupt-parent = <&intc>;
|
||||
status = "okay";
|
||||
|
||||
phy-mode = "xgmii";
|
||||
phy-handle = <ðernet_phy2>;
|
||||
|
||||
mdio {
|
||||
ethernet_phy2: ethernet-phy@4 {
|
||||
compatible = "ethernet-phy-ieee802.3-c45";
|
||||
reg = <4>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
uio@40026000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x40026000 0x2000>;
|
||||
reg-names = "misc-enet-regs1";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
uio@40006000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x40006000 0x2000>;
|
||||
reg-names = "misc-enet-regs2";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
uio@43d40000 {
|
||||
compatible = "usrp-uio";
|
||||
reg = <0x43d40000 0x40000>;
|
||||
reg-names = "wr-regs";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
uart2@42c00000 {
|
||||
compatible = "xlnx,xps-uartlite-1.00.a";
|
||||
reg = <0x42c00000 0x1000>;
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <0 54 4>;
|
||||
};
|
||||
|
||||
qsfp_i2c: qsfp-i2c@43D80000 {
|
||||
compatible = "xlnx,xps-iic-2.00.a";
|
||||
clocks = <&clkc 15>;
|
||||
interrupt-parent = <&intc>;
|
||||
interrupts = <0 55 4>;
|
||||
reg = <0x43D80000 0x10000>;
|
||||
};
|
||||
};
|
||||
|
||||
#include "n320-common.dtsi"
|
||||
#include "dma-common.dtsi"
|
||||
@@ -0,0 +1,90 @@
|
||||
#
|
||||
# Copyright 2017-2018 Ettus Research, a National Instruments Company
|
||||
#
|
||||
|
||||
#include $(IP_DIR)/axi4_dualport_sram/Makefile.inc
|
||||
include $(IP_DIR)/hb47_1to2/Makefile.inc
|
||||
include $(IP_DIR)/hb47_2to1/Makefile.inc
|
||||
include $(IP_DIR)/axi64_4k_2clk_fifo/Makefile.inc
|
||||
include $(IP_DIR)/axi64_8k_2clk_fifo/Makefile.inc
|
||||
include $(IP_DIR)/axi_intercon_2x64_256_bd/Makefile.inc
|
||||
include $(IP_DIR)/axi_intercon_4x64_256_bd/Makefile.inc
|
||||
include $(IP_DIR)/ddr3_32bit/Makefile.inc
|
||||
include $(IP_DIR)/fifo_4k_2clk/Makefile.inc
|
||||
include $(IP_DIR)/fifo_short_2clk/Makefile.inc
|
||||
#include $(IP_DIR)/input_sample_fifo/Makefile.inc
|
||||
include $(IP_DIR)/one_gig_eth_pcs_pma/Makefile.inc
|
||||
include $(IP_DIR)/misc_clock_gen/Makefile.inc
|
||||
include $(IP_DIR)/ten_gig_eth_pcs_pma/Makefile.inc
|
||||
include $(IP_DIR)/aurora_64b66b_pcs_pma/Makefile.inc
|
||||
include $(IP_DIR)/axi3_to_axi4lite_protocol_converter/Makefile.inc
|
||||
include $(IP_DIR)/axis_fifo_to_axi4lite/Makefile.inc
|
||||
include $(IP_DIR)/axi_eth_dma/Makefile.inc
|
||||
include $(IP_DIR)/axi4_to_axi3_protocol_converter_32/Makefile.inc
|
||||
include $(IP_DIR)/axi4_to_axi3_protocol_converter_64/Makefile.inc
|
||||
include $(IP_DIR)/n310_ps_bd/Makefile.inc
|
||||
|
||||
BD_SRCS = \
|
||||
$(IP_AXI_INTERCON_2X64_256_BD_SRCS) \
|
||||
$(IP_AXI_INTERCON_4X64_256_BD_SRCS) \
|
||||
$(IP_N310_PS_BD_SRCS)
|
||||
|
||||
IP_XCI_SRCS = \
|
||||
$(IP_HB47_1TO2_SRCS) \
|
||||
$(IP_HB47_2TO1_SRCS) \
|
||||
$(IP_AXI4_BRAM_SRCS) \
|
||||
$(IP_AXI64_4K_2CLK_FIFO_SRCS) \
|
||||
$(IP_AXI64_8K_2CLK_FIFO_SRCS) \
|
||||
$(IP_AXI3_TO_AXI4LITE_PROTOCOL_CONVERTER_SRCS) \
|
||||
$(IP_AXI4_TO_AXI3_PROTOCOL_CONVERTER_32_SRCS) \
|
||||
$(IP_AXI4_TO_AXI3_PROTOCOL_CONVERTER_64_SRCS) \
|
||||
$(IP_AXIS_FIFO_TO_AXI4LITE_SRCS) \
|
||||
$(IP_MISC_CLOCK_GEN_SRCS) \
|
||||
$(IP_FIFO_4K_2CLK_SRCS) \
|
||||
$(IP_FIFO_SHORT_2CLK_SRCS) \
|
||||
$(IP_AXI_ETH_DMA_SRCS) \
|
||||
$(IP_ONE_GIG_ETH_PCS_PMA_SRCS) \
|
||||
$(IP_TEN_GIG_ETH_PCS_PMA_SRCS) \
|
||||
$(IP_AURORA_64B66B_PCS_PMA_SRCS)
|
||||
|
||||
IP_DRAM_XCI_SRCS = \
|
||||
$(IP_DDR3_32BIT_SRCS)
|
||||
|
||||
# Currently unused
|
||||
# $(IP_INPUT_SAMPLE_FIFO_SRCS) \
|
||||
|
||||
IP_CODEGEN_SRCS = \
|
||||
$(ONE_GIGE_PHY_SRCS) \
|
||||
$(TEN_GIGE_PHY_SRCS)
|
||||
|
||||
IP_SYNTH_OUTPUTS = \
|
||||
$(IP_HB47_1TO2_OUTS) \
|
||||
$(IP_HB47_2TO1_OUTS) \
|
||||
$(IP_AXI4_BRAM_OUTS) \
|
||||
$(IP_AXI64_4K_2CLK_FIFO_OUTS) \
|
||||
$(IP_AXI64_8K_2CLK_FIFO_OUTS) \
|
||||
$(IP_AXI3_TO_AXI4LITE_PROTOCOL_CONVERTER_OUTS) \
|
||||
$(IP_AXI_INTERCONNECT_OUTS) \
|
||||
$(IP_AXI4_TO_AXI3_PROTOCOL_CONVERTER_32_OUTS) \
|
||||
$(IP_AXI4_TO_AXI3_PROTOCOL_CONVERTER_64_OUTS) \
|
||||
$(IP_AXIS_FIFO_TO_AXI4LITE_OUTS) \
|
||||
$(IP_FIFO_4K_2CLK_OUTS) \
|
||||
$(IP_FIFO_SHORT_2CLK_OUTS) \
|
||||
$(IP_ONE_GIG_ETH_PCS_PMA_OUTS) \
|
||||
$(IP_AXI_ETH_DMA_OUTS) \
|
||||
$(IP_TEN_GIG_ETH_PCS_PMA_OUTS) \
|
||||
$(IP_AURORA_64B66B_PCS_PMA_OUTS)
|
||||
|
||||
BD_OUTPUTS = \
|
||||
$(IP_AXI_INTERCON_2X64_256_BD_OUTS) \
|
||||
$(IP_AXI_INTERCON_4X64_256_BD_OUTS) \
|
||||
$(IP_N310_PS_BD_OUTS)
|
||||
|
||||
# Currently unused
|
||||
# $(IP_INPUT_SAMPLE_FIFO_OUTS) \
|
||||
# $(IP_AXI_INTERCON_4X64_128_OUTS) \
|
||||
|
||||
ip: $(IP_SYNTH_OUTPUTS) $(IP_CODEGEN_SRCS) $(BD_OUTPUTS)
|
||||
|
||||
.PHONY: ip
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
#
|
||||
# Copyright 2016 Ettus Research
|
||||
#
|
||||
|
||||
include $(TOOLS_DIR)/make/viv_ip_builder.mak
|
||||
|
||||
AURORA_PHY_SRCS = \
|
||||
$(IP_DIR)/aurora_64b66b_pcs_pma/aurora_phy_x1.v \
|
||||
$(IP_DIR)/aurora_64b66b_pcs_pma/aurora_phy_mmcm.v \
|
||||
$(IP_DIR)/aurora_64b66b_pcs_pma/aurora_phy_clk_gen.v \
|
||||
$(IP_DIR)/aurora_64b66b_pcs_pma/aurora_axis_mac.v \
|
||||
$(IP_AURORA_64B66B_PCS_PMA_EXAMPLE_SRCS)
|
||||
|
||||
IP_AURORA_64B66B_PCS_PMA_EXAMPLE_SRCS = $(addprefix $(IP_BUILD_DIR)/aurora_64b66b_pcs_pma_ex/, \
|
||||
aurora_64b66b_pcs_pma_ex.srcs/shared_logic/aurora_64b66b_pcs_pma_clock_module.v \
|
||||
aurora_64b66b_pcs_pma_ex.srcs/shared_logic/aurora_64b66b_pcs_pma_gt_common_wrapper.v \
|
||||
aurora_64b66b_pcs_pma_ex.srcs/shared_logic/aurora_64b66b_pcs_pma_support_reset_logic.v \
|
||||
aurora_64b66b_pcs_pma_ex.srcs/shared_logic/aurora_64b66b_pcs_pma_support.v \
|
||||
imports/aurora_64b66b_pcs_pma_cdc_sync_exdes.v \
|
||||
imports/aurora_64b66b_pcs_pma_example_axi_to_ll.v \
|
||||
imports/aurora_64b66b_pcs_pma_example_ll_to_axi.v \
|
||||
)
|
||||
|
||||
IP_AURORA_64B66B_PCS_PMA_SRCS = $(IP_BUILD_DIR)/aurora_64b66b_pcs_pma/aurora_64b66b_pcs_pma.xci
|
||||
|
||||
IP_AURORA_64B66B_PCS_PMA_OUTS = $(addprefix $(IP_BUILD_DIR)/aurora_64b66b_pcs_pma/, \
|
||||
aurora_64b66b_pcs_pma.xci.out \
|
||||
)
|
||||
|
||||
$(IP_AURORA_64B66B_PCS_PMA_SRCS) $(IP_AURORA_64B66B_PCS_PMA_OUTS) $(IP_AURORA_64B66B_PCS_PMA_EXAMPLE_SRCS): $(IP_DIR)/aurora_64b66b_pcs_pma/aurora_64b66b_pcs_pma.xci
|
||||
$(call BUILD_VIVADO_IP,aurora_64b66b_pcs_pma,$(ARCH),$(PART_ID),$(IP_DIR),$(IP_BUILD_DIR),1)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user