Author SHA1 Message Date
Ayzen 62c0266a6b per-point switching: hardware bring-up, profiles, protocol doc
Verified on the bench that the modified master bitstream excites in every stage
and the RF switch routes: 16 traces per sweep, 62 dB between the two switch
positions of one master port, 9.9k measurements/s. Adds the built master image,
two run profiles, a verification script and librevna_protocol.md, and drops the
stale prototype driver copy that the firmware tree still carried.
2026-09-15 14:41:54 +03:00
Ayzen 3f6cfc9108 switch controller: separate pin per switch, gap histogram
PB2 now drives the switch on master port 1 and PB6 the one on port 2, both
updated in a single BSRR write so they move in the same cycle. The CDC report
gained a gap histogram, which showed the point boundary sits at 70-79 us against
62 us between stages, so the resync threshold only fires on the longer
inter-sweep pauses; the misleading "stages per point" counter is renamed to
match what it actually counts.
2026-09-15 14:41:21 +03:00
AyzenandClaude Opus 5 caac6561c2 fpga: pin placer cost table 2, add the built master bitstream
Ограничение MCU_MOSI OFFSET hold маргинально уже в стоке: запас +0.458 нс.
Поэтому любое изменение нетлиста переставляет размещение и может его опрокинуть.
A/B в ISE: сток - Timing Score 0, версия на маске при cost table 1 - 5480.

Cost table 2 даёт Timing Score 0, причём запас по hold на MCU_MOSI больше
стокового: +0.642 против +0.458 нс. Значение зафиксировано в VNA.xise одной
строкой, иначе следующая сборка снова словит нарушение.

Ресурсы финальной сборки: 2302 LUT против 2189 у стока (40% против 38% ёмкости
xc6slx9). Промежуточные 2182, которые я приводил раньше, были из сборки с
cost table 1 - её перебор потом переделал, и упаковка map изменилась.

Битстрим положен как top_master_per_point_switching.bin, а не поверх
top_master.bin: последний - одна из двух копий невосстановимого битстрима, из
которого собран текущий combined.vnafw.

Документ приведён в согласованное состояние: таблица контракта и описание
Sweep.vhd отставали от версии на маске.

Собрано и проверено на машине сборки: ISE 14.7 в виртуалке, xtclsh в батч-режиме.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 14:18:20 +03:00
AyzenandClaude Opus 5 59c9d4f255 fpga: replace variable shift with a compare mask in port gating
Контрольная сборка стока в ISE показала, что первая версия правки внесла
нарушение тайминга: сток даёт Timing Score 0, а она — 1880 (hold на входе
MCU_MOSI). Причина — shift_right с переменным сдвигом синтезируется в barrel
shifter, а вызывался он четырежды: +142 LUT при +3 регистрах, из-за чего
поехало размещение и пострадала SPI-шина, по которой MCU пишет регистры FPGA.
Сбой там означал бы неверную конфигурацию развёртки.

Теперь младшие биты счётчика стадий просто маскируются, а маска декодируется
из SUBSTAGE_BITS тремя вентилями. Итог: 2182 LUT против 2189 у стока, то есть
логика стала дешевле стоковой. При SUBSTAGE_BITS=0 маска все единицы и
выражение вырождается в стоковое stage_cnt = port_stage буквально.

Заодно контракт стал однозначнее: хост присылает ПЕРВУЮ стадию блока порта, а
не индекс порта. Без под-стадий это то же число, поэтому стоковая совместимость
сохраняется, а зарезервированное "7 = порт выключен" больше не может совпасть с
настоящей стадией (при четырёх под-стадиях маскированная семёрка совпадала с
блоком второго порта).

Из VHDL убраны не-ASCII символы: GHDL отвергает их даже в комментариях.

Проверено: тестбенч проходит все четыре сценария и падает под мутацией
(8 сработавших проверок), 305 python-тестов зелёные, ISE собирает битстрим.
Остаточное нарушение hold на MCU_MOSI ловится подбором cost table размещателя —
ограничение маргинально уже в стоке (запас +0.458 нс).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 14:02:30 +03:00
AyzenandClaude Opus 5 dfb285ab93 add windows install/build scripts for per-point switching
Скрипты, которыми правки ставятся в дерево LibreVNA на сборочной машине и
собирается прошивка MCU мастера её штатным тулчейном (STM32CubeIDE 1.17.0,
gcc 12.3.1). Оригиналы шести изменённых файлов сохраняются в backup_original,
так что откат — обратный xcopy.

Проверено на месте: все 7 файлов легли побайтово (сверил sha256 каждого),
прошивка мастера собралась, эталон предыдущей прошивки остался цел в
extracted/master_stm32.bin.

Битстрим FPGA этими скриптами не собирается — нужна ISE 14.7 в виртуалке,
процедура описана в README.txt и per_point_switching.md.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 12:48:52 +03:00
AyzenandClaude Opus 5 2412aedc58 switch controller: shorten the gap-minimum window to adapt to dwell changes
Окно минимума было 4096 отсчётов, и это давало опасную асимметрию: при
УМЕНЬШЕНИИ межстадийной паузы минимум падает мгновенно, а при УВЕЛИЧЕНИИ
(подняли dwell_us или задержку PLL прибора) устаревшее маленькое значение живёт
тысячи стадий. Порог оказывался ниже реальной межстадийной паузы, детектор
границы срабатывал на каждой стадии и залипал ключ в положении A на пару
развёрток.

Окно сокращено до 16 отсчётов. Длинное окно не давало точности: пауза задаётся
счётчиком в FPGA и детерминирована, а межстадийная — самая частая (три из
четырёх при четырёх стадиях), так что минимум по десятку отсчётов уже равен ей.
Зато теперь смена настроек подхватывается за считанные точки, и случайная
короткая пауза от помехи вымывается так же быстро.

IFBW на порог не влияет и влиять не может: он меняет длительность оцифровки
(фронт-спад), а меряется пауза (спад-фронт). Плюс ключ переключается по спаду,
когда оцифровка закончена, а детектор границы во время оцифровки неактивен —
boundaryPending_ сбрасывается на фронте. Разобрано в README.

Прошито и проверено: после сброса ядро в loop, Verified OK.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 12:37:31 +03:00
AyzenandClaude Opus 5 c1f8654677 review fixes: shared mock capture window, 2-position controller caveat
Мок-бэкенд ставил каждому трейсу свой capture_end_ns, потому что метка бралась
в момент создания трейса. На реальном железе все комбинации коллекции выходят из
одного синхронизированного цикла и делят одно окно — мок теперь ведёт себя так
же, иначе он вводит в заблуждение при чтении записанных меток.

В README контроллера добавлена оговорка: прошивка рассчитана ровно на два
положения ключа. Хост допускает и 4, но тогда положение перестаёт быть
чередованием одного бита и нужен контроллер на две управляющие линии.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-09 22:15:50 +03:00
AyzenandClaude Opus 5 7d1879ad79 per-point switching: FPGA and LibreVNA MCU changes
FPGA мастера: порт излучает не в одной стадии, а в блоке подряд идущих —
младшие SUBSTAGE_BITS бит счётчика стадий стали положением выходного ключа,
старшие выбирают порт. Вынесено в функцию port_excites в Sweep.vhd, новое поле
приезжает из свободных битов 8:6 регистра SweepSetup через SPIConfig и top.vhd.

Совместимость со стоком строгая: при SUBSTAGE_BITS=0 сдвиг нулевой, а
добавленная проверка "порт-стадия выше последней" ничего не меняет, потому что
счётчик стадий и так пробегает только 0..STAGES. Ручной режим и анализатор
спектра, где STAGES=0, ведут себя ровно как раньше.

MCU: у SetupSweep добавлен параметр substage_bits со значением по умолчанию 0,
поэтому вызовы из Manual.cpp и SpectrumAnalyzer.cpp не тронуты. VNA.cpp берёт
ширину под-стадии из port3Stage — порта 3 у этого железа нет, поле свободно, и
формат пакета не меняется.

Проверено: GHDL анализирует все три VHDL-файла чисто; новый самопроверяющийся
Test_Sweep.vhd прогоняет четыре сценария (сток, два положения, приёмник без
излучения, четыре положения) и проверен мутацией — с возвращённым стоковым
сравнением сценарии с под-стадиями падают. Обе сборки MCU собираются без ошибок.
Битовые позиции сверены сквозь всю цепочку: хост шлёт port3Stage=1 в слове
0x243, MCU пишет регистр 0x7041, FPGA читает SUBSTAGE_BITS=1.

Слейвы перепрошивать не нужно: им шлётся порт-стадия 7, которая со счётчиком
0..3 не совпадает и в стоковом сравнении.

Исходники теперь опережают лежащие рядом бинарники — предупреждение добавлено в
начало reproduce/README.md, хеш README в SHA256SUMS обновлён. Порядок ввода в
строй расписан в per_point_switching.md.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-09 22:06:23 +03:00
AyzenandClaude Opus 5 0db3dbe295 switch controller firmware + per-point switching spec
Прошивка STM32 (WeAct G431CB, тот же тулчейн, что у пульта тележки), которая
стоит в разрыве триггерной петли между мастером и первым слейвом и переключает
выходной ключ внутри частотной точки.

Положение ключа — младший бит номера стадии, а период 2 нацело делит 4 стадии,
поэтому чередование не рвётся на границе точки и контроллеру достаточно
инвертировать ногу на каждый цикл триггера. Переключение по СПАДУ: спад означает
«оцифровка закончилась», дальше идёт окно успокоения следующей стадии (~62 мкс
при dwell_us=2), которого ключу хватает с запасом, и кольцо удерживать не надо.

Один потерянный фронт инвертировал бы чётность навсегда и молча поменял антенны
местами, поэтому контроллер распознаёт границу точки по длине паузы (между
точками к успокоению добавляется перезагрузка регистров PLL) и принудительно
ставит положение A — чётность чинится на каждой точке, а не раз на развёртку.
Порог берётся как минимум паузы по скользящему окну с запасом, то есть
подстраивается сам; отдельный провод-маркер начала развёртки не нужен.

Задержку зеркалирования проверил по Sweep.vhd: мастер стартует оцифровку по
своему TRIGGER_IN с конца кольца, то есть тоже после контроллера. Задержка
общая для всех приборов и сокращается в отношении «приёмник/опорник» — фазовой
ошибки не вносит, только чуть удлиняет развёртку.

Собирается: RAM 13.9%, Flash 20.0%.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-09 21:45:50 +03:00
AyzenandClaude Opus 5 6693ece0aa per-point stimulus switching: host side
Матрица 4x4 за одну развёртку: каждый порт мастера измеряется на каждой частоте
дважды, с двумя положениями выходного ключа. Ключ дёргает контроллер в
триггерной петле, поэтому расбери переключателями больше не управляет —
SwitchedMatrixRadarService уходит из тракта, все 16 комбинаций снимаются в
пределах одной точки вместо разброса между тремя развёртками.

Выходы нумеруются позиция-мажорно, стадии порт-мажорно (старшие биты счётчика
стадий выбирают порт, младший — положение ключа). Из этого следует, что
положение ключа = младший бит номера стадии, а период 2 нацело делит 4 стадии —
поэтому контроллеру достаточно инвертировать ногу на каждый цикл триггера, без
абсолютного счётчика. Выходы 0 и 1 при этом сохраняют прежний смысл.

Приёмники слейвов пронумерованы от числа выходов + 1, а не от фиксированного 3:
иначе при 4 выходах прямой член «приёмник 3 <- выход 3» назывался бы так же, как
отражение выхода 3. При двух выходах даёт прежние порты 3..6.

Слейвам порт-стадии выставляются в 7: стоковый приём «одна за последней стадией»
перестаёт работать, когда порт выбирается старшими битами.

Всё за флагом multi_device.stimulus_switch_positions (1 = прежнее поведение,
байт в байт). Спецификация правок FPGA/STM в device_firmware/per_point_switching.md.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-09 21:26:56 +03:00
AyzenandClaude Opus 5 d2338ff10c added librevna firmware reproduce kit
Полное дерево LibreVNA v1.6.5 с доработками master/slave, эталонные битстримы
и прошивки STM32, упаковщик .vnafw. Проверено: build.sh пересобирает обе
прошивки побайтово идентично лежащим рядом .vnafw.

Мастер-битстрим (top_master.bin / extracted/master_fpga.bin) больше нигде не
существует — place&route в ISE недетерминирован, из исходников он не
восстанавливается.

Положено в multi_libreVNA_firmware/reproduce, а не в device_firmware/reproduce
как сказано в README комплекта: SHA256SUMS и build.sh ссылаются на
../combined.vnafw, а .vnafw лежат здесь.

Корневые правила .gitignore build*/build/ выбрасывали 482 файла, включая сам
build.sh и эталонные прошивки STM32 из SHA256SUMS — дописано разыгноривание.
Оставшиеся 7 файлов перебивал вложенный апстримный .gitignore (более глубокий
имеет приоритет), они добавлены force-add'ом. Промежуточные .o/.d/.su из
build-каталогов убраны, .bin/.elf/.hex/.map оставлены.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-09 21:08:02 +03:00
Ayzen 7997abe2d9 added capture time for every sweep 2026-09-03 17:30:19 +03:00
Guriy 8a52431bd3 cart_firmware_settings_changed 2026-08-27 13:53:33 +03:00
Ayzen cc6d189d52 cart_firmware_added 2026-08-26 15:40:10 +03:00
Ayzen 6ada811c2f some fixes 2026-08-26 15:02:21 +03:00
BogatskiyG 74723bb635 Merge branch 'laser-temp-monitoring' into feature/switched-matrix-radar 2026-08-04 14:57:03 +03:00
BogatskiyG 7c0ae1ecf8 removed the b-scan collection_id floor 2026-08-03 18:59:34 +03:00
BogatskiyG b183401e6f added bscan reprocessing 2026-07-31 18:14:54 +03:00
aweandClaude Opus 4.8 e219f6ec02 Add laser temperature monitoring for current-variation runs
Independent monitor + checker for CHANGE_CURRENT_LD1 variation, where the
board sweeps LD1 current autonomously while both laser temperatures must stay
on their static setpoints. Nothing previously verified that the setpoints were
actually reached, so a stale temperature silently corrupted measurements.

New package python_app/hardware_full/laser_control/monitoring/:
- session.py: LaserVariationSession snapshot (targets + tolerance frozen at start)
- readings_channel.py: JSONL append/tail channel for per-sweep readings
- monitor.py: LaserTemperatureMonitor polls the board once per sweep, publishes
- checker.py: LaserTemperatureChecker validates temp1/temp2 vs targets (0.03 C),
  warns to console per laser with anti-spam state

CLI entry points scripts/laser_temp_monitor.py and scripts/laser_temp_checker.py
run as independent processes communicating via IPC files.

Also: add temp_tolerance_c to LaserVariationModeModel (schema + codec round-trip)
and write the session snapshot from apply_kamil_adc_laser_control's variation path
so the checker works with pipeline-started runs too.

Tests in tests/test_laser_temp_monitoring.py (17 cases); existing laser-control
protocol and config-codec suites remain green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-27 21:41:14 +03:00
awe 52c1218bf7 Independent monitor + checker for CHANGE_CURRENT_LD1 variation 2026-07-27 16:24:58 +03:00
Ayzen 3efe968dd1 some kamil_adc fixes 2026-07-02 17:44:24 +03:00
Ayzen 42532c9868 added new filtration and fixed processing parameters 2026-06-23 21:55:40 +03:00
Ayzen 4ca4b27246 new libreVNA config 2026-06-23 19:11:59 +03:00
1338 changed files with 651062 additions and 697 deletions
+48 -3
View File
@@ -8,6 +8,7 @@ build*
# C extensions
python_app/data*
*.so
*.ipynb
*.npy
snapshots/
test_results*
@@ -20,8 +21,8 @@ dist/
downloads/
eggs/
.eggs/
lib/
lib64/
/lib/
/lib64/
parts/
sdist/
var/
@@ -165,6 +166,25 @@ ENV/
env.bak/
venv.bak/
# Локальные инструменты, распакованные не из пакетного менеджера (GHDL для
# анализа и симуляции VHDL, clangd). Ставятся скриптом, в репозиторий не идут.
.tools/
# База компиляции для clangd: абсолютные пути этой машины.
# Генерируется .claude/tools/gen_compile_commands.sh из Makefile.
compile_commands.json
# Граф знаний graphify: 22 МБ, пересобирается из кода за минуту.
# Список исключений для него — в .graphifyignore, он тоже не версионируется
# (см. ниже, вместе с остальной обвязкой Claude Code).
graphify-out/
# Payload комплекта установки на Windows: копия файлов из дерева LibreVNA.
# Генерируется install_windows/make_files.sh; в git не идёт, чтобы не разойтись
# с деревом (уже расходился).
device_firmware/multi_libreVNA_firmware/reproduce/install_windows/files/
device_firmware/multi_libreVNA_firmware/reproduce/install_windows/backup_original/
# Spyder project settings
.spyderproject
.spyproject
@@ -225,6 +245,31 @@ __marimo__/
python_app/runtime
SHARE_INTERNET_TO_PI.md
# Локальная обвязка Claude Code: инструкции, хуки, скилы, конфиги инструментов.
# В репозиторий не идёт.
CLAUDE.md
docs/
.claude/
.graphifyignore
pyrightconfig.json
/docs/
test_end_2/
# --- device_firmware: PlatformIO / STM32G431 cart remote ---
# build output (regenerated by `pio run`)
device_firmware/cart_firmware/.pio/
device_firmware/switch_controller/.pio/
# scope captures: raw .bin + .npz + preview .png, local-only
device_firmware/cart_firmware/captures/
# machine-specific, regenerated by the PlatformIO extension
device_firmware/cart_firmware/.vscode/c_cpp_properties.json
device_firmware/cart_firmware/.vscode/launch.json
device_firmware/cart_firmware/.vscode/ipch/
device_firmware/cart_firmware/.vscode/.browse.c_cpp.db*
# --- device_firmware: комплект воспроизведения прошивок LibreVNA ---
# Корневые `build*` / `build/` иначе молча выбрасывают сам build.sh и эталонные
# прошивки STM32, на которые ссылается reproduce/SHA256SUMS. Каталог сборки
# приходится разыгнорить целиком: git не умеет возвращать файл, у которого
# исключён родительский каталог.
!device_firmware/multi_libreVNA_firmware/reproduce/build.sh
!device_firmware/multi_libreVNA_firmware/reproduce/LibreVNA/Software/VNA_embedded/build/
!device_firmware/multi_libreVNA_firmware/reproduce/LibreVNA/Software/VNA_embedded/build_external_lo_slave/
+31 -8
View File
@@ -65,17 +65,36 @@ PROCESSOR_SOURCES := \
# from the vendored headers alone and only needs those libraries present at run
# time. Built on demand (not part of `all`) for radar.model == kamil_adc.
KAMIL_COLLECTOR_DIR := data_acq_and_processing/kamil_adc_collector
KAMIL_COLLECTOR_INCLUDES := -I$(KAMIL_COLLECTOR_DIR)/include -I$(KAMIL_COLLECTOR_DIR)/vendor/lcard
# The collector now also drives the RF switches itself (switch-aware mode), so it
# reuses the orchestrator's switch drivers and the shared run_config loader, which
# pull in the common config/ipc/locator headers and the vendored nlohmann/json.
KAMIL_COLLECTOR_INCLUDES := \
-I$(KAMIL_COLLECTOR_DIR)/include \
-I$(KAMIL_COLLECTOR_DIR)/vendor/lcard \
-Idata_acq_and_processing/common_cpp/ipc/include \
-Idata_acq_and_processing/common_cpp/config/include \
-Idata_acq_and_processing/sweep_orchestrator/device_drivers/interfaces \
-Idata_acq_and_processing/sweep_orchestrator/device_drivers/switches \
-Idata_acq_and_processing/processing/locator/include \
-Idata_acq_and_processing/third_party
KAMIL_COLLECTOR_LDFLAGS := -pthread -ldl -lutil
# Collector sources, including the shared drivers/config loader it reuses. These
# are compiled into a private build/kamil/ tree (see rule below) so they never
# collide with the orchestrator's objects, which use different compile flags.
KAMIL_COLLECTOR_SOURCES := \
$(KAMIL_COLLECTOR_DIR)/src/main.cpp \
$(KAMIL_COLLECTOR_DIR)/src/tty_protocol_writer.cpp \
$(KAMIL_COLLECTOR_DIR)/src/capture_file_writer.cpp
$(KAMIL_COLLECTOR_DIR)/src/capture_file_writer.cpp \
data_acq_and_processing/common_cpp/config/src/run_config.cpp \
data_acq_and_processing/common_cpp/ipc/src/shared_types.cpp \
data_acq_and_processing/sweep_orchestrator/device_drivers/switches/h7992_minimal_driver.cpp \
data_acq_and_processing/sweep_orchestrator/device_drivers/switches/hmc349a_minimal_driver.cpp
SWEEP_ORCH_OBJS := $(addprefix $(BUILD_DIR)/,$(COMMON_SOURCES:.cpp=.o) $(ORCH_SOURCES:.cpp=.o))
PREPROCESSOR_OBJS := $(addprefix $(BUILD_DIR)/,$(COMMON_SOURCES:.cpp=.o) $(PREPROC_SOURCES:.cpp=.o))
DATA_PROCESSOR_OBJS := $(addprefix $(BUILD_DIR)/,$(COMMON_SOURCES:.cpp=.o) $(PROCESSOR_SOURCES:.cpp=.o))
KAMIL_COLLECTOR_OBJS := $(addprefix $(BUILD_DIR)/,$(KAMIL_COLLECTOR_SOURCES:.cpp=.o))
KAMIL_BUILD_DIR := $(BUILD_DIR)/kamil
KAMIL_COLLECTOR_OBJS := $(addprefix $(KAMIL_BUILD_DIR)/,$(notdir $(KAMIL_COLLECTOR_SOURCES:.cpp=.o)))
DEPFILES := $(sort $(SWEEP_ORCH_OBJS:.o=.d) $(PREPROCESSOR_OBJS:.o=.d) $(DATA_PROCESSOR_OBJS:.o=.d) $(KAMIL_COLLECTOR_OBJS:.o=.d))
TARGETS := \
@@ -101,11 +120,15 @@ $(BIN_DIR)/data_processor: $(DATA_PROCESSOR_OBJS)
@mkdir -p $(BIN_DIR)
$(CXX) $(DATA_PROCESSOR_OBJS) -o $@ $(LDFLAGS)
# The collector is self-contained: compile its objects with only the vendored
# L-Card headers (no project/VISA includes) by overriding the generic rule's
# variables for these objects, then link with dlopen/openpty support.
$(KAMIL_COLLECTOR_OBJS): INCLUDES := $(KAMIL_COLLECTOR_INCLUDES)
$(KAMIL_COLLECTOR_OBJS): VISA_CXXFLAGS :=
# The collector compiles into its own build/kamil/ tree with collector-only
# includes (no VISA), so the shared driver/config sources it reuses never collide
# with the orchestrator's objects of the same name. Basenames are unique, so a
# vpath lets one pattern rule find every source.
vpath %.cpp $(sort $(dir $(KAMIL_COLLECTOR_SOURCES)))
$(KAMIL_BUILD_DIR)/%.o: %.cpp
@mkdir -p $(dir $@)
$(CXX) $(CXXFLAGS) $(KAMIL_COLLECTOR_INCLUDES) -c $< -o $@
$(BIN_DIR)/kamil_adc_collector: $(KAMIL_COLLECTOR_OBJS)
@mkdir -p $(BIN_DIR)
+4 -2
View File
@@ -69,9 +69,11 @@ controls plus a pixel-identical live plot through an embedded web UI.
## Requirements
- Linux (POSIX shared memory; GPIO on Raspberry Pi).
- Linux (POSIX shared memory; GPIO on Raspberry Pi). The deployment target is a
**Raspberry Pi 5**; hardware PWM gating for the generator sweep is Pi 5
specific (GPIO12/13/18/19, `dtoverlay=pwm-2chan`).
- A C++20 compiler and `make` — Eigen and nlohmann/json are vendored, so no extra C++ dependencies are needed.
- Python 3.12 with a virtual environment.
- **Python 3.10 or newer**, in a virtual environment.
## Build and run
@@ -38,6 +38,13 @@ struct SweepTraceBlock {
std::vector<Complex32> s11{};
// Complex S21 samples for matching frequency points.
std::vector<Complex32> s21{};
// Monotonic window in which THIS trace's sweep was measured, excluding the
// switch drive and settling that preceded it. In a switched matrix the
// collection is assembled combo by combo over many milliseconds, so the
// collection-level window says nothing about when an individual combo was
// measured. Zero on both is a valid "unmeasured" sentinel.
std::uint64_t capture_start_ns = 0;
std::uint64_t capture_end_ns = 0;
};
struct RawSweepCollection {
@@ -172,6 +172,10 @@ void require_count_fits(std::uint32_t count, std::size_t min_bytes_each, BinaryR
return trace;
}
// The capture windows live in a TRAILER after the trace blocks rather than inside
// them, so a reader built before they existed still decodes every trace and simply
// stops early. The trailer grows the same way: collection window first, then the
// per-trace window table (one pair per trace, in trace order).
void write_trace_collection(BinaryWriter& writer, std::uint32_t magic, const RawSweepCollection& collection) {
writer.write(magic);
writer.write(collection.collection_id);
@@ -184,6 +188,12 @@ void write_trace_collection(BinaryWriter& writer, std::uint32_t magic, const Raw
writer.write(collection.capture_start_ns);
writer.write(collection.capture_end_ns);
writer.write(checked_count_to_u32(collection.traces.size(), "Trace capture window count"));
for (const auto& trace : collection.traces) {
writer.write(trace.capture_start_ns);
writer.write(trace.capture_end_ns);
}
}
[[nodiscard]] auto read_trace_collection(BinaryReader& reader, std::uint32_t expected_magic) -> RawSweepCollection {
@@ -204,16 +214,31 @@ void write_trace_collection(BinaryWriter& writer, std::uint32_t magic, const Raw
collection.traces.push_back(read_trace_block(reader));
}
// Each trailer stage is optional: a payload from an older producer stops after
// the trace blocks (or after the collection window) and leaves the rest zeroed.
if (reader.remaining_bytes() == 0U) {
return collection;
}
if (reader.remaining_bytes() != (sizeof(std::uint64_t) * 2U)) {
throw std::runtime_error("Unexpected trailing bytes in trace collection");
if (reader.remaining_bytes() < (sizeof(std::uint64_t) * 2U)) {
throw std::runtime_error("Truncated capture window in trace collection");
}
collection.capture_start_ns = reader.read<std::uint64_t>();
collection.capture_end_ns = reader.read<std::uint64_t>();
if (reader.remaining_bytes() == 0U) {
return collection;
}
const auto trace_time_count = reader.read<std::uint32_t>();
if (trace_time_count != collection.traces.size()) {
throw std::runtime_error("Per-trace capture window count does not match trace count");
}
for (auto& trace : collection.traces) {
trace.capture_start_ns = reader.read<std::uint64_t>();
trace.capture_end_ns = reader.read<std::uint64_t>();
}
return collection;
}
@@ -188,7 +188,7 @@ auto ShmRing::open_or_create(
const bool geometry_ok = header->capacity == capacity && header->slot_size_bytes == slot_size_bytes;
if (magic_ok && version_ok && geometry_ok) {
// Fix #50: the requested mapped_size matched the header geometry, but the
// the requested mapped_size matched the header geometry, but the
// backing file may have been created undersized by another process. Confirm
// st_size covers the geometry before trusting the mapping.
struct stat info {};
@@ -257,7 +257,7 @@ auto ShmRing::open_existing(const std::string& name) -> ShmRing {
if (header->version != kRingVersion) {
throw std::runtime_error("Shared memory ring version mismatch for " + name);
}
// Fix #50: ensure the mapping actually spans every slot the header describes.
// ensure the mapping actually spans every slot the header describes.
validate_geometry(*header, mapped_size, name);
ShmRing ring{};
@@ -411,7 +411,7 @@ void ShmRing::validate_name(const std::string& name) {
}
void ShmRing::validate_geometry(const Header& header, std::size_t mapped_size, const std::string& name) {
// Fix #50: derive the expected size from the header's own geometry fields and
// derive the expected size from the header's own geometry fields and
// require the real mapping to cover it. A bogus capacity/slot_size or a truncated
// mapping would otherwise yield out-of-bounds slot offsets and a SIGSEGV.
const std::uint32_t capacity = header.capacity;
@@ -13,12 +13,18 @@ counterpart to the C++ `sweep_orchestrator` used by LibreVNA devices.
| Path | Contents |
|------|----------|
| `src/` | Collector implementation (`main.cpp`) and the PTY / capture-file writers. |
| `include/` | Headers for the writers. |
| `include/` | Headers for the writers plus `switch_sequencer.h`. |
| `vendor/lcard/` | L-Card X502/E502 SDK headers (`x502api.h`, `e502api.h`, `lcard_pstdint.h`), vendored verbatim so the collector builds with no external include path. |
The sources under `src/` and `include/` are imported verbatim from the original
standalone tool and are kept byte-for-byte identical — the wire format and
acquisition behaviour are unchanged; only their home moved into this repo.
The sources started as a verbatim import of the original standalone tool, but are
**no longer identical to it**: the collector now drives the RF switches itself
(switch-aware mode, `SwitchSequencer`), stepping to the next combination inside
the hardware idle gap between sweeps and flagging a sweep *dirty* when a readout
backlog means the toggle could not have landed in that gap. It therefore reuses
the orchestrator's switch drivers and the shared `run_config` loader, which is why
its build has its own include set and its own `build/kamil/` object tree.
The wire format towards the Python producer is unchanged.
## Build
@@ -0,0 +1,147 @@
#pragma once
#include <cstddef>
#include <memory>
#include <utility>
#include <vector>
#include "shared_types.hpp"
#include "switch_driver.hpp"
namespace radar::kamil {
/**
* @brief Drives the input/output RF switches in lock-step with sweep boundaries.
*
* The E-502 stream is free-running: sweeps are delimited by DI_SYN2 edges with a
* hardware idle gap between them. On every completed sweep we step to the next
* switch combination *during that gap*, so the next sweep starts already settled
* in the new state and no samples are lost.
*
* The one failure mode of doing this purely in software is the readout backlog:
* if, at the moment we observe a sweep's end, we are running so far behind real
* time that the toggle could not have landed within the gap, the upcoming sweep
* straddles the transition. We flag that sweep *dirty*; the consumer drops it and
* we re-take the same combination on the following sweep (which is then clean,
* because no transition happens during its gap). A clean sweep costs nothing; a
* miss costs exactly one extra sweep period for that one combination.
*
* The sequencer owns the two switch drivers and exposes only what the collector
* needs at a sweep boundary: which combination the upcoming sweep belongs to and
* whether it is expected to be clean. All timing policy lives here so the recv
* loop stays readable.
*/
class SwitchSequencer {
public:
struct Settings {
/// Combinations to cycle through, one sweep each, in order. Empty disables
/// the sequencer entirely (the collector then streams a single passthrough
/// channel exactly as before).
std::vector<radar::ipc::ComboKey> combos{};
/// Guaranteed minimum inter-sweep idle window, in milliseconds. This is a
/// hardware property of the sweep generator; treat it as a lower bound.
double gap_ms = 10.0;
/// RF settle time required after a position change, in milliseconds.
double settle_ms = 1.0;
};
SwitchSequencer(
Settings settings,
std::unique_ptr<drivers::SwitchDriver> input_switch,
std::unique_ptr<drivers::SwitchDriver> output_switch
)
: settings_(std::move(settings)),
input_switch_(std::move(input_switch)),
output_switch_(std::move(output_switch)) {}
[[nodiscard]] auto enabled() const -> bool { return !settings_.combos.empty(); }
/// Open both switch drivers and park at the first combination.
void open() {
if (!enabled()) {
return;
}
output_switch_->open();
input_switch_->open();
index_ = 0;
applied_ = settings_.combos.front();
apply(applied_);
upcoming_dirty_ = false; // the first sweep is captured in a settled state
}
void close() {
if (!enabled()) {
return;
}
// Best-effort: teardown must never throw out of the collector's stop path.
try {
output_switch_->close();
} catch (...) {
}
try {
input_switch_->close();
} catch (...) {
}
}
/// Combination the in-progress / upcoming sweep is captured under.
[[nodiscard]] auto current_combo() const -> radar::ipc::ComboKey {
return settings_.combos[index_];
}
/// Whether the in-progress / upcoming sweep is expected to straddle a switch
/// transition and must be dropped by the consumer.
[[nodiscard]] auto current_dirty() const -> bool { return upcoming_dirty_; }
/**
* @brief Advance the sequence at a completed sweep's end (start of the gap).
*
* @param backlog_ms Estimated readout lag at this instant — how far behind
* real time we are, i.e. how late the toggle we issue now will land.
*
* If the sweep that just ended was clean we step to the next combination and
* toggle the switches now, inside the gap. If it was dirty we re-take the same
* combination (the switches are already there and long settled). The upcoming
* sweep is marked dirty only when a real transition happens *and* the backlog
* leaves no room for it to settle before the next sweep starts.
*/
void on_sweep_end(double backlog_ms) {
if (!enabled()) {
return;
}
if (upcoming_dirty_) {
// The sweep that just ended straddled a transition: re-take the same
// combination. The switches are already applied and settled, so the
// next sweep is clean without touching the hardware again.
upcoming_dirty_ = false;
return;
}
index_ = (index_ + 1U) % settings_.combos.size();
const radar::ipc::ComboKey next = settings_.combos[index_];
const bool position_changed = !(next == applied_);
if (position_changed) {
apply(next);
applied_ = next;
}
upcoming_dirty_ = position_changed && ((backlog_ms + settings_.settle_ms) > settings_.gap_ms);
}
private:
void apply(const radar::ipc::ComboKey& combo) {
// Output first, then input — same order the sweep orchestrator uses, so
// both acquisition paths drive an identical hardware sequence.
output_switch_->switch_to(combo.output_pos);
input_switch_->switch_to(combo.input_pos);
}
Settings settings_;
std::unique_ptr<drivers::SwitchDriver> input_switch_;
std::unique_ptr<drivers::SwitchDriver> output_switch_;
std::size_t index_ = 0;
radar::ipc::ComboKey applied_{};
bool upcoming_dirty_ = false;
};
} // namespace radar::kamil
@@ -17,6 +17,11 @@
#include "capture_file_writer.h"
#include "tty_protocol_writer.h"
#include "switch_sequencer.h"
#include "run_config.hpp"
#include "h7992_minimal_driver.hpp"
#include "hmc349a_minimal_driver.hpp"
#include <algorithm>
#include <array>
#include <atomic>
@@ -113,6 +118,12 @@ struct Config {
std::string live_html_path = "live_plot.html";
std::string live_json_path = "live_plot.json";
std::optional<std::string> tty_path;
// When set, the collector reads switch and combo configuration from this
// run_config.json and drives the RF switches itself, one combination per
// sweep, tagging each emitted sweep with its combo (see SwitchSequencer).
std::optional<std::string> run_config_path;
double switch_gap_ms = 10.0;
double switch_settle_ms = 1.0;
bool di1_group_average = false;
bool do1_toggle_per_frame = false;
bool do1_noise_subtract = false;
@@ -479,6 +490,7 @@ void print_help(const char* exe_name) {
<< " [di1:zero|trace|ignore]\n"
<< " [duration_ms:100] [packet_limit:0] [csv:capture.csv] [svg:capture.svg]\n"
<< " [live_html:live_plot.html] [live_json:live_plot.json] [tty:/tmp/ttyADC_data] [di1_group_avg]\n"
<< " [config:run_config.json] [switch_gap_ms:10] [switch_settle_ms:1]\n"
<< " [do1_toggle_per_frame] [do1_noise_subtract] [do1_raw_tty_marked] [do1_pair_subtract_avg] [noise_avg_steps:N]\n"
<< " [do8_freq_ref] [do8_cycle_period:10] [do8_threshold:X]\n"
<< " [recv_block:32768] [stats_period_ms:1000] [live_update_period_ms:1000] [svg_history_packets:50] [start_wait_ms:10000]\n"
@@ -514,6 +526,13 @@ void print_help(const char* exe_name) {
<< " step_words:32768 -> input stream transfer step in 32-bit words\n"
<< " live_html/live_json -> live graph files updated as packets arrive outside tty fast stream-only modes\n"
<< " tty:/tmp/ttyADC_data -> write a continuous legacy 4-word CH1/CH2 stream; with channels:1, CH2 is 0\n"
<< " config:run_config.json -> switch-aware mode: read the input/output switch and combo\n"
<< " configuration from this run_config.json and drive the RF switches\n"
<< " in lock-step with sweeps; each sweep is tagged with its combo via a\n"
<< " 0x00C0 frame (input_pos, output_pos, dirty). Omit for standalone mode.\n"
<< " switch_gap_ms:10 -> guaranteed minimum inter-sweep idle window; lower bound used to decide\n"
<< " whether an in-gap switch lands before the next sweep starts\n"
<< " switch_settle_ms:1 -> RF settle time required after a switch position change\n"
<< " di1_group_avg -> with tty + di1:trace, emit one averaged 4-word step per constant DI1 run\n"
<< " do1_toggle_per_frame -> hardware cyclic DO1 pattern in module memory:\n"
<< " DO1 outputs 00110011... continuously (toggle every 2 ADC ticks)\n"
@@ -793,6 +812,18 @@ Config parse_args(int argc, char** argv) {
cfg.tty_path = arg.substr(4);
continue;
}
if (starts_with(arg, "config:")) {
cfg.run_config_path = arg.substr(7);
continue;
}
if (starts_with(arg, "switch_gap_ms:")) {
cfg.switch_gap_ms = parse_double(arg.substr(14), "switch_gap_ms");
continue;
}
if (starts_with(arg, "switch_settle_ms:")) {
cfg.switch_settle_ms = parse_double(arg.substr(17), "switch_settle_ms");
continue;
}
fail("Unknown argument: " + arg);
}
@@ -1203,6 +1234,10 @@ constexpr uint32_t kDo1TogglePeriodTicks = 2U;
constexpr uint32_t kDo1CyclePatternWords = kDo1TogglePeriodTicks * 2U;
constexpr uint32_t kDo8HighTicks = 2U;
constexpr uint16_t kTtyMarkerDi8High = 0x00A8U;
// Combo tag frame: [0x00C0, input_pos, output_pos, dirty]. Emitted right after a
// sweep-boundary frame to tell the consumer which switch combination the upcoming
// sweep belongs to, and whether it straddled a switch transition (dirty != 0).
constexpr uint16_t kTtyMarkerComboTag = 0x00C0U;
constexpr uint32_t kStreamInputAdcFlag = 0x80000000U;
constexpr uint32_t kStreamInputCalibratedAdcFlag = 0x40000000U;
@@ -1802,6 +1837,55 @@ void print_device_info(const t_x502_info& info) {
<< "MCU firmware: " << info.mcu_firmware_ver << "\n";
}
// Build one switch driver (native GPIO or mock) from a parsed switch config,
// reusing the exact driver implementations the sweep orchestrator uses so both
// acquisition paths drive identical hardware.
std::unique_ptr<radar::drivers::SwitchDriver> make_switch_driver(const radar::config::SwitchConfig& sc) {
if (sc.driver_kind == radar::config::SwitchDriverKind::HMC349A) {
return std::make_unique<radar::drivers::HMC349AMinimalDriver>(
radar::drivers::HMC349AMinimalDriverSettings{
.name = sc.name,
.mode = sc.driver_mode,
.positions = sc.positions,
.default_position = sc.default_position,
.gpio_chip = sc.gpio_chip,
.pin_a = sc.pin_a,
.invert_logic = sc.invert_logic,
});
}
return std::make_unique<radar::drivers::H7992MinimalDriver>(
radar::drivers::H7992MinimalDriverSettings{
.name = sc.name,
.mode = sc.driver_mode,
.positions = sc.positions,
.default_position = sc.default_position,
.gpio_chip = sc.gpio_chip,
.pin_a = sc.pin_a,
.pin_b = sc.pin_b,
});
}
// Construct the switch sequencer from the run_config given via `config:<path>`.
// Returns nullptr (switching disabled, single-channel passthrough) when no config
// was supplied or it declares no combinations.
std::unique_ptr<radar::kamil::SwitchSequencer> make_switch_sequencer(const Config& cfg) {
if (!cfg.run_config_path.has_value()) {
return nullptr;
}
const radar::config::RunConfig rc = radar::config::load_run_config(*cfg.run_config_path);
if (rc.run_combos.empty()) {
return nullptr;
}
radar::kamil::SwitchSequencer::Settings settings;
settings.combos = rc.run_combos;
settings.gap_ms = cfg.switch_gap_ms;
settings.settle_ms = cfg.switch_settle_ms;
return std::make_unique<radar::kamil::SwitchSequencer>(
std::move(settings),
make_switch_driver(rc.input_switch),
make_switch_driver(rc.output_switch));
}
int run(const Config& cfg) {
Api api;
DeviceHandle device(api);
@@ -2029,6 +2113,21 @@ int run(const Config& cfg) {
tty_writer->emit_packet_start(tty_packet_start_marker);
}
}
// Switch sequencer (optional): drives the RF switches in lock-step with sweep
// boundaries and tags each sweep with its combination. Disabled (nullptr) when
// no run_config was passed, so the standalone/calibration use stays unchanged.
std::unique_ptr<radar::kamil::SwitchSequencer> sequencer = make_switch_sequencer(cfg);
if (sequencer && sequencer->enabled()) {
sequencer->open();
std::cout << "Switch sequencer enabled: cycling switch combinations per sweep "
<< "(gap_ms=" << cfg.switch_gap_ms << ", settle_ms=" << cfg.switch_settle_ms << ")\n";
} else {
sequencer.reset(); // normalize to nullptr so call sites can test the pointer
}
// Estimated readout backlog (ms) at the current loop iteration; how far behind
// real time we are, used to decide whether an in-gap switch lands in time.
double current_backlog_ms = 0.0;
std::unique_ptr<CaptureFileWriter> writer;
if (!fast_tty_avg_stream_mode) {
writer = std::make_unique<CaptureFileWriter>(cfg.csv_path, cfg.svg_path, cfg.live_html_path, cfg.live_json_path);
@@ -2317,6 +2416,15 @@ int run(const Config& cfg) {
auto append_tty_packet_start = [&]() {
append_tty_frame(tty_packet_start_marker, 0xFFFF, 0xFFFF, 0xFFFF);
// Right after the boundary, tag the upcoming sweep with its switch combo so
// the consumer can group sweeps and drop the dirty ones.
if (sequencer) {
const radar::ipc::ComboKey combo = sequencer->current_combo();
append_tty_frame(kTtyMarkerComboTag,
static_cast<uint16_t>(combo.input_pos),
static_cast<uint16_t>(combo.output_pos),
static_cast<uint16_t>(sequencer->current_dirty() ? 1U : 0U));
}
};
auto append_tty_group_step = [&]() {
@@ -2714,6 +2822,12 @@ int run(const Config& cfg) {
std::cout << "\n";
}
// A real sweep just completed: step the switch sequence into the gap. A
// user-stop teardown is not a sweep boundary, so skip it.
if (sequencer && (frames != 0U) && (reason != PacketCloseReason::UserStop)) {
sequencer->on_sweep_end(current_backlog_ms);
}
packet_active = false;
packet_avg_steps = 0;
fast_packet_frames = 0;
@@ -2768,6 +2882,11 @@ int run(const Config& cfg) {
recv_request_words = std::min<uint32_t>(ready_words, read_capacity_words);
recv_timeout_ms = 0;
}
// Backlog already queued in the driver = how far behind real time we are.
// Drives the switch sequencer's in-gap clean/dirty decision.
if ((ready_err == X502_ERR_OK) && (combined_input_rate_hz > 0.0)) {
current_backlog_ms = 1000.0 * static_cast<double>(ready_words) / combined_input_rate_hz;
}
const int32_t recvd = api.Recv(device.hnd, raw.data(), recv_request_words, recv_timeout_ms);
if (recvd < 0) {
@@ -3170,6 +3289,11 @@ int run(const Config& cfg) {
expect_ok(api, api.StreamsStop(device.hnd), "Stop streams");
device.streams_started = false;
// Park the switches in their safe default and release the GPIO lines.
if (sequencer) {
sequencer->close();
}
if (cfg.do1_toggle_per_frame) {
const uint32_t clear_mask = kE502Do1Mask | kE502Do2Mask | (cfg.do8_freq_ref ? kE502Do8Mask : 0U);
expect_ok(api,
@@ -34,6 +34,9 @@ auto CalibrationMaster::apply_to_trace(const ipc::SweepTraceBlock& measured_trac
output.frequency_hz = measured_trace.frequency_hz;
output.s21 = apply_s21(measured_trace.combo, measured_trace.frequency_hz, measured_trace.s21);
output.s11 = apply_s11(measured_trace.combo, measured_trace.frequency_hz, measured_trace.s11);
// Calibration reshapes the samples, not when they were measured.
output.capture_start_ns = measured_trace.capture_start_ns;
output.capture_end_ns = measured_trace.capture_end_ns;
return output;
}
@@ -132,6 +132,9 @@ auto ReferenceMaster::apply_to_trace(const ipc::SweepTraceBlock& calibrated_trac
output.frequency_hz = calibrated_trace.frequency_hz;
output.s21 = apply_s21(calibrated_trace.combo, calibrated_trace.frequency_hz, calibrated_trace.s21);
output.s11 = apply_s11(calibrated_trace.combo, calibrated_trace.frequency_hz, calibrated_trace.s11);
// Reference subtraction reshapes the samples, not when they were measured.
output.capture_start_ns = calibrated_trace.capture_start_ns;
output.capture_end_ns = calibrated_trace.capture_end_ns;
return output;
}
@@ -45,8 +45,10 @@ struct ProcessingLiveConfig {
float gpr_min_depth_m = 2.0F;
float gpr_max_depth_m = 14.0F;
float gpr_range_comp_power = 0.1F;
float gpr_angle_comp_power = 0.0F;
float gpr_comp_power = 0.2F;
// BP object-detection stop level, as a fraction of the global peak (Python
// Horns_motion_3libre.py BP_OBJECT_MIN_FRAC); peaks below it are not objects.
float gpr_object_min_frac = 0.7F;
std::string gpr_score_mode = "combined";
// Backprojection intra-sweep speed-correction mode: "int_minus" (full
// correction) or "int_focus" (focusing residual only). Mirrors the Python
@@ -73,13 +75,15 @@ struct ProcessingLiveConfig {
// BP image is computed in the y=imaging_plane_y_m slice of the 3D grid.
// Default 0 keeps legacy 1D antenna layouts imaging in the antenna plane.
float gpr_imaging_plane_y_m = 0.0F;
// Locator filter parameters. Mode-dependent threshold (legacy_gpr uses
// `legacy_gpr_min_visible_pair_count`, everything else uses
// `gpr_min_visible_score`). Draw limits apply only to non-legacy modes.
float gpr_min_visible_score = 0.0F;
// Coherent BP object visibility (window + the draw limits below) is applied in
// the processor itself, matching Horns_motion_3libre.py — there is NO score
// threshold for it. Only legacy GPR still thresholds, on a pair count.
float legacy_gpr_min_visible_pair_count = 0.0F;
std::uint32_t gpr_max_detected_objects_to_draw = 0;
std::uint32_t gpr_draw_top_m_objects = 0;
// Cross-frame approach filter: an object is shown only once it persists as a
// motion-consistent track over this many consecutive frames (<= 1 disables it).
std::uint32_t gpr_object_approach_min_frames = 3;
// Visible X/Z window (metres). The locator clips broadcast objects to this
// window so the socket emits only what the desktop plot actually shows.
float gpr_visible_x_min_m = -2.0F;
@@ -65,7 +65,7 @@ void DataProcessor::run(const std::atomic<bool>& stop_requested) {
std::uint64_t last_applied_history_command_seq = 0;
std::uint64_t error_count = 0;
std::uint64_t consecutive_errors = 0;
// Fix #55: track the socket-fed speed used for the last reprocess so a change
// track the socket-fed speed used for the last reprocess so a change
// arriving without a live-config revision bump still triggers a reprocess of
// the current result (gated below by reprocess_current_result).
std::optional<double> last_reprocessed_socket_speed = std::nullopt;
@@ -124,7 +124,7 @@ void DataProcessor::run(const std::atomic<bool>& stop_requested) {
publish_locator(replay_result, live_config);
}
last_replayed_revision = live_revision;
// Fix #55: record the speed we just reprocessed with so an
//record the speed we just reprocessed with so an
// unchanged socket value does not retrigger every iteration.
last_reprocessed_socket_speed = current_socket_speed;
}
@@ -232,29 +232,23 @@ auto DataProcessor::build_locator_filter(const ProcessingLiveConfig& live_config
live_config.processor_mode.empty() ? default_processor_mode_ : live_config.processor_mode;
radar::locator::FilterParams filter{};
// Clip broadcast objects to the same visible X/Z window the desktop plot uses,
// so the socket emits only the objects the operator actually sees.
if (requested_mode == "legacy_gpr") {
// Legacy GPR emits its objects unfiltered, so the socket applies the legacy
// rule here: clip to the visible window and threshold on the pair count. The
// GUI disables "draw top N" for legacy, so we skip it on the wire to match.
filter.visible_bounds = radar::locator::VisibleBounds{
.x_min = live_config.gpr_visible_x_min_m,
.x_max = live_config.gpr_visible_x_max_m,
.z_min = live_config.gpr_visible_z_min_m,
.z_max = live_config.gpr_visible_z_max_m,
};
if (requested_mode == "legacy_gpr") {
filter.min_score = live_config.legacy_gpr_min_visible_pair_count;
// The GUI deliberately disables the "draw top N" capping for legacy
// GPR, so we also skip it on the wire to match observation semantics.
filter.draw_limits.reset();
} else {
filter.min_score = live_config.gpr_min_visible_score;
if (live_config.gpr_max_detected_objects_to_draw > 0U
&& live_config.gpr_draw_top_m_objects > 0U) {
filter.draw_limits = radar::locator::DrawLimits{
.max_detected_objects = live_config.gpr_max_detected_objects_to_draw,
.draw_top_objects = live_config.gpr_draw_top_m_objects,
};
}
}
// Coherent BP already emits the FINAL visible object set from the processor
// (window + N/M, no score threshold — matching Horns_motion_3libre.py), so the
// socket forwards it verbatim. The default FilterParams passes everything through
// (it only drops non-finite rows), keeping the filtering logic in one place.
return filter;
}
@@ -255,11 +255,11 @@ void apply_legacy_gpr_algorithm_alias(ProcessingLiveConfig& config, const std::s
}
config.gpr_range_comp_power = static_cast<float>(found->get<double>());
}
if (const auto found = root.find("gpr_angle_comp_power"); found != root.end()) {
if (const auto found = root.find("gpr_object_min_frac"); found != root.end()) {
if (!found->is_number()) {
throw std::runtime_error("processing.gpr_angle_comp_power must be number");
throw std::runtime_error("processing.gpr_object_min_frac must be number");
}
config.gpr_angle_comp_power = static_cast<float>(found->get<double>());
config.gpr_object_min_frac = static_cast<float>(found->get<double>());
}
if (const auto found = root.find("gpr_comp_power"); found != root.end()) {
if (!found->is_number()) {
@@ -355,12 +355,6 @@ void apply_legacy_gpr_algorithm_alias(ProcessingLiveConfig& config, const std::s
}
config.gpr_imaging_plane_y_m = static_cast<float>(found->get<double>());
}
if (const auto found = root.find("gpr_min_visible_score"); found != root.end()) {
if (!found->is_number()) {
throw std::runtime_error("processing.gpr_min_visible_score must be number");
}
config.gpr_min_visible_score = static_cast<float>(found->get<double>());
}
for (const auto& [key, target] : {
std::pair{"gpr_visible_x_min_m", &config.gpr_visible_x_min_m},
std::pair{"gpr_visible_x_max_m", &config.gpr_visible_x_max_m},
@@ -388,6 +382,10 @@ void apply_legacy_gpr_algorithm_alias(ProcessingLiveConfig& config, const std::s
config.gpr_draw_top_m_objects =
parse_u32_number(*found, "processing.gpr_draw_top_m_objects");
}
if (const auto found = root.find("gpr_object_approach_min_frames"); found != root.end()) {
config.gpr_object_approach_min_frames =
parse_u32_number(*found, "processing.gpr_object_approach_min_frames");
}
if (const auto found = root.find("ignore_socket_speed"); found != root.end()) {
if (!found->is_boolean()) {
throw std::runtime_error("processing.ignore_socket_speed must be bool");
@@ -1,5 +1,6 @@
#pragma once
#include "object_approach_filter.hpp"
#include "processor_interface.hpp"
namespace radar::processing {
@@ -13,6 +14,11 @@ class GprProcessor final : public ProcessorInterface {
std::span<const ipc::PreprocessedCollection> previous_collections,
const ProcessingLiveConfig& live_config
) -> ipc::ResultCollection override;
private:
// Cross-frame "approach" track filter. Persists across collections because the
// owning processor instance is long-lived (one per data_processor run).
ObjectApproachFilter approach_filter_{};
};
class LegacyGprProcessor final : public ProcessorInterface {
@@ -0,0 +1,172 @@
#pragma once
#include <algorithm>
#include <cmath>
#include <cstddef>
#include <cstdint>
#include <deque>
#include <limits>
#include <vector>
namespace radar::processing {
// Temporal "approach" filter for coherent-BP detections — a port of the objects-only
// filter in Horns_motion_3libre's demonstrate notebook.
//
// It keeps only objects that persist as a *motion-consistent track* across at least
// `min_frames` consecutive frames: as the radar moves, a real target reappears at a
// predictable, shifting (x, z), whereas a one-frame noise spike forms no track and is
// dropped. The expected per-frame change in range is `speed * dt * cos(look_angle)`,
// where `dt` is the real interval between consecutive frames (so dropped frames and a
// varying frame period are handled naturally).
//
// CAUSAL: unlike the offline notebook (which can look forward over the whole sequence),
// this confirms a track by looking *backward* — an object is kept once it ends a track
// of `min_frames` frames seen so far. A target therefore first appears after it has
// persisted `min_frames` frames; the early frames of its track are not shown
// retroactively.
//
// Stateless across pipeline restarts is approximated by breaking tracks across a large
// inter-frame gap (`kMaxFrameGapSeconds`), so a stale history from a previous run cannot
// spuriously confirm objects.
//
// IDEMPOTENT under reprocessing: the data_processor re-runs the last collection (or
// replays the whole window) whenever live settings or the socket speed change, with no
// new sweep. The history is therefore keyed by `frame_id` (the strictly increasing
// collection id): the same id replaces its entry (reprocess of the current frame), a
// smaller id rebuilds from scratch (a replay restart), so repeated reprocessing never
// duplicates frames or falsely confirms a track.
class ObjectApproachFilter {
public:
struct Point {
double x_m;
double z_m;
};
// Record `objects` as frame `frame_id` and return, per object, whether it is
// confirmed (ends a >= `min_frames` motion-consistent track). `frame_id` is the
// collection id (identity/order, survives reprocessing); `frame_time_seconds` is the
// frame's wall-clock timestamp (drives the inter-frame interval); `speed_m_s`/
// `look_angle_deg` are the live motion estimate. `min_frames <= 1` disables filtering.
[[nodiscard]] auto confirm(
const std::vector<Point>& objects,
std::uint64_t frame_id,
double frame_time_seconds,
double speed_m_s,
double look_angle_deg,
std::size_t min_frames
) -> std::vector<bool> {
record_frame(Frame{frame_id, frame_time_seconds, objects});
const std::size_t history_depth = std::max<std::size_t>(min_frames, 1U);
while (history_.size() > history_depth) {
history_.pop_front();
}
std::vector<bool> confirmed(objects.size(), min_frames <= 1U);
if (min_frames <= 1U || history_.size() < min_frames) {
return confirmed; // disabled, or not enough history yet to confirm anything
}
const double range_step_per_second = std::abs(speed_m_s) * std::cos(to_radians(look_angle_deg));
for (std::size_t object_index = 0U; object_index < objects.size(); ++object_index) {
confirmed[object_index] = has_backward_track(objects[object_index], min_frames, range_step_per_second);
}
return confirmed;
}
void reset() { history_.clear(); }
private:
struct Frame {
std::uint64_t id;
double time_seconds;
std::vector<Point> objects;
};
// Append a genuinely new frame, replace the current one on reprocessing (same id),
// or rebuild from scratch when the id steps backward (a replay restart). This keeps
// the history one entry per distinct collection no matter how often settings change.
void record_frame(Frame frame) {
if (history_.empty() || frame.id > history_.back().id) {
history_.push_back(std::move(frame));
} else if (frame.id == history_.back().id) {
history_.back() = std::move(frame);
} else {
history_.clear();
history_.push_back(std::move(frame));
}
}
// Fixed matching tolerances (Horns_motion notebook 0.2 block). Range decreases as the
// radar approaches the target, hence the negative Z sign.
static constexpr double kXToleranceM = 0.45;
static constexpr double kRangeToleranceFraction = 0.85;
static constexpr double kRangeToleranceFloorM = 0.12;
static constexpr double kRangeSign = -1.0;
static constexpr double kMaxFrameGapSeconds = 2.0;
[[nodiscard]] static auto to_radians(double degrees) -> double {
return degrees * (M_PI / 180.0);
}
// Walk back from the current object through the history, matching a motion-consistent
// predecessor in each earlier frame. Confirmed iff a full chain of `min_frames` frames
// (the current one plus `min_frames - 1` predecessors) is found.
[[nodiscard]] auto has_backward_track(
const Point& object,
std::size_t min_frames,
double range_step_per_second
) const -> bool {
const std::size_t newest = history_.size() - 1U;
Point current = object;
for (std::size_t step = 1U; step < min_frames; ++step) {
const std::size_t earlier_index = newest - step;
const Frame& earlier = history_[earlier_index];
const double dt = history_[earlier_index + 1U].time_seconds - earlier.time_seconds;
if (!(dt > 0.0) || dt > kMaxFrameGapSeconds) {
return false; // non-monotonic time, or a gap that breaks the track
}
const double expected_range_shift = range_step_per_second * dt;
const Point* predecessor = match_predecessor(current, earlier.objects, expected_range_shift);
if (predecessor == nullptr) {
return false;
}
current = *predecessor;
}
return true;
}
// The best earlier-frame object consistent with `object` having moved by one frame:
// its range was larger by `expected_range_shift` (radar since approached), within the
// cross-range and range tolerances. Returns nullptr when nothing matches.
[[nodiscard]] static auto match_predecessor(
const Point& object,
const std::vector<Point>& candidates,
double expected_range_shift
) -> const Point* {
const double target_z = object.z_m - (kRangeSign * expected_range_shift);
const double range_tolerance =
std::max(kRangeToleranceFloorM, kRangeToleranceFraction * expected_range_shift);
const Point* best = nullptr;
double best_cost = std::numeric_limits<double>::infinity();
for (const Point& candidate : candidates) {
const double dx = std::abs(candidate.x_m - object.x_m);
const double dz = std::abs(candidate.z_m - target_z);
if (dx > kXToleranceM || dz > range_tolerance) {
continue;
}
const double cost = (dx / kXToleranceM) * (dx / kXToleranceM)
+ (dz / range_tolerance) * (dz / range_tolerance);
if (cost < best_cost) {
best = &candidate;
best_cost = cost;
}
}
return best;
}
std::deque<Frame> history_{}; // recent frames, newest at the back; capped to min_frames
};
} // namespace radar::processing
@@ -21,7 +21,6 @@ constexpr double kSmoothSigma = 1.5;
// same default 'reflect' (half-sample symmetric) extension — see reflect_index.
constexpr double kGaussianTruncate = 4.0;
constexpr std::size_t kMaxObjects = 10U;
constexpr double kObjectMinFrac = 0.7;
constexpr double kRegionThresholdFrac = 0.75;
constexpr double kSuppressThresholdFrac = 0.20;
constexpr double kSuppressRadiusXM = 0.80;
@@ -1405,7 +1404,8 @@ void apply_depth_gate(
[[nodiscard]] auto find_bp_objects(
const std::vector<double>& bp_image,
const GridDefinition& grid
const GridDefinition& grid,
double min_frac
) -> std::vector<ObjectRecord> {
std::vector<ObjectRecord> objects{};
if (bp_image.empty() || grid.x_grid.size() < 2U || grid.z_grid.size() < 2U) {
@@ -1414,7 +1414,7 @@ void apply_depth_gate(
std::vector<double> work = bp_image;
const double global_peak = max_value(work);
const double stop_level = kObjectMinFrac * global_peak;
const double stop_level = min_frac * global_peak;
if (!(global_peak > 0.0)) {
return objects;
}
@@ -1740,7 +1740,15 @@ void add_bp_score_metrics(
}
}
[[nodiscard]] auto output_objects_sorted(
// Select the FINAL visible objects exactly as Horns_motion_3libre.py does, so the
// processor is the single source of truth: the GUI plot and the locator socket both
// consume this set verbatim (no second, duplicated filter). Steps, in order:
// 1. drop sidelobe candidates (when enabled), then sort by score (peak tie-break);
// 2. clip to the visible X/Z window (display window doubles as an object gate);
// 3. apply the N/M draw rule (BP_MAX_DETECTED_OBJECTS_TO_DRAW / BP_DRAW_TOP_M_OBJECTS):
// if more than N survive, show none; otherwise keep the top M.
// There is deliberately NO score threshold (the Python reference has none).
[[nodiscard]] auto select_visible_objects(
const std::vector<ObjectRecord>& objects,
const ProcessingLiveConfig& live_config
) -> std::vector<const ObjectRecord*> {
@@ -1750,6 +1758,12 @@ void add_bp_score_metrics(
if (live_config.gpr_remove_sidelobe_objects_enabled && object.sidelobe_candidate) {
continue;
}
if (object.x_m < live_config.gpr_visible_x_min_m
|| object.x_m > live_config.gpr_visible_x_max_m
|| object.z_m < live_config.gpr_visible_z_min_m
|| object.z_m > live_config.gpr_visible_z_max_m) {
continue;
}
visible.push_back(&object);
}
@@ -1759,6 +1773,17 @@ void add_bp_score_metrics(
}
return left->selected_score > right->selected_score;
});
// N/M draw rule (0 on either disables limiting, mirroring the GUI/locator default).
const auto max_detected = live_config.gpr_max_detected_objects_to_draw;
const auto draw_top = live_config.gpr_draw_top_m_objects;
if (max_detected > 0U && draw_top > 0U) {
if (visible.size() > max_detected) {
visible.clear();
} else if (visible.size() > draw_top) {
visible.resize(draw_top);
}
}
return visible;
}
@@ -1815,7 +1840,8 @@ void add_bp_score_metrics(
const config::RunConfig& run_config,
const ipc::PreprocessedCollection& collection,
std::span<const ipc::PreprocessedCollection> previous_collections,
const ProcessingLiveConfig& live_config
const ProcessingLiveConfig& live_config,
ObjectApproachFilter& approach_filter
) -> ipc::ResultCollection {
ipc::ResultCollection results{};
results.collection_id = collection.collection_id;
@@ -1833,8 +1859,10 @@ void add_bp_score_metrics(
return results;
}
const double velocity_mps =
kSpeedOfLightMetersPerSec / std::sqrt(std::max(1e-6, static_cast<double>(run_config.gpr.relative_permittivity)));
// Coherent BP fixes the medium to vacuum/air (eps_r = 1), matching the Python
// reference Horns_motion_3libre.py (its 0.3 block hardcodes eps_r = 1.0). The
// configurable relative_permittivity stays a legacy-GPR-only knob.
const double velocity_mps = kSpeedOfLightMetersPerSec;
const double start_hz = static_cast<double>(live_config.gpr_start_freq_mhz) * 1'000'000.0;
const double stop_hz = static_cast<double>(live_config.gpr_stop_freq_mhz) * 1'000'000.0;
const double min_depth_m = static_cast<double>(live_config.gpr_min_depth_m);
@@ -1920,7 +1948,7 @@ void add_bp_score_metrics(
min_depth_m,
max_depth_m,
std::max(0.0, static_cast<double>(live_config.gpr_range_comp_power)),
std::max(0.0, static_cast<double>(live_config.gpr_angle_comp_power))
0.0 // angle compensation fixed off (Python Horns_motion_3libre.py COMP_ANGLE_POWER = 0.0)
);
if (bp.image.empty()) {
return results;
@@ -1930,7 +1958,7 @@ void add_bp_score_metrics(
const auto incoherent_display_map =
normalize_bp_map(bp.incoherent, grid, min_depth_m, max_depth_m, kSmoothSigma);
auto objects = find_bp_objects(display_map, grid);
auto objects = find_bp_objects(display_map, grid, static_cast<double>(live_config.gpr_object_min_frac));
add_local_prominence_metrics(objects, display_map, grid, min_depth_m, max_depth_m);
add_incoherent_support_metrics(objects, incoherent_display_map, bp.coherence_factor);
mark_sidelobe_candidates(objects, selected_traces, selection, imaging_plane_y_m);
@@ -1951,14 +1979,34 @@ void add_bp_score_metrics(
results.collection_payloads.push_back(build_image_payload("gpr_accumulator", grid.x_grid, grid.z_grid, display_map));
// Final visible set (window + N/M), then the cross-frame approach filter: keep only
// objects confirmed as a >= min_frames motion-consistent track (Horns_motion notebook).
const auto visible = select_visible_objects(objects, live_config);
std::vector<ObjectApproachFilter::Point> visible_points{};
visible_points.reserve(visible.size());
for (const auto* object : visible) {
visible_points.push_back({object->x_m, object->z_m});
}
const auto confirmed = approach_filter.confirm(
visible_points,
collection.collection_id,
static_cast<double>(collection.monotonic_ns) * 1e-9,
static_cast<double>(live_config.gpr_speed_m_s),
static_cast<double>(live_config.gpr_look_angle_deg),
static_cast<std::size_t>(live_config.gpr_object_approach_min_frames)
);
std::vector<std::vector<float>> point_rows{};
point_rows.reserve(objects.size());
for (const auto* object : output_objects_sorted(objects, live_config)) {
point_rows.reserve(visible.size());
for (std::size_t index = 0U; index < visible.size(); ++index) {
if (!confirmed[index]) {
continue;
}
point_rows.push_back(
{
static_cast<float>(object->x_m),
static_cast<float>(object->z_m),
static_cast<float>(object->selected_score),
static_cast<float>(visible[index]->x_m),
static_cast<float>(visible[index]->z_m),
static_cast<float>(visible[index]->selected_score),
}
);
}
@@ -36,7 +36,7 @@ auto GprProcessor::process_collection(
std::span<const ipc::PreprocessedCollection> previous_collections,
const ProcessingLiveConfig& live_config
) -> ipc::ResultCollection {
return process_backprojection_gpr(run_config, collection, previous_collections, live_config);
return process_backprojection_gpr(run_config, collection, previous_collections, live_config, approach_filter_);
}
auto LegacyGprProcessor::name() const -> std::string {
@@ -147,14 +147,18 @@ class DriverLifecycleGuard {
// Worst-case serialized size of a collection given the configured combo count and sweep
// point count, using the trace wire format (see ipc::write_trace_collection/write_trace_block):
// collection header: magic(4) + collection_id(8) + monotonic_ns(8) + trace_count(4)
// + capture_start_ns(8) + capture_end_ns(8) = 40 bytes
// + capture_start_ns(8) + capture_end_ns(8)
// + trace capture window count(4) = 44 bytes
// per trace block: input_pos(4) + output_pos(4) + point_count(4) = 12 bytes
// + per point: frequency(4) + s11(8) + s21(8) = 20 bytes
// + trailer: capture_start_ns(8) + capture_end_ns(8) = 16 bytes
[[nodiscard]] auto worst_case_serialized_bytes(std::size_t combo_count, std::uint32_t sweep_points) -> std::size_t {
constexpr std::size_t kCollectionHeaderBytes = 40U;
constexpr std::size_t kCollectionHeaderBytes = 44U;
constexpr std::size_t kTraceHeaderBytes = 12U;
constexpr std::size_t kBytesPerPoint = 20U;
const std::size_t per_trace = kTraceHeaderBytes + (static_cast<std::size_t>(sweep_points) * kBytesPerPoint);
constexpr std::size_t kTraceTrailerBytes = 16U;
const std::size_t per_trace =
kTraceHeaderBytes + (static_cast<std::size_t>(sweep_points) * kBytesPerPoint) + kTraceTrailerBytes;
return kCollectionHeaderBytes + (combo_count * per_trace);
}
@@ -207,7 +211,7 @@ SweepOrchestrator::SweepOrchestrator(
void SweepOrchestrator::run(const std::atomic<bool>& stop_requested) {
// Fail fast on a config error: a slot that is too small for the worst-case payload can
// never carry a full collection, so report it clearly at startup instead of dropping
// every collection at runtime (fix #27).
// every collection at runtime.
const auto worst_case_bytes = worst_case_serialized_bytes(config_.run_combos.size(), config_.radar.sweep.points);
if (worst_case_bytes > raw_ring_.slot_size_bytes()) {
throw std::runtime_error(
@@ -219,7 +223,7 @@ void SweepOrchestrator::run(const std::atomic<bool>& stop_requested) {
}
DriverLifecycleGuard lifecycle_guard(radar_driver_, input_switch_driver_, output_switch_driver_);
// Wait for the devices to become available before starting (fix #8/#9): an absent device
// Wait for the devices to become available before starting: an absent device
// makes the orchestrator wait, not exit.
if (!lifecycle_guard.open_all_with_retry(stop_requested)) {
return; // stop requested before any device became available
@@ -290,7 +294,12 @@ auto SweepOrchestrator::acquire_one_collection(
// Production drivers ignore this; mock drivers use it to give every
// (input, output) pair its own synthetic response.
radar_driver_.set_active_combo(combo);
// Stamp around the sweep only: the switch drive and settling above belong to
// neither the previous combo nor this one, so excluding them keeps the window
// an honest "when was this combo actually measured".
const auto sweep_start_ns = ipc::current_monotonic_ns();
auto sweep = radar_driver_.acquire_sweep();
const auto sweep_end_ns = ipc::current_monotonic_ns();
validate_sweep(sweep);
ipc::SweepTraceBlock trace{};
@@ -298,6 +307,8 @@ auto SweepOrchestrator::acquire_one_collection(
trace.frequency_hz = std::move(sweep.frequency_hz);
trace.s11 = std::move(sweep.s11);
trace.s21 = std::move(sweep.s21);
trace.capture_start_ns = sweep_start_ns;
trace.capture_end_ns = sweep_end_ns;
collection.traces.push_back(std::move(trace));
}
+5
View File
@@ -0,0 +1,5 @@
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch
+10
View File
@@ -0,0 +1,10 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
],
"unwantedRecommendations": [
"ms-vscode.cpptools-extension-pack"
]
}
@@ -0,0 +1,57 @@
# Протокол старого пульта тележки (реверс-инжиниринг)
Снято 2026-08-20 осциллографом Hantek DPO7204C с сигнального провода пульта
(канал CH3). Инструменты: `tools/capture.py` (захват), `tools/decode.py`
(декодер), сырые данные и картинки — в `captures/`.
## Физический уровень
- Один сигнальный провод, логика **3.3 В**.
- **Инвертированный UART** (стандартная полярность SBUS): в покое линия
**низкая** (~0 В), импульсы вверх до ~3.3 В.
- Скорость **100 000 бод**, формат **8E2** (8 бит данных, чётность even,
2 стоп-бита), биты LSB-first. Длительность бита 10 мкс.
## Кадровый уровень — SBUS
Стандартный кадр Futaba SBUS, 25 байт (3 мс на линии):
| Смещение | Размер | Содержимое |
|---|---|---|
| 0 | 1 | Заголовок `0x0F` |
| 1 | 22 | 16 каналов × 11 бит, упакованы подряд LSB-first |
| 23 | 1 | Флаги: bit0=CH17, bit1=CH18, bit2=frame_lost, bit3=failsafe |
| 24 | 1 | Футер `0x00` |
Распаковка каналов: 22 байта складываются в 176-битное число LSB-first,
канал N (N=0..15) = биты [11·N .. 11·N+10], диапазон значений 0–2047.
- Кадры отправляются каждые **50 мс** (20 Гц). Это медленнее стандартного
SBUS (7/14 мс) — ответная часть с этим темпом работает.
- Флаги во всех наблюдениях = `0x00`.
## Карта каналов (нумерация с 1)
| Управление | Канал | Мин | Нейтраль | Макс |
|---|---|---|---|---|
| Стик вперёд/назад | **2** | 433 (назад) | 1024 | 1643 (вперёд) |
| Стик влево/вправо | **4** | 446 (влево) | 1024 | 1654 (вправо) |
| Остальные 14 | — | всегда 1024 | | |
Диапазон осей ~±600 от нейтрали (не полная шкала SBUS). Других органов
управления на пульте нет.
Эталонный кадр нейтрали (hex):
```
0F 00 04 20 00 01 08 40 00 02 10 80 00 04 20 00 01 08 40 00 02 10 80 00 00
```
## Воспроизведение на STM32G431
- USART: 100000 бод, 8 бит + чётность even (в терминах STM32: M=1, 9-bit
с PCE=1), 2 стоп-бита, **TXINV=1** (аппаратная инверсия TX) — бит-бэнг
не нужен.
- Отправлять 25-байтовый кадр по таймеру каждые 50 мс.
- Нейтраль: все каналы 1024; управление — каналы 2 и 4 в измеренных
диапазонах.
@@ -0,0 +1,10 @@
[env:weact_g431cb]
platform = ststm32
board = genericSTM32G431CB
framework = arduino
upload_protocol = stlink
debug_tool = stlink
monitor_speed = 115200
build_flags =
-DUSBCON
-DUSBD_USE_CDC
+166
View File
@@ -0,0 +1,166 @@
// Пульт тележки: стик (АЦП PA0/PA1) -> SBUS на USART1 TX (PA9).
// Протокол: инвертированный SBUS, 100000 бод 8E2, 25 байт каждые 50 мс
// (см. docs/protocol.md). USB CDC (Serial) — отладочный вывод.
#include <Arduino.h>
// ---- калибровка стика (АЦП 12 бит, замерено 2026-08-20) ----
static const int X_FWD = 650, X_MID = 2014, X_BACK = 3378; // PA0 (плечи равны: 2014-650 = 3378-2014 = 1364)
static const int Y_RIGHT = 479, Y_MID = 1981, Y_LEFT = 3586; // PA1
static const int DEADZONE = 15; // отсечка дребезга вокруг нейтрали
// ---- SBUS-значения старого пульта ----
static const uint16_t SBUS_MID = 1024;
static const uint16_t CH2_MIN = 433, CH2_MAX = 1643; // назад..вперёд
static const uint16_t CH4_MIN = 446, CH4_MAX = 1654; // влево..вправо
// ---- expo: 0 = линейно, 1 = максимально мягкая нейтраль ----
static const float EXPO_K = 0.0f;
// ---- общий масштаб выхода: 1.0 = диапазон старого пульта ----
static const float RANGE_SCALE = 0.75f;
// симметричные плечи: вперёд и назад дают одинаковый максимум
static const uint16_t CH2_SPAN = 591; // min(1643-1024, 1024-433)
static const uint16_t CH4_SPAN = 578; // min(1654-1024, 1024-446)
// ---- профиль газа/поворота ----
static const float MOVE_START = 0.15f; // старт движения, доля хода стика
static const float POWER_FWD = 0.60f; // потолок «вперёд»
static const float POWER_BACK = 0.50f; // потолок «назад»
static const float POWER_TURN = 0.70f; // потолок поворота
static const uint16_t CH2_DB = 221; // мёртвая зона приёмника тележки (ЗАМЕРИТЬ по монитору)
static const uint16_t CH4_DB = 221;
static const uint32_t FRAME_PERIOD_MS = 50;
static const uint32_t PIN_X = PA0;
static const uint32_t PIN_Y = PA1;
static UART_HandleTypeDef s_sbusUart;
// USART1 TX = PA9 (AF7), 100000 бод, 8E2, TX инвертирован
static void sbusUartInit() {
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_USART1_CLK_ENABLE();
GPIO_InitTypeDef gpio = {};
gpio.Pin = GPIO_PIN_9;
gpio.Mode = GPIO_MODE_AF_PP;
gpio.Pull = GPIO_NOPULL;
gpio.Speed = GPIO_SPEED_FREQ_LOW;
gpio.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &gpio);
s_sbusUart.Instance = USART1;
s_sbusUart.Init.BaudRate = 100000;
s_sbusUart.Init.WordLength = UART_WORDLENGTH_9B; // 8 данных + чётность
s_sbusUart.Init.StopBits = UART_STOPBITS_2;
s_sbusUart.Init.Parity = UART_PARITY_EVEN;
s_sbusUart.Init.Mode = UART_MODE_TX;
s_sbusUart.Init.HwFlowCtl = UART_HWCONTROL_NONE;
s_sbusUart.Init.OverSampling = UART_OVERSAMPLING_16;
s_sbusUart.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_TXINVERT_INIT;
s_sbusUart.AdvancedInit.TxPinLevelInvert = UART_ADVFEATURE_TXINV_ENABLE;
HAL_UART_Init(&s_sbusUart);
}
// нормализация одной оси в [-1..1] с мёртвой зоной и асимметричными плечами
static float axisNorm(int adc, int lowEnd, int mid, int highEnd) {
float x;
if (adc < mid - DEADZONE) {
x = (float)(mid - adc) / (float)(mid - lowEnd); // к lowEnd -> +1
} else if (adc > mid + DEADZONE) {
x = -(float)(adc - mid) / (float)(highEnd - mid); // к highEnd -> -1
} else {
return 0.0f;
}
return constrain(x, -1.0f, 1.0f);
}
// expo-кривая: гасит чувствительность у нейтрали, сохраняет края
static float expo(float x) {
return EXPO_K * x * x * x + (1.0f - EXPO_K) * x;
}
static uint16_t toSbus(float x, uint16_t span) {
return (uint16_t)(SBUS_MID + lroundf(x * span));
}
// стик [-1..1] -> SBUS-значение канала: ниже MOVE_START — нейтраль, выше —
// линейно от порога срабатывания приёмника (db) до POWER_FRAC*span на полном стике
static uint16_t driveToSbus(float x, uint16_t span, uint16_t db,
float powerPos, float powerNeg) {
float mag = fabsf(x);
if (mag <= MOVE_START)
return SBUS_MID;
float outMax = (x > 0.0f ? powerPos : powerNeg) * span;
float t = (mag - MOVE_START) / (1.0f - MOVE_START);
long delta = lroundf(db + t * (outMax - db));
return (x > 0.0f) ? (uint16_t)(SBUS_MID + delta)
: (uint16_t)(SBUS_MID - delta);
}
static void sbusPack(uint8_t out[25], const uint16_t ch[16]) {
out[0] = 0x0F;
memset(out + 1, 0, 22);
uint32_t bitpos = 0;
for (int n = 0; n < 16; n++) {
for (int b = 0; b < 11; b++) {
if (ch[n] & (1u << b))
out[1 + (bitpos >> 3)] |= 1u << (bitpos & 7);
bitpos++;
}
}
out[23] = 0x00; // флаги
out[24] = 0x00; // футер
}
static int readAvg(uint32_t pin) {
uint32_t acc = 0;
for (int i = 0; i < 16; i++)
acc += analogRead(pin);
return acc / 16;
}
void setup() {
Serial.begin(115200);
analogReadResolution(12);
pinMode(PIN_X, INPUT_ANALOG);
pinMode(PIN_Y, INPUT_ANALOG);
sbusUartInit();
}
void loop() {
static uint32_t next = 0;
uint32_t now = millis();
if (now < next)
return;
next = now + FRAME_PERIOD_MS;
int adcX = readAvg(PIN_X);
int adcY = readAvg(PIN_Y);
// вперёд = adcX к X_FWD (вниз) -> +1; вправо = adcY к Y_RIGHT -> +1
float fwd = axisNorm(adcX, X_FWD, X_MID, X_BACK);
float right = axisNorm(adcY, Y_RIGHT, Y_MID, Y_LEFT);
uint16_t ch[16];
for (int i = 0; i < 16; i++)
ch[i] = SBUS_MID;
ch[1] = driveToSbus(fwd, CH2_SPAN, CH2_DB, POWER_FWD, POWER_BACK); // канал 2 — газ
ch[3] = driveToSbus(right, CH4_SPAN, CH4_DB, POWER_TURN, POWER_TURN); // канал 4 — поворот
uint8_t frame[25];
sbusPack(frame, ch);
HAL_UART_Transmit(&s_sbusUart, frame, sizeof(frame), 20);
Serial.print("adc=");
Serial.print(adcX);
Serial.print(",");
Serial.print(adcY);
Serial.print(" fwd=");
Serial.print(fwd, 3);
Serial.print(" right=");
Serial.print(right, 3);
Serial.print(" ch2=");
Serial.print(ch[1]);
Serial.print(" ch4=");
Serial.println(ch[3]);
}
@@ -0,0 +1,34 @@
#!/usr/bin/env python3
"""Analyze a captured frame: extract pulse timing structure.
Usage: .venv/bin/python tools/analyze.py captures/<name>.npz
"""
import sys
import numpy as np
path = sys.argv[1]
d = np.load(path)
volts = d["volts"]
srate = float(d["srate"])
dt_us = 1e6 / srate
# threshold midway between the two dominant plateaus
hi_level = np.median(volts) # idle dominates the frame -> median = idle (high)
lo_level = np.percentile(volts, 10)
thr = (hi_level + lo_level) / 2
bits = (volts > thr).astype(np.int8)
print(f"levels: high~{hi_level:.2f} low~{lo_level:.2f} thr={thr:.2f} (raw units)")
# run-length encode
edges = np.flatnonzero(np.diff(bits)) + 1
starts = np.concatenate(([0], edges))
ends = np.concatenate((edges, [len(bits)]))
levels = bits[starts]
dur_us = (ends - starts) * dt_us
print(f"{len(levels)} runs total")
print("\nidx level dur_us (first/last runs are idle padding)")
for i, (lv, du) in enumerate(zip(levels, dur_us)):
tag = "H" if lv else "L"
print(f"{i:4d} {tag} {du:10.2f}")
@@ -0,0 +1,116 @@
#!/usr/bin/env python3
"""Capture one single-shot CH3 frame from Hantek DPO7204C, save raw + PNG.
Flow: query settings -> :SINGle -> poll :TRIGger:STATus? until STOP ->
WAVeform:DATA:ALL? CHANnel3 (drained completely, multi-packet aware).
Scope is left in STOP so the on-screen frame matches the saved data.
Usage: .venv/bin/python tools/capture.py <name> [device]
Saves captures/<name>.bin, captures/<name>.npz, captures/<name>.png
"""
import os
import sys
import time
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np
DEV = sys.argv[2] if len(sys.argv) > 2 else "/dev/usbtmc2"
NAME = sys.argv[1] if len(sys.argv) > 1 else "capture"
OUTDIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "captures")
os.makedirs(OUTDIR, exist_ok=True)
FIRST_HDR = 11 + 117 # '#9'+9-digit len, then 18 bytes counters + 99 bytes info
NEXT_HDR = 11 + 18 # follow-up packets: counters only
def read_exact(fd, n):
buf = b""
while len(buf) < n:
chunk = os.read(fd, min(1 << 20, n - len(buf)))
if not chunk:
raise IOError("short read from scope")
buf += chunk
return buf
def read_packet(fd):
head = read_exact(fd, 11)
assert head[:2] == b"#9", f"bad packet start: {head!r}"
pkt_len = int(head[2:11])
body = read_exact(fd, pkt_len)
return head + body
def query(fd, cmd):
os.write(fd, cmd.encode() + b"\n")
return os.read(fd, 256).decode(errors="replace").strip()
fd = os.open(DEV, os.O_RDWR)
print("IDN:", query(fd, "*IDN?"))
tdiv = float(query(fd, ":TIMebase:SCALe?"))
vdiv = float(query(fd, ":CHANnel3:SCALe?"))
voff = float(query(fd, ":CHANnel3:OFFSet?"))
print(f"tdiv={tdiv} s/div vdiv={vdiv} V/div offset={voff} V")
os.write(fd, b":SINGle\n")
for _ in range(100):
time.sleep(0.1)
st = query(fd, ":TRIGger:STATus?")
if st == "STOP":
break
else:
sys.exit(f"scope did not reach STOP (last status: {st})")
print("status: STOP (frame captured)")
srate = float(query(fd, ":ACQuire:SRATe?"))
print(f"srate={srate:.3e} Sa/s")
os.write(fd, b"WAVeform:DATA:ALL? CHANnel3\n")
pkt = read_packet(fd)
total_len = int(pkt[11:20])
info_hdr = pkt[29:FIRST_HDR]
data = pkt[FIRST_HDR:]
raw_all = pkt
while len(data) < total_len:
os.write(fd, b"WAVeform:DATA:ALL? CHANnel3\n")
p = read_packet(fd)
raw_all += p
data += p[NEXT_HDR:]
print(f"received {len(data)} samples (declared {total_len})")
print("info header hex:", info_hdr.hex(" "))
os.close(fd)
raw = np.frombuffer(data[:total_len], dtype=np.uint8).astype(np.float32)
# unsigned 8-bit, 25.6 levels/div, mid-screen = code 128, offset shifts zero
volts = (raw - 128.0) / 25.6 * vdiv - voff
t = np.arange(len(volts)) / srate * 1e3 # ms
base = os.path.join(OUTDIR, NAME)
with open(base + ".bin", "wb") as f:
f.write(raw_all)
np.savez(base + ".npz", volts=volts, srate=srate, vdiv=vdiv, voff=voff, tdiv=tdiv)
fig, axes = plt.subplots(2, 1, figsize=(16, 8))
axes[0].plot(t, volts, lw=0.5)
axes[0].set_title(f"{NAME} — full frame ({srate:.0e} Sa/s, {vdiv} V/div, off {voff} V)")
# zoom on activity: region where signal deviates from its median
dev_idx = np.where(np.abs(volts - np.median(volts)) > 0.5)[0]
if len(dev_idx):
lo = max(0, dev_idx[0] - int(0.05 * (dev_idx[-1] - dev_idx[0] + 1)) - 100)
hi = min(len(volts), dev_idx[-1] + int(0.05 * (dev_idx[-1] - dev_idx[0] + 1)) + 100)
axes[1].plot(t[lo:hi], volts[lo:hi], lw=0.7)
axes[1].set_title("zoom on activity")
for ax in axes:
ax.set_xlabel("t, ms")
ax.set_ylabel("U, V")
ax.grid(True, alpha=0.3)
fig.tight_layout()
fig.savefig(base + ".png", dpi=110)
print("saved:", base + ".png")
print(f"range: min={volts.min():.3f} V max={volts.max():.3f} V median={np.median(volts):.3f} V")
@@ -0,0 +1,91 @@
#!/usr/bin/env python3
"""Rigorous comparison of two SBUS captures (old remote vs our firmware).
Usage: .venv/bin/python tools/compare.py captures/a.npz captures/b.npz
"""
import sys
import numpy as np
def extract(path):
d = np.load(path)
v = d["volts"]
srate = float(d["srate"])
idle = np.median(v)
p10, p90 = np.percentile(v, [10, 90])
active = p10 if abs(p10 - idle) > abs(p90 - idle) else p90
thr = (idle + active) / 2
phys_hi = v > thr # physical high (pulse)
# plateau levels: median of samples well inside each state
lvl_hi = np.median(v[phys_hi])
lvl_lo = np.median(v[~phys_hi])
# runs
sig = phys_hi.astype(np.int8)
edges = np.flatnonzero(np.diff(sig)) + 1
starts = np.concatenate(([0], edges))
ends = np.concatenate((edges, [len(sig)]))
levels = sig[starts]
dur_us = (ends - starts) * 1e6 / srate
# burst envelope: first to last physical-high sample
hi_idx = np.flatnonzero(phys_hi)
envelope_us = (hi_idx[-1] - hi_idx[0] + 1) * 1e6 / srate
# inner runs (drop leading/trailing idle)
runs = [(int(l), float(du)) for l, du in zip(levels[1:-1], dur_us[1:-1])]
# UART logic: logic1 == idle state; idle here is physical low
stream = []
for l, du in runs:
n = max(1, round(du / 10.0))
stream.extend([1 - l] * n) # physical high -> logic 0
stream.extend([1] * 24)
frames = []
i = 0
while i + 12 <= len(stream):
if stream[i] == 1:
i += 1
continue
byte = sum(b << k for k, b in enumerate(stream[i + 1 : i + 9]))
frames.append(byte)
i += 12
# bit clock estimate: envelope should be 299 bits (last stop bits merge w/ idle)
n_units = round(envelope_us / 10.0)
bit_us = envelope_us / n_units
return {
"lvl_hi": lvl_hi,
"lvl_lo": lvl_lo,
"runs": runs,
"frames": frames,
"envelope_us": envelope_us,
"bit_us": bit_us,
"vmin": float(v.min()),
"vmax": float(v.max()),
}
a_path, b_path = sys.argv[1], sys.argv[2]
A, B = extract(a_path), extract(b_path)
print(f"{'':24s} {'A: ' + a_path:>28s} {'B: ' + b_path:>28s}")
print(f"{'bytes decoded':24s} {len(A['frames']):>28d} {len(B['frames']):>28d}")
ha = " ".join(f"{x:02X}" for x in A["frames"])
hb = " ".join(f"{x:02X}" for x in B["frames"])
print(f"frames identical: {A['frames'] == B['frames']}")
print(" A:", ha)
print(" B:", hb)
print(f"{'run count':24s} {len(A['runs']):>28d} {len(B['runs']):>28d}")
qa = [round(du / 10) for _, du in A["runs"]]
qb = [round(du / 10) for _, du in B["runs"]]
la = [l for l, _ in A["runs"]]
lb = [l for l, _ in B["runs"]]
print(f"quantized run pattern identical: {qa == qb and la == lb}")
print(f"{'envelope, us':24s} {A['envelope_us']:>28.2f} {B['envelope_us']:>28.2f}")
print(f"{'bit time, us':24s} {A['bit_us']:>28.4f} {B['bit_us']:>28.4f}")
print(f"{'-> baud':24s} {1e6/A['bit_us']:>28.1f} {1e6/B['bit_us']:>28.1f}")
print(f"{'high plateau, V':24s} {A['lvl_hi']:>28.3f} {B['lvl_hi']:>28.3f}")
print(f"{'low plateau, V':24s} {A['lvl_lo']:>28.3f} {B['lvl_lo']:>28.3f}")
print(f"{'abs min/max, V':24s} {A['vmin']:>14.2f}/{A['vmax']:>12.2f} {B['vmin']:>14.2f}/{B['vmax']:>12.2f}")
# worst run deviation from ideal 10us grid
da = max(abs(du - 10 * round(du / 10)) for _, du in A["runs"])
db = max(abs(du - 10 * round(du / 10)) for _, du in B["runs"])
print(f"{'worst grid dev, us':24s} {da:>28.2f} {db:>28.2f}")
@@ -0,0 +1,76 @@
#!/usr/bin/env python3
"""Decode a captured frame as SBUS: UART 100 kbit/s 8E2, 25-byte frame,
16 channels x 11 bits.
Usage: .venv/bin/python tools/decode.py captures/<name>.npz
"""
import sys
import numpy as np
BIT_US = 10.0
path = sys.argv[1]
d = np.load(path)
volts = d["volts"]
srate = float(d["srate"])
dt_us = 1e6 / srate
# idle level dominates the record; UART logic 1 == idle regardless of
# physical polarity (this line is standard inverted SBUS: idle low)
idle = np.median(volts)
p10, p90 = np.percentile(volts, [10, 90])
active = p10 if abs(p10 - idle) > abs(p90 - idle) else p90
thr = (idle + active) / 2
if active > idle:
sig = (volts < thr).astype(np.int8) # pulses up -> logic 0
else:
sig = (volts > thr).astype(np.int8)
edges = np.flatnonzero(np.diff(sig)) + 1
starts = np.concatenate(([0], edges))
ends = np.concatenate((edges, [len(sig)]))
levels = sig[starts]
dur_us = (ends - starts) * dt_us
stream = []
for lv, du in zip(levels[1:-1], dur_us[1:-1]):
stream.extend([int(lv)] * max(1, round(du / BIT_US)))
# trailing idle of last stop bits is trimmed by run cut; pad with idle-high
stream.extend([1] * 24)
# deframe 8E2: start=0, 8 data LSB-first, even parity, 2 stop=1
i = 0
frames = []
errors = []
while i + 12 <= len(stream):
if stream[i] == 1:
i += 1
continue
data = stream[i + 1 : i + 9]
par = stream[i + 9]
stops = stream[i + 10 : i + 12]
byte = sum(b << k for k, b in enumerate(data))
if par != (sum(data) & 1):
errors.append((len(frames), "parity"))
if stops != [1, 1]:
errors.append((len(frames), f"stop={stops}"))
frames.append(byte)
i += 12
print(f"decoded {len(frames)} bytes, errors: {errors if errors else 'none'}")
print("hex:", " ".join(f"{b:02X}" for b in frames))
if len(frames) >= 25 and frames[0] == 0x0F:
payload = frames[1:23]
flags = frames[23]
footer = frames[24]
bits = 0
for k, b in enumerate(payload):
bits |= b << (8 * k)
ch = [(bits >> (11 * n)) & 0x7FF for n in range(16)]
print("\nSBUS frame OK" if footer == 0x00 else f"\nfooter unexpected: {footer:02X}")
print("channels:", ch)
print(f"flags: 0x{flags:02X} (bit0=ch17 bit1=ch18 bit2=frame_lost bit3=failsafe)")
else:
print("not a valid SBUS frame (no 0x0F header)")
@@ -0,0 +1,51 @@
#!/usr/bin/env python3
"""Minimal SCPI helper for Hantek DPO7204C over /dev/usbtmc2."""
import os
import sys
import time
DEV = "/dev/usbtmc2"
class Scope:
def __init__(self, dev=DEV):
self.fd = os.open(dev, os.O_RDWR)
def write(self, cmd: str):
os.write(self.fd, cmd.encode() + b"\n")
def read(self, n=1 << 20, timeout=3.0) -> bytes:
# usbtmc read returns one transfer chunk; loop until short read
chunks = []
end = time.time() + timeout
while time.time() < end:
try:
data = os.read(self.fd, n)
except OSError:
break
chunks.append(data)
if not data or len(data) < n:
break
return b"".join(chunks)
def query(self, cmd: str, timeout=3.0) -> str:
self.write(cmd)
return self.read(timeout=timeout).decode(errors="replace").strip()
def query_raw(self, cmd: str, timeout=5.0) -> bytes:
self.write(cmd)
return self.read(timeout=timeout)
def close(self):
os.close(self.fd)
if __name__ == "__main__":
s = Scope()
for cmd in sys.argv[1:]:
if cmd.endswith("?"):
print(f"{cmd:40s} -> {s.query(cmd)}")
else:
s.write(cmd)
print(f"{cmd:40s} [sent]")
s.close()
+267
View File
@@ -0,0 +1,267 @@
# Бинарный протокол LibreVNA: что шлёт и парсит наш драйвер
Разбор USB-протокола LibreVNA и того, какое его подмножество использует
`python_app/hardware_full/librevna_multi_device_driver`. Про переключение
стимула внутри частотной точки — отдельный документ,
[per_point_switching.md](per_point_switching.md).
Прошивка в репозитории лежит под
`device_firmware/multi_libreVNA_firmware/reproduce/LibreVNA/Software/VNA_embedded/Application/`,
дальше он сокращён до `<FW>`. Версия протокола, заявленная прошивкой —
`Protocol::Version = 14` (`<FW>/Communication/Protocol.hpp:13`).
## 1. Транспорт
Поверх USB у LibreVNA свой бинарный протокол, а не tty/serial. Endpoints:
| Endpoint | Направление |
| --- | --- |
| `0x01` | хост -> устройство |
| `0x81` | устройство -> хост |
| `0x82` | отладочные ASCII-логи |
Наш драйвер шлёт в `0x01`, читает из `0x81`, `0x82` не использует. Приёмный
поток и очередь пакетов — в `librevna_multi_device_driver/transport.py`.
Очередь принятых пакетов ограничена и работает по принципу drop-oldest:
блокировать USB-поток чтения нельзя, а устаревшие пакеты всё равно
выбрасываются предсборочным дренажом (`transport.py:109`).
## 2. Структура кадра
Одна и та же почти для всех типов пакетов
(`<FW>/Communication/PacketConstants.h`):
| Поле | Длина | Значение |
| --- | --- | --- |
| Header | 1 | всегда `0x5A` |
| Length | 2 | длина **всего** кадра, little-endian |
| Type | 1 | номер типа пакета |
| Payload | переменная | |
| CRC32 | 4 | по всему кадру, включая header |
Итого накладных расходов 8 байт: `длина кадра = 8 + len(payload)`.
Кодирование и разбор на хосте — в общем модуле одиночного драйвера, а не в
multi-device: `python_app/hardware_full/librevna_driver/protocol/frame.py`,
функции `encode_frame` (строка 25) и `decode_frame` (строка 49). Поток байт
разбирает `FrameScanner`, который умеет ресинхронизироваться после битого кадра,
не роняя устройство.
### CRC: у `VNADatapoint` особый случай
Прошивка **не считает** CRC для `VNADatapoint` и пишет туда ноль, потому что
расчёт занимает около 18 мкс — это основная часть времени кодирования и
передачи точки (`<FW>/Communication/Protocol.cpp:149`). На приёме она,
наоборот, **требует** ровно нуля: непустой CRC у datapoint считается ошибкой
(`Protocol.cpp:69` и `Protocol.cpp:80`).
Наш хост повторяет это поведение точно: `decode_frame` проверяет CRC32 для всех
типов, а для `VNADatapoint` требует ноль (`frame.py:20` — список исключений).
Дополнительно multi-device парсер отбраковывает пакет, у которого тело не
кратно 9 байтам на значение: раз CRC у datapoint нет, это единственная защита
от ресинхронизации на `0x5A`, случайно оказавшийся внутри payload
(`librevna_multi_device_driver/protocol.py:137`).
## 3. Типы пакетов
Полный enum — `<FW>/Communication/Protocol.hpp:573`, там 30+ типов. Наш драйвер
использует шесть (`librevna_multi_device_driver/protocol.py:17`):
| Тип | Номер | Зачем |
| --- | --- | --- |
| `SweepSettings` | 2 | настройка развёртки, она же её запуск |
| `Ack` | 7 | подтверждение команды |
| `Nack` | 10 | отказ |
| `Reference` | 11 | выбор источника опорной частоты |
| `SetIdle` | 20 | остановить развёртку, перевести в idle |
| `VNADatapoint` | 27 | поток измерений |
То есть это узкий VNA-sweep-драйвер, а не полная реализация всех режимов
прибора. Не используются `RequestDeviceInfo`, проверка версии протокола,
`SetTrigger`/`ClearTrigger`, генератор, анализатор спектра, калибровочные
пакеты.
## 4. Пакеты, которые шлём
### `Reference` (11)
Структура — `Protocol.hpp:186`: `uint32 ExtRefOuputFreq` плюс битовое поле
`AutomaticSwitch` и `UseExternalRef`.
Шлём `output_frequency_hz = 0` и флаг внешней опоры: выход `Ref Out` не
включаем, а устройству принудительно указываем использовать внешние 10 МГц.
Строит `build_reference_settings_payload` (`protocol.py:48`), отправляет
`controller.py`.
### `SweepSettings` (2)
Структура — `Protocol.hpp:155`:
```c
uint64 f_start, f_stop;
uint16 points;
uint32 if_bandwidth;
int16 cdbm_excitation_start;
uint8 standby:1, syncMaster:1, suppressPeaks:1, fixedPowerSetting:1,
logSweep:1, syncMode:2, unused1:1;
uint16 stages:3, port1Stage:3, port2Stage:3, port3Stage:3, port4Stage:3, unused2:1;
int16 cdbm_excitation_stop;
uint16 dwell_time; // в микросекундах
```
Что кладём (`build_sweep_settings_payload`, `protocol.py:58`):
- `f_start`/`f_stop`/`points`/`if_bandwidth` — из `SweepConfiguration`;
- мощность старта и стопа одинаковая, `fixedPowerSetting = 1` — аттенюатор и
мощность PLL не меняются по развёртке;
- `suppressPeaks = 1`, `logSweep = 0`, `standby = 0`;
- `syncMode = 3` (триггерная синхронизация), если синхронизация включена;
- `syncMaster = 1` только у мастера;
- `stages` — номер последней стадии, не их количество;
- порт-стадии — см. ниже.
Про `syncMode = 3`: в стоковой прошивке рядом с полем стоит комментарий
«Trigger synchronization (not supported yet by hardware)». В нашем форке этот
режим и используется — устройство переводит обе триггерные линии FPGA в Hi-Z.
**Порт-стадии — не то, что было в первой версии драйвера.** Раньше мастер
получал `port1Stage = 0`, а слейв `1`. Сейчас:
- мастеру отправляется **первая стадия блока** порта (`index * substage_count`);
без под-стадий это просто индекс порта, то есть стоковая раскладка;
- приёмным устройствам обе порт-стадии выставляются в
`DISABLED_PORT_STAGE = 7` (`protocol.py:36`) — «порт выключен»;
- ширина блока под-стадий передаётся как `log2` в неиспользуемое поле
`port3Stage`.
Почему именно так и почему семёрка безопасна — в
[per_point_switching.md](per_point_switching.md).
### `SetIdle` (20)
Без payload. Выключает активный режим и останавливает развёртку. Используется
как служебная команда: остановить непрерывную развёртку, убраться при ошибке,
`close()`.
### `Ack` (7) / `Nack` (10)
Ответы устройства на команды хоста. `wait_for_acknowledgement`
(`transport.py:96`) читает входящие пакеты, на `Ack` считает команду
применённой, на `Nack` бросает исключение, прочие асинхронные пакеты
пропускает.
## 5. `VNADatapoint` (27) — поток измерений
Шаблон `VNADatapoint<s>` — `Protocol.hpp:25`; у прошивки `s = 32`, то есть до 32
значений в точке (три на стадию при восьми стадиях).
Payload:
| Поле | Тип | Длина |
| --- | --- | --- |
| `frequency` | uint64 | 8 |
| `cdBm` | int16 | 2 |
| `pointNum` | uint16 | 2 |
| `real_values` | n × float32 | 4n |
| `imag_values` | n × float32 | 4n |
| `descr_values` | n × uint8 | n |
Фиксированная часть — 12 байт, дальше по 9 байт на значение, причём **не
чередуясь**: сначала все реальные части, потом все мнимые, потом все
дескрипторы. Отсюда `n = (len(payload) - 12) / 9`.
Разбирает `parse_vna_datapoint_payload` (`protocol.py:137`).
### Байт дескриптора
Смещения битов — `<FW>/Communication/PacketConstants.h:42`:
| Биты | Значение |
| --- | --- |
| 0 | порт 1 |
| 1 | порт 2 |
| 2 | порт 3 |
| 3 | порт 4 |
| 4 | опорный приёмник (Reference) |
| 5..7 | номер стадии |
То же отражено в `enum class Source` (`Protocol.hpp:17`): `Port1 = 0x01`,
`Port2 = 0x02`, `Port3 = 0x04`, `Port4 = 0x08`, `Reference = 0x10`.
Прошивка собирает байт как `stage << 5 | sourceMask`.
На каждую стадию приходит ровно три значения (`<FW>/VNA.cpp:407`): порт 1, порт
2 и опорный приёмник. **Ловушка:** у опорного значения маска не `0x10`, а
`Port1 | Port2 | Reference = 0x13` — то есть биты портов у него тоже стоят.
Поэтому отбирать сигнальное значение только по биту порта нельзя, надо ещё
требовать сброшенный бит 4; именно так и сделано в `find_receiver_value`.
Ищет значение по этому байту `find_receiver_value` (`protocol.py:174`) —
фильтрует по стадии, по признаку опорного приёмника и, если задан, по порту.
Например: «стадия 0 + ref» — опорный приёмник мастера; «стадия 0 + порт 1, не
ref» — сигнал на первом приёмнике.
## 6. Как из этого получаются S-параметры
Устройство S-параметры **не считает** — оно отдаёт только сырые комплексные
отсчёты приёмников. Считает хост, в
`librevna_multi_device_driver/cycle_collection.py`.
Нормировка (`calculate_last_cycle_s_parameters`, строка 783): каждый канал
делится на опорный приёмник **мастера**, а не на локальный опорный приёмник
слейва — потому что излучает именно мастер. Опорные измерения хранятся по
номеру выходного канала (`master_reference_measurements_by_output`), так как с
переключением стимула выходов больше, чем портов мастера.
Имена S-параметров: отражение мастера — `master_reflection_s_parameter_name`
(строка 760), прямые каналы — `build_forward_s_parameter_names` (строка 765).
Нумерация приёмных портов слейвов начинается **после** всех выходов, чтобы
`S33`/`S44` отражения не столкнулись с прямыми каналами.
## 7. Почему поле мощности читается, но не используется
В парсере стоит:
```python
frequency_hz, _power_level_centidecibels_milliwatt, point_index = struct.unpack_from(
"<QhH", payload, 0
)
```
Поле мощности в payload реально существует и стоит между частотой и номером
точки, поэтому прочитать его необходимо, чтобы правильно достать `point_index`.
Подчёркивание в имени — обычный питоновский признак «прочитали намеренно, но не
используем».
По смыслу оно не нужно: для сбора циклов достаточно частоты, индекса точки и
массива отсчётов, а S-параметры считаются как отношение сигнала к опоре.
К тому же развёртка идёт с фиксированной мощностью (`cdbm_excitation_start ==
cdbm_excitation_stop`, `fixedPowerSetting = 1`), так что поле лишь дублирует
уже известное из настройки.
Понадобилось бы оно при переменной по частоте мощности, при логировании
фактической мощности каждой точки или при проверке, что устройство
действительно выдаёт ожидаемый профиль.
## 8. Чего в драйвере сознательно нет
- запроса `DeviceInfo` и проверки версии протокола устройства;
- отладочного endpoint `0x82`;
- пакетов калибровки, генератора, анализатора спектра;
- `SetTrigger`/`ClearTrigger` — синхронизация настраивается полем `syncMode` в
`SweepSettings`, а сама петля триггера аппаратная.
CRC входящих пакетов, в отличие от первой версии драйвера, **проверяется** —
см. раздел 2.
## 9. Карта модулей хоста
| Файл | Роль |
| --- | --- |
| `librevna_driver/protocol/frame.py` | кадр: кодирование, разбор, CRC, ресинхронизация |
| `librevna_multi_device_driver/protocol.py` | номера пакетов, сборка payload, парсер datapoint, поиск по дескриптору |
| `librevna_multi_device_driver/transport.py` | USB bulk, приёмный поток, очередь, ожидание `Ack` |
| `librevna_multi_device_driver/controller.py` | высокоуровневые команды: настроить развёртку, собрать циклы, остановить |
| `librevna_multi_device_driver/cycle_collection.py` | сбор точек в полные циклы, нормировка в S-параметры, имена трасс |
| `librevna_multi_device_driver/models.py` | `SweepConfiguration`, выходные каналы, ограничения стадий |
@@ -0,0 +1,15 @@
*.s#*
*.b#*
*.log
*.net
*.op.raw
*.raw
*.vnafw
*.aux
*.log
*.synctex.gz
*.xcf
*.out
*.toc
*.pyc
Hardware/Renderings
@@ -0,0 +1,118 @@
#!/usr/bin/env python3
import argparse
import binascii
from pathlib import Path
DEFAULT_FPGA_BITSTREAM = "FPGA/VNA/top.bin"
DEFAULT_OUTPUT = "combined.vnafw"
DEFAULT_MCU_CANDIDATES = [
"Software/VNA_embedded/Debug/VNA_embedded.bin",
"Software/VNA_embedded/Release/VNA_embedded.bin",
"Software/VNA_embedded/build/VNA_embedded.bin",
]
HEADER_SIZE = 24
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
description="Assemble a combined LibreVNA firmware image.",
)
parser.add_argument(
"--bitstream",
default=DEFAULT_FPGA_BITSTREAM,
help=f"FPGA bitstream to package (default: {DEFAULT_FPGA_BITSTREAM})",
)
parser.add_argument(
"--output",
default=DEFAULT_OUTPUT,
help=f"Output firmware image path (default: {DEFAULT_OUTPUT})",
)
parser.add_argument(
"--mcu",
help="Explicit MCU firmware .bin path. If omitted, the newest known build is used.",
)
return parser.parse_args()
def select_mcu_firmware(explicit_path: str | None) -> Path:
if explicit_path is not None:
path = Path(explicit_path)
if not path.is_file():
raise FileNotFoundError(f"MCU firmware not found: {path}")
return path
latest_modification = 0.0
newest_mcu: Path | None = None
for candidate in DEFAULT_MCU_CANDIDATES:
path = Path(candidate)
if not path.is_file():
continue
modified_time = path.stat().st_mtime
if modified_time >= latest_modification:
latest_modification = modified_time
newest_mcu = path
if newest_mcu is None:
raise FileNotFoundError("Couldn't find MCU firmware file")
return newest_mcu
def crc32_from_file(filename: Path, initial_crc: int) -> int:
buffer = filename.read_bytes()
return binascii.crc32(buffer, initial_crc) & 0xFFFFFFFF
def main() -> int:
args = parse_args()
bitstream_path = Path(args.bitstream)
if not bitstream_path.is_file():
raise FileNotFoundError(f"FPGA bitstream not found: {bitstream_path}")
mcu_firmware_path = select_mcu_firmware(args.mcu)
output_path = Path(args.output)
print(f"Using {mcu_firmware_path} as MCU firmware")
size_fpga = bitstream_path.stat().st_size
size_mcu = mcu_firmware_path.stat().st_size
print(f"Got FPGA bitstream of size {size_fpga}")
print(f"Got MCU firmware of size {size_mcu}")
crc = crc32_from_file(bitstream_path, 0xFFFFFFFF)
crc = crc32_from_file(mcu_firmware_path, crc)
print(f"Calculating CRC...:{hex(crc)}")
output_path.parent.mkdir(parents=True, exist_ok=True)
with output_path.open("wb") as firmware_image:
firmware_image.write(b"VNA!")
firmware_image.write((HEADER_SIZE).to_bytes(4, byteorder="little"))
firmware_image.write(size_fpga.to_bytes(4, byteorder="little"))
firmware_image.write((HEADER_SIZE + size_fpga).to_bytes(4, byteorder="little"))
firmware_image.write(size_mcu.to_bytes(4, byteorder="little"))
firmware_image.write(crc.to_bytes(4, byteorder="little"))
if firmware_image.tell() != HEADER_SIZE:
raise RuntimeError(
"Incorrect header size "
f"(defined as {HEADER_SIZE} but actual header is {firmware_image.tell()})"
)
firmware_image.write(bitstream_path.read_bytes())
firmware_image.write(mcu_firmware_path.read_bytes())
if firmware_image.tell() % 256 != 0:
padding = 256 - firmware_image.tell() % 256
firmware_image.write(bytearray(padding))
final_size = firmware_image.tell()
print(f"Created combined firmware file at {output_path} with size {final_size}")
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -0,0 +1,12 @@
*
!.gitignore
!*/
!*.vhd
!*.ucf
!*.ipf
!*.gise
!*.xise
!*.py
!*.bin
!VNA/*.dat
@@ -0,0 +1,45 @@
#!/usr/bin/env python3
import math
# Adapt these constants to the step attenuator
BITS_OF_ATTENUATION = 7
LSB_ATTENUATOR_DB = 0.25
NUMBER_LINEAR_ATTENUATION_STEPS = 128
file = open("AMdepth.dat", "w")
def bindigits(n, bits):
s = bin(n & int("1"*bits, 2))[2:]
return ("{0:0>%s}" % (bits)).format(s)
for i in range(NUMBER_LINEAR_ATTENUATION_STEPS):
# calculate percentage of attenuation
percent = float(i) / (NUMBER_LINEAR_ATTENUATION_STEPS - 1)
# calculate attenuation in dB
if percent < 1:
required_dB = -20*math.log10(1 - percent)
else:
required_dB = 999
# round to attenuator steps
attenuator_dB = round(required_dB / LSB_ATTENUATOR_DB) * LSB_ATTENUATOR_DB
# convert to digital attenuator value
attenuator_step = int(attenuator_dB / LSB_ATTENUATOR_DB)
# constrain
if attenuator_step < 0:
attenuator_step = 0
elif attenuator_step >= pow(2, BITS_OF_ATTENUATION):
attenuator_step = pow(2, BITS_OF_ATTENUATION) - 1
output = bindigits(attenuator_step, BITS_OF_ATTENUATION)
file.write(output+"\n")
# Calculate actual attenuation
actual_dB = attenuator_step * LSB_ATTENUATOR_DB
actual_percent = 1 - pow(10, -actual_dB/20)
percent_desired = round(percent*100, 2)
percent_actual = round(actual_percent*100, 2)
print(f'Target modulation: {percent_desired:.2f}, target dB: {required_dB:.2f}, attenuator setting: {attenuator_step}, achieved dB: {actual_dB}, achieved modulation: {percent_actual:.2f}')
file.close()
@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<generated_project xmlns="http://www.xilinx.com/XMLSchema" xmlns:xil_pn="http://www.xilinx.com/XMLSchema">
<!-- -->
<!-- For tool use only. Do not edit. -->
<!-- -->
<!-- ProjectNavigator created generated project file. -->
<!-- For use in tracking generated file and other information -->
<!-- allowing preservation of process status. -->
<!-- -->
<!-- Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved. -->
<version xmlns="http://www.xilinx.com/XMLSchema">11.1</version>
<sourceproject xmlns="http://www.xilinx.com/XMLSchema" xil_pn:fileType="FILE_XISE" xil_pn:name="AMMult.xise"/>
<files xmlns="http://www.xilinx.com/XMLSchema">
<file xil_pn:fileType="FILE_ASY" xil_pn:name="AMMult.asy" xil_pn:origination="imported"/>
<file xil_pn:fileType="FILE_SYMBOL" xil_pn:name="AMMult.sym" xil_pn:origination="imported"/>
<file xil_pn:fileType="FILE_VHO" xil_pn:name="AMMult.vho" xil_pn:origination="imported"/>
</files>
<transforms xmlns="http://www.xilinx.com/XMLSchema">
<transform xil_pn:end_ts="1654646662" xil_pn:name="TRAN_copyInitialToXSTAbstractSynthesis" xil_pn:start_ts="1654646662">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1654895235" xil_pn:name="TRAN_schematicsToHdl" xil_pn:prop_ck="-4873039598653988690" xil_pn:start_ts="1654895235">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1654895235" xil_pn:name="TRAN_regenerateCores" xil_pn:prop_ck="1388655879939993469" xil_pn:start_ts="1654895235">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1654895235" xil_pn:name="TRAN_SubProjectAbstractToPreProxy" xil_pn:start_ts="1654895235">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1654895235" xil_pn:name="TRAN_xawsTohdl" xil_pn:prop_ck="-8697384035118631440" xil_pn:start_ts="1654895235">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
</transforms>
</generated_project>
@@ -0,0 +1,102 @@
--------------------------------------------------------------------------------
-- This file is owned and controlled by Xilinx and must be used solely --
-- for design, simulation, implementation and creation of design files --
-- limited to Xilinx devices or technologies. Use with non-Xilinx --
-- devices or technologies is expressly prohibited and immediately --
-- terminates your license. --
-- --
-- XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" SOLELY --
-- FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR XILINX DEVICES. BY --
-- PROVIDING THIS DESIGN, CODE, OR INFORMATION AS ONE POSSIBLE --
-- IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD, XILINX IS --
-- MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE FROM ANY --
-- CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING ANY --
-- RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY --
-- DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE --
-- IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR --
-- REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF --
-- INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A --
-- PARTICULAR PURPOSE. --
-- --
-- Xilinx products are not intended for use in life support appliances, --
-- devices, or systems. Use in such applications are expressly --
-- prohibited. --
-- --
-- (c) Copyright 1995-2022 Xilinx, Inc. --
-- All rights reserved. --
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- You must compile the wrapper file AMMult.vhd when simulating
-- the core, AMMult. When compiling the wrapper file, be sure to
-- reference the XilinxCoreLib VHDL simulation library. For detailed
-- instructions, please refer to the "CORE Generator Help".
-- The synthesis directives "translate_off/translate_on" specified
-- below are supported by Xilinx, Mentor Graphics and Synplicity
-- synthesis tools. Ensure they are correct for your synthesis tool(s).
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- synthesis translate_off
LIBRARY XilinxCoreLib;
-- synthesis translate_on
ENTITY AMMult IS
PORT (
clk : IN STD_LOGIC;
a : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
b : IN STD_LOGIC_VECTOR(6 DOWNTO 0);
ce : IN STD_LOGIC;
p : OUT STD_LOGIC_VECTOR(14 DOWNTO 0)
);
END AMMult;
ARCHITECTURE AMMult_a OF AMMult IS
-- synthesis translate_off
COMPONENT wrapped_AMMult
PORT (
clk : IN STD_LOGIC;
a : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
b : IN STD_LOGIC_VECTOR(6 DOWNTO 0);
ce : IN STD_LOGIC;
p : OUT STD_LOGIC_VECTOR(14 DOWNTO 0)
);
END COMPONENT;
-- Configuration specification
FOR ALL : wrapped_AMMult USE ENTITY XilinxCoreLib.mult_gen_v11_2(behavioral)
GENERIC MAP (
c_a_type => 1,
c_a_width => 8,
c_b_type => 1,
c_b_value => "10000001",
c_b_width => 7,
c_ccm_imp => 0,
c_ce_overrides_sclr => 0,
c_has_ce => 1,
c_has_sclr => 0,
c_has_zero_detect => 0,
c_latency => 1,
c_model_type => 0,
c_mult_type => 1,
c_optimize_goal => 1,
c_out_high => 14,
c_out_low => 0,
c_round_output => 0,
c_round_pt => 0,
c_verbosity => 0,
c_xdevicefamily => "spartan6"
);
-- synthesis translate_on
BEGIN
-- synthesis translate_off
U0 : wrapped_AMMult
PORT MAP (
clk => clk,
a => a,
b => b,
ce => ce,
p => p
);
-- synthesis translate_on
END AMMult_a;
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<generated_project xmlns="http://www.xilinx.com/XMLSchema" xmlns:xil_pn="http://www.xilinx.com/XMLSchema">
<!-- -->
<!-- For tool use only. Do not edit. -->
<!-- -->
<!-- ProjectNavigator created generated project file. -->
<!-- For use in tracking generated file and other information -->
<!-- allowing preservation of process status. -->
<!-- -->
<!-- Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved. -->
<version xmlns="http://www.xilinx.com/XMLSchema">11.1</version>
<sourceproject xmlns="http://www.xilinx.com/XMLSchema" xil_pn:fileType="FILE_XISE" xil_pn:name="DFT_CLK.xise"/>
<files xmlns="http://www.xilinx.com/XMLSchema">
<file xil_pn:fileType="FILE_ASY" xil_pn:name="DFT_CLK.asy" xil_pn:origination="imported"/>
<file xil_pn:fileType="FILE_VHO" xil_pn:name="DFT_CLK.vho" xil_pn:origination="imported"/>
</files>
<transforms xmlns="http://www.xilinx.com/XMLSchema"/>
</generated_project>
@@ -0,0 +1,59 @@
# file: DFT_CLK.ucf
#
# (c) Copyright 2008 - 2011 Xilinx, Inc. All rights reserved.
#
# This file contains confidential and proprietary information
# of Xilinx, Inc. and is protected under U.S. and
# international copyright and other intellectual property
# laws.
#
# DISCLAIMER
# This disclaimer is not a license and does not grant any
# rights to the materials distributed herewith. Except as
# otherwise provided in a valid license issued to you by
# Xilinx, and to the maximum extent permitted by applicable
# law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
# WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
# AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
# BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
# INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
# (2) Xilinx shall not be liable (whether in contract or tort,
# including negligence, or under any other theory of
# liability) for any loss or damage of any kind or nature
# related to, arising under or in connection with these
# materials, including for any direct, or any indirect,
# special, incidental, or consequential loss or damage
# (including loss of data, profits, goodwill, or any type of
# loss or damage suffered as a result of any action brought
# by a third party) even if such damage or loss was
# reasonably foreseeable or Xilinx had been advised of the
# possibility of the same.
#
# CRITICAL APPLICATIONS
# Xilinx products are not designed or intended to be fail-
# safe, or for use in any application requiring fail-safe
# performance, such as life-support or safety devices or
# systems, Class III medical devices, nuclear facilities,
# applications related to the deployment of airbags, or any
# other applications that could lead to death, personal
# injury, or severe property or environmental damage
# (individually and collectively, "Critical
# Applications"). Customer assumes the sole risk and
# liability of any use of Xilinx products in Critical
# Applications, subject only to applicable laws and
# regulations governing limitations on product liability.
#
# THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
# PART OF THIS FILE AT ALL TIMES.
#
# Input clock periods. These duplicate the values entered for the
# input clocks. You can use these to time your system
#----------------------------------------------------------------
NET "CLK_IN1" TNM_NET = "CLK_IN1";
TIMESPEC "TS_CLK_IN1" = PERIOD "CLK_IN1" 62.5 ns HIGH 50% INPUT_JITTER 625.0ps;
# FALSE PATH constraints
PIN "RESET" TIG;
@@ -0,0 +1,169 @@
-- file: DFT_CLK.vhd
--
-- (c) Copyright 2008 - 2011 Xilinx, Inc. All rights reserved.
--
-- This file contains confidential and proprietary information
-- of Xilinx, Inc. and is protected under U.S. and
-- international copyright and other intellectual property
-- laws.
--
-- DISCLAIMER
-- This disclaimer is not a license and does not grant any
-- rights to the materials distributed herewith. Except as
-- otherwise provided in a valid license issued to you by
-- Xilinx, and to the maximum extent permitted by applicable
-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
-- (2) Xilinx shall not be liable (whether in contract or tort,
-- including negligence, or under any other theory of
-- liability) for any loss or damage of any kind or nature
-- related to, arising under or in connection with these
-- materials, including for any direct, or any indirect,
-- special, incidental, or consequential loss or damage
-- (including loss of data, profits, goodwill, or any type of
-- loss or damage suffered as a result of any action brought
-- by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the
-- possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-
-- safe, or for use in any application requiring fail-safe
-- performance, such as life-support or safety devices or
-- systems, Class III medical devices, nuclear facilities,
-- applications related to the deployment of airbags, or any
-- other applications that could lead to death, personal
-- injury, or severe property or environmental damage
-- (individually and collectively, "Critical
-- Applications"). Customer assumes the sole risk and
-- liability of any use of Xilinx products in Critical
-- Applications, subject only to applicable laws and
-- regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
-- PART OF THIS FILE AT ALL TIMES.
--
------------------------------------------------------------------------------
-- User entered comments
------------------------------------------------------------------------------
-- None
--
------------------------------------------------------------------------------
-- "Output Output Phase Duty Pk-to-Pk Phase"
-- "Clock Freq (MHz) (degrees) Cycle (%) Jitter (ps) Error (ps)"
------------------------------------------------------------------------------
-- CLK_OUT1___160.000______0.000______50.0______336.927____150.000
--
------------------------------------------------------------------------------
-- "Input Clock Freq (MHz) Input Jitter (UI)"
------------------------------------------------------------------------------
-- __primary______________16____________0.010
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
library unisim;
use unisim.vcomponents.all;
entity DFT_CLK is
port
(-- Clock in ports
CLK_IN1 : in std_logic;
-- Clock out ports
CLK_OUT1 : out std_logic;
-- Status and control signals
RESET : in std_logic;
LOCKED : out std_logic
);
end DFT_CLK;
architecture xilinx of DFT_CLK is
attribute CORE_GENERATION_INFO : string;
attribute CORE_GENERATION_INFO of xilinx : architecture is "DFT_CLK,clk_wiz_v3_6,{component_name=DFT_CLK,use_phase_alignment=true,use_min_o_jitter=false,use_max_i_jitter=false,use_dyn_phase_shift=false,use_inclk_switchover=false,use_dyn_reconfig=false,feedback_source=FDBK_AUTO,primtype_sel=DCM_SP,num_out_clk=1,clkin1_period=62.5,clkin2_period=62.5,use_power_down=false,use_reset=true,use_locked=true,use_inclk_stopped=false,use_status=false,use_freeze=false,use_clk_valid=false,feedback_type=SINGLE,clock_mgr_type=AUTO,manual_override=false}";
-- Input clock buffering / unused connectors
signal clkin1 : std_logic;
-- Output clock buffering
signal clkfb : std_logic;
signal clk0 : std_logic;
signal clkfx : std_logic;
signal clkfbout : std_logic;
signal locked_internal : std_logic;
signal status_internal : std_logic_vector(7 downto 0);
begin
-- Input buffering
--------------------------------------
clkin1 <= CLK_IN1;
-- Clocking primitive
--------------------------------------
-- Instantiation of the DCM primitive
-- * Unused inputs are tied off
-- * Unused outputs are labeled unused
dcm_sp_inst: DCM_SP
generic map
(CLKDV_DIVIDE => 2.000,
CLKFX_DIVIDE => 1,
CLKFX_MULTIPLY => 10,
CLKIN_DIVIDE_BY_2 => FALSE,
CLKIN_PERIOD => 62.5,
CLKOUT_PHASE_SHIFT => "NONE",
CLK_FEEDBACK => "1X",
DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS",
PHASE_SHIFT => 0,
STARTUP_WAIT => FALSE)
port map
-- Input clock
(CLKIN => clkin1,
CLKFB => clkfb,
-- Output clocks
CLK0 => clk0,
CLK90 => open,
CLK180 => open,
CLK270 => open,
CLK2X => open,
CLK2X180 => open,
CLKFX => clkfx,
CLKFX180 => open,
CLKDV => open,
-- Ports for dynamic phase shift
PSCLK => '0',
PSEN => '0',
PSINCDEC => '0',
PSDONE => open,
-- Other control and status signals
LOCKED => locked_internal,
STATUS => status_internal,
RST => RESET,
-- Unused pin, tie low
DSSEN => '0');
LOCKED <= locked_internal;
-- Output buffering
-------------------------------------
clkf_buf : BUFG
port map
(O => clkfb,
I => clk0);
clkout1_buf : BUFG
port map
(O => CLK_OUT1,
I => clkfx);
end xilinx;
@@ -0,0 +1,60 @@
# file: DFT_CLK_exdes.ucf
#
# (c) Copyright 2008 - 2011 Xilinx, Inc. All rights reserved.
#
# This file contains confidential and proprietary information
# of Xilinx, Inc. and is protected under U.S. and
# international copyright and other intellectual property
# laws.
#
# DISCLAIMER
# This disclaimer is not a license and does not grant any
# rights to the materials distributed herewith. Except as
# otherwise provided in a valid license issued to you by
# Xilinx, and to the maximum extent permitted by applicable
# law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
# WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
# AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
# BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
# INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
# (2) Xilinx shall not be liable (whether in contract or tort,
# including negligence, or under any other theory of
# liability) for any loss or damage of any kind or nature
# related to, arising under or in connection with these
# materials, including for any direct, or any indirect,
# special, incidental, or consequential loss or damage
# (including loss of data, profits, goodwill, or any type of
# loss or damage suffered as a result of any action brought
# by a third party) even if such damage or loss was
# reasonably foreseeable or Xilinx had been advised of the
# possibility of the same.
#
# CRITICAL APPLICATIONS
# Xilinx products are not designed or intended to be fail-
# safe, or for use in any application requiring fail-safe
# performance, such as life-support or safety devices or
# systems, Class III medical devices, nuclear facilities,
# applications related to the deployment of airbags, or any
# other applications that could lead to death, personal
# injury, or severe property or environmental damage
# (individually and collectively, "Critical
# Applications"). Customer assumes the sole risk and
# liability of any use of Xilinx products in Critical
# Applications, subject only to applicable laws and
# regulations governing limitations on product liability.
#
# THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
# PART OF THIS FILE AT ALL TIMES.
#
# Input clock periods. These duplicate the values entered for the
# input clocks. You can use these to time your system
#----------------------------------------------------------------
NET "CLK_IN1" TNM_NET = "CLK_IN1";
TIMESPEC "TS_CLK_IN1" = PERIOD "CLK_IN1" 62.5 ns HIGH 50% INPUT_JITTER 625.0ps;
# FALSE PATH constraints
PIN "COUNTER_RESET" TIG;
PIN "RESET" TIG;
@@ -0,0 +1,192 @@
-- file: DFT_CLK_exdes.vhd
--
-- (c) Copyright 2008 - 2011 Xilinx, Inc. All rights reserved.
--
-- This file contains confidential and proprietary information
-- of Xilinx, Inc. and is protected under U.S. and
-- international copyright and other intellectual property
-- laws.
--
-- DISCLAIMER
-- This disclaimer is not a license and does not grant any
-- rights to the materials distributed herewith. Except as
-- otherwise provided in a valid license issued to you by
-- Xilinx, and to the maximum extent permitted by applicable
-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
-- (2) Xilinx shall not be liable (whether in contract or tort,
-- including negligence, or under any other theory of
-- liability) for any loss or damage of any kind or nature
-- related to, arising under or in connection with these
-- materials, including for any direct, or any indirect,
-- special, incidental, or consequential loss or damage
-- (including loss of data, profits, goodwill, or any type of
-- loss or damage suffered as a result of any action brought
-- by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the
-- possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-
-- safe, or for use in any application requiring fail-safe
-- performance, such as life-support or safety devices or
-- systems, Class III medical devices, nuclear facilities,
-- applications related to the deployment of airbags, or any
-- other applications that could lead to death, personal
-- injury, or severe property or environmental damage
-- (individually and collectively, "Critical
-- Applications"). Customer assumes the sole risk and
-- liability of any use of Xilinx products in Critical
-- Applications, subject only to applicable laws and
-- regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
-- PART OF THIS FILE AT ALL TIMES.
--
------------------------------------------------------------------------------
-- Clocking wizard example design
------------------------------------------------------------------------------
-- This example design instantiates the created clocking network, where each
-- output clock drives a counter. The high bit of each counter is ported.
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
library unisim;
use unisim.vcomponents.all;
entity DFT_CLK_exdes is
generic (
TCQ : in time := 100 ps);
port
(-- Clock in ports
CLK_IN1 : in std_logic;
-- Reset that only drives logic in example design
COUNTER_RESET : in std_logic;
CLK_OUT : out std_logic_vector(1 downto 1) ;
-- High bits of counters driven by clocks
COUNT : out std_logic;
-- Status and control signals
RESET : in std_logic;
LOCKED : out std_logic
);
end DFT_CLK_exdes;
architecture xilinx of DFT_CLK_exdes is
-- Parameters for the counters
---------------------------------
-- Counter width
constant C_W : integer := 16;
-- When the clock goes out of lock, reset the counters
signal locked_int : std_logic;
signal reset_int : std_logic := '0';
-- Declare the clocks and counter
signal clk : std_logic;
signal clk_int : std_logic;
signal clk_n : std_logic;
signal counter : std_logic_vector(C_W-1 downto 0) := (others => '0');
-- Need to buffer input clocks that aren't already buffered
signal clk_in1_buf : std_logic;
signal rst_sync : std_logic;
signal rst_sync_int : std_logic;
signal rst_sync_int1 : std_logic;
signal rst_sync_int2 : std_logic;
component DFT_CLK is
port
(-- Clock in ports
CLK_IN1 : in std_logic;
-- Clock out ports
CLK_OUT1 : out std_logic;
-- Status and control signals
RESET : in std_logic;
LOCKED : out std_logic
);
end component;
begin
-- Alias output to internally used signal
LOCKED <= locked_int;
-- When the clock goes out of lock, reset the counters
reset_int <= (not locked_int) or RESET or COUNTER_RESET;
process (clk, reset_int) begin
if (reset_int = '1') then
rst_sync <= '1';
rst_sync_int <= '1';
rst_sync_int1 <= '1';
rst_sync_int2 <= '1';
elsif (clk 'event and clk='1') then
rst_sync <= '0';
rst_sync_int <= rst_sync;
rst_sync_int1 <= rst_sync_int;
rst_sync_int2 <= rst_sync_int1;
end if;
end process;
-- Insert BUFGs on all input clocks that don't already have them
----------------------------------------------------------------
clkin1_buf : BUFG
port map
(O => clk_in1_buf,
I => CLK_IN1);
-- Instantiation of the clocking network
----------------------------------------
clknetwork : DFT_CLK
port map
(-- Clock in ports
CLK_IN1 => clk_in1_buf,
-- Clock out ports
CLK_OUT1 => clk_int,
-- Status and control signals
RESET => RESET,
LOCKED => locked_int);
clk_n <= not clk;
clkout_oddr : ODDR2
port map
(Q => CLK_OUT(1),
C0 => clk,
C1 => clk_n,
CE => '1',
D0 => '1',
D1 => '0',
R => '0',
S => '0');
-- Connect the output clocks to the design
-------------------------------------------
clk <= clk_int;
-- Output clock sampling
-------------------------------------
process (clk, rst_sync_int2) begin
if (rst_sync_int2 = '1') then
counter <= (others => '0') after TCQ;
elsif (rising_edge(clk)) then
counter <= counter + 1 after TCQ;
end if;
end process;
-- alias the high bit to the output
COUNT <= counter(C_W-1);
end xilinx;
@@ -0,0 +1,197 @@
-- file: DFT_CLK_tb.vhd
--
-- (c) Copyright 2008 - 2011 Xilinx, Inc. All rights reserved.
--
-- This file contains confidential and proprietary information
-- of Xilinx, Inc. and is protected under U.S. and
-- international copyright and other intellectual property
-- laws.
--
-- DISCLAIMER
-- This disclaimer is not a license and does not grant any
-- rights to the materials distributed herewith. Except as
-- otherwise provided in a valid license issued to you by
-- Xilinx, and to the maximum extent permitted by applicable
-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
-- (2) Xilinx shall not be liable (whether in contract or tort,
-- including negligence, or under any other theory of
-- liability) for any loss or damage of any kind or nature
-- related to, arising under or in connection with these
-- materials, including for any direct, or any indirect,
-- special, incidental, or consequential loss or damage
-- (including loss of data, profits, goodwill, or any type of
-- loss or damage suffered as a result of any action brought
-- by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the
-- possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-
-- safe, or for use in any application requiring fail-safe
-- performance, such as life-support or safety devices or
-- systems, Class III medical devices, nuclear facilities,
-- applications related to the deployment of airbags, or any
-- other applications that could lead to death, personal
-- injury, or severe property or environmental damage
-- (individually and collectively, "Critical
-- Applications"). Customer assumes the sole risk and
-- liability of any use of Xilinx products in Critical
-- Applications, subject only to applicable laws and
-- regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
-- PART OF THIS FILE AT ALL TIMES.
--
------------------------------------------------------------------------------
-- Clocking wizard demonstration testbench
------------------------------------------------------------------------------
-- This demonstration testbench instantiates the example design for the
-- clocking wizard. Input clocks are toggled, which cause the clocking
-- network to lock and the counters to increment.
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
use ieee.std_logic_textio.all;
library std;
use std.textio.all;
library work;
use work.all;
entity DFT_CLK_tb is
end DFT_CLK_tb;
architecture test of DFT_CLK_tb is
-- Clock to Q delay of 100 ps
constant TCQ : time := 100 ps;
-- timescale is 1ps
constant ONE_NS : time := 1 ns;
-- how many cycles to run
constant COUNT_PHASE : integer := 1024 + 1;
-- we'll be using the period in many locations
constant PER1 : time := 62.5 ns;
-- Declare the input clock signals
signal CLK_IN1 : std_logic := '1';
-- The high bit of the sampling counter
signal COUNT : std_logic;
-- Status and control signals
signal RESET : std_logic := '0';
signal LOCKED : std_logic;
signal COUNTER_RESET : std_logic := '0';
-- signal defined to stop mti simulation without severity failure in the report
signal end_of_sim : std_logic := '0';
signal CLK_OUT : std_logic_vector(1 downto 1);
--Freq Check using the M & D values setting and actual Frequency generated
component DFT_CLK_exdes
generic (
TCQ : in time := 100 ps);
port
(-- Clock in ports
CLK_IN1 : in std_logic;
-- Reset that only drives logic in example design
COUNTER_RESET : in std_logic;
CLK_OUT : out std_logic_vector(1 downto 1) ;
-- High bits of counters driven by clocks
COUNT : out std_logic;
-- Status and control signals
RESET : in std_logic;
LOCKED : out std_logic
);
end component;
begin
-- Input clock generation
--------------------------------------
process begin
CLK_IN1 <= not CLK_IN1; wait for (PER1/2);
end process;
-- Test sequence
process
procedure simtimeprint is
variable outline : line;
begin
write(outline, string'("## SYSTEM_CYCLE_COUNTER "));
write(outline, NOW/PER1);
write(outline, string'(" ns"));
writeline(output,outline);
end simtimeprint;
procedure simfreqprint (period : time; clk_num : integer) is
variable outputline : LINE;
variable str1 : string(1 to 16);
variable str2 : integer;
variable str3 : string(1 to 2);
variable str4 : integer;
variable str5 : string(1 to 4);
begin
str1 := "Freq of CLK_OUT(";
str2 := clk_num;
str3 := ") ";
str4 := 1000000 ps/period ;
str5 := " MHz" ;
write(outputline, str1 );
write(outputline, str2);
write(outputline, str3);
write(outputline, str4);
write(outputline, str5);
writeline(output, outputline);
end simfreqprint;
begin
RESET <= '1';
wait for (PER1*6);
RESET <= '0';
wait until LOCKED = '1';
COUNTER_RESET <= '1';
wait for (PER1*20);
COUNTER_RESET <= '0';
wait for (PER1*COUNT_PHASE);
simtimeprint;
end_of_sim <= '1';
wait for 1 ps;
report "Simulation Stopped." severity failure;
wait;
end process;
-- Instantiation of the example design containing the clock
-- network and sampling counters
-----------------------------------------------------------
dut : DFT_CLK_exdes
generic map (
TCQ => TCQ)
port map
(-- Clock in ports
CLK_IN1 => CLK_IN1,
-- Reset for logic in example design
COUNTER_RESET => COUNTER_RESET,
CLK_OUT => CLK_OUT,
-- High bits of the counters
COUNT => COUNT,
-- Status and control signals
RESET => RESET,
LOCKED => LOCKED);
-- Freq Check
end test;
@@ -0,0 +1,220 @@
-- file: DFT_CLK_tb.vhd
--
-- (c) Copyright 2008 - 2011 Xilinx, Inc. All rights reserved.
--
-- This file contains confidential and proprietary information
-- of Xilinx, Inc. and is protected under U.S. and
-- international copyright and other intellectual property
-- laws.
--
-- DISCLAIMER
-- This disclaimer is not a license and does not grant any
-- rights to the materials distributed herewith. Except as
-- otherwise provided in a valid license issued to you by
-- Xilinx, and to the maximum extent permitted by applicable
-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
-- (2) Xilinx shall not be liable (whether in contract or tort,
-- including negligence, or under any other theory of
-- liability) for any loss or damage of any kind or nature
-- related to, arising under or in connection with these
-- materials, including for any direct, or any indirect,
-- special, incidental, or consequential loss or damage
-- (including loss of data, profits, goodwill, or any type of
-- loss or damage suffered as a result of any action brought
-- by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the
-- possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-
-- safe, or for use in any application requiring fail-safe
-- performance, such as life-support or safety devices or
-- systems, Class III medical devices, nuclear facilities,
-- applications related to the deployment of airbags, or any
-- other applications that could lead to death, personal
-- injury, or severe property or environmental damage
-- (individually and collectively, "Critical
-- Applications"). Customer assumes the sole risk and
-- liability of any use of Xilinx products in Critical
-- Applications, subject only to applicable laws and
-- regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
-- PART OF THIS FILE AT ALL TIMES.
--
------------------------------------------------------------------------------
-- Clocking wizard demonstration testbench
------------------------------------------------------------------------------
-- This demonstration testbench instantiates the example design for the
-- clocking wizard. Input clocks are toggled, which cause the clocking
-- network to lock and the counters to increment.
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
use ieee.std_logic_textio.all;
library std;
use std.textio.all;
library work;
use work.all;
entity DFT_CLK_tb is
end DFT_CLK_tb;
architecture test of DFT_CLK_tb is
-- Clock to Q delay of 100 ps
constant TCQ : time := 100 ps;
-- timescale is 1ps
constant ONE_NS : time := 1 ns;
-- how many cycles to run
constant COUNT_PHASE : integer := 1024 + 1;
-- we'll be using the period in many locations
constant PER1 : time := 62.5 ns;
-- Declare the input clock signals
signal CLK_IN1 : std_logic := '1';
-- The high bit of the sampling counter
signal COUNT : std_logic;
-- Status and control signals
signal RESET : std_logic := '0';
signal LOCKED : std_logic;
signal COUNTER_RESET : std_logic := '0';
signal timeout_counter : std_logic_vector (13 downto 0) := (others => '0');
-- signal defined to stop mti simulation without severity failure in the report
signal end_of_sim : std_logic := '0';
signal CLK_OUT : std_logic_vector(1 downto 1);
--Freq Check using the M & D values setting and actual Frequency generated
component DFT_CLK_exdes
port
(-- Clock in ports
CLK_IN1 : in std_logic;
-- Reset that only drives logic in example design
COUNTER_RESET : in std_logic;
CLK_OUT : out std_logic_vector(1 downto 1) ;
-- High bits of counters driven by clocks
COUNT : out std_logic;
-- Status and control signals
RESET : in std_logic;
LOCKED : out std_logic
);
end component;
begin
-- Input clock generation
--------------------------------------
process begin
CLK_IN1 <= not CLK_IN1; wait for (PER1/2);
end process;
-- Test sequence
process
procedure simtimeprint is
variable outline : line;
begin
write(outline, string'("## SYSTEM_CYCLE_COUNTER "));
write(outline, NOW/PER1);
write(outline, string'(" ns"));
writeline(output,outline);
end simtimeprint;
procedure simfreqprint (period : time; clk_num : integer) is
variable outputline : LINE;
variable str1 : string(1 to 16);
variable str2 : integer;
variable str3 : string(1 to 2);
variable str4 : integer;
variable str5 : string(1 to 4);
begin
str1 := "Freq of CLK_OUT(";
str2 := clk_num;
str3 := ") ";
str4 := 1000000 ps/period ;
str5 := " MHz" ;
write(outputline, str1 );
write(outputline, str2);
write(outputline, str3);
write(outputline, str4);
write(outputline, str5);
writeline(output, outputline);
end simfreqprint;
begin
report "Timing checks are not valid" severity note;
RESET <= '1';
wait for (PER1*6);
RESET <= '0';
wait until LOCKED = '1';
wait for (PER1*20);
COUNTER_RESET <= '1';
wait for (PER1*19.5);
COUNTER_RESET <= '0';
wait for (PER1*1);
report "Timing checks are valid" severity note;
wait for (PER1*COUNT_PHASE);
simtimeprint;
end_of_sim <= '1';
wait for 1 ps;
report "Simulation Stopped." severity failure;
wait;
end process;
process (CLK_IN1)
procedure simtimeprint is
variable outline : line;
begin
write(outline, string'("## SYSTEM_CYCLE_COUNTER "));
write(outline, NOW/PER1);
write(outline, string'(" ns"));
writeline(output,outline);
end simtimeprint;
begin
if (CLK_IN1'event and CLK_IN1='1') then
timeout_counter <= timeout_counter + '1';
if (timeout_counter = "10000000000000") then
if (LOCKED /= '1') then
simtimeprint;
report "NO LOCK signal" severity failure;
end if;
end if;
end if;
end process;
-- Instantiation of the example design containing the clock
-- network and sampling counters
-----------------------------------------------------------
dut : DFT_CLK_exdes
port map
(-- Clock in ports
CLK_IN1 => CLK_IN1,
-- Reset for logic in example design
COUNTER_RESET => COUNTER_RESET,
CLK_OUT => CLK_OUT,
-- High bits of the counters
COUNT => COUNT,
-- Status and control signals
RESET => RESET,
LOCKED => LOCKED);
-- Freq Check
end test;
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<generated_project xmlns="http://www.xilinx.com/XMLSchema" xmlns:xil_pn="http://www.xilinx.com/XMLSchema">
<!-- -->
<!-- For tool use only. Do not edit. -->
<!-- -->
<!-- ProjectNavigator created generated project file. -->
<!-- For use in tracking generated file and other information -->
<!-- allowing preservation of process status. -->
<!-- -->
<!-- Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved. -->
<version xmlns="http://www.xilinx.com/XMLSchema">11.1</version>
<sourceproject xmlns="http://www.xilinx.com/XMLSchema" xil_pn:fileType="FILE_XISE" xil_pn:name="DSP48.xise"/>
<files xmlns="http://www.xilinx.com/XMLSchema">
<file xil_pn:fileType="FILE_ASY" xil_pn:name="DSP48.asy" xil_pn:origination="imported"/>
<file xil_pn:fileType="FILE_SYMBOL" xil_pn:name="DSP48.sym" xil_pn:origination="imported"/>
<file xil_pn:fileType="FILE_VHO" xil_pn:name="DSP48.vho" xil_pn:origination="imported"/>
</files>
<transforms xmlns="http://www.xilinx.com/XMLSchema"/>
</generated_project>
@@ -0,0 +1,139 @@
--------------------------------------------------------------------------------
-- This file is owned and controlled by Xilinx and must be used solely --
-- for design, simulation, implementation and creation of design files --
-- limited to Xilinx devices or technologies. Use with non-Xilinx --
-- devices or technologies is expressly prohibited and immediately --
-- terminates your license. --
-- --
-- XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" SOLELY --
-- FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR XILINX DEVICES. BY --
-- PROVIDING THIS DESIGN, CODE, OR INFORMATION AS ONE POSSIBLE --
-- IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD, XILINX IS --
-- MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE FROM ANY --
-- CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING ANY --
-- RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY --
-- DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE --
-- IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR --
-- REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF --
-- INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A --
-- PARTICULAR PURPOSE. --
-- --
-- Xilinx products are not intended for use in life support appliances, --
-- devices, or systems. Use in such applications are expressly --
-- prohibited. --
-- --
-- (c) Copyright 1995-2020 Xilinx, Inc. --
-- All rights reserved. --
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- You must compile the wrapper file DSP48.vhd when simulating
-- the core, DSP48. When compiling the wrapper file, be sure to
-- reference the XilinxCoreLib VHDL simulation library. For detailed
-- instructions, please refer to the "CORE Generator Help".
-- The synthesis directives "translate_off/translate_on" specified
-- below are supported by Xilinx, Mentor Graphics and Synplicity
-- synthesis tools. Ensure they are correct for your synthesis tool(s).
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- synthesis translate_off
LIBRARY XilinxCoreLib;
-- synthesis translate_on
ENTITY DSP48 IS
PORT (
clk : IN STD_LOGIC;
ce : IN STD_LOGIC;
sel : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
a : IN STD_LOGIC_VECTOR(17 DOWNTO 0);
b : IN STD_LOGIC_VECTOR(17 DOWNTO 0);
c : IN STD_LOGIC_VECTOR(47 DOWNTO 0);
p : OUT STD_LOGIC_VECTOR(47 DOWNTO 0)
);
END DSP48;
ARCHITECTURE DSP48_a OF DSP48 IS
-- synthesis translate_off
COMPONENT wrapped_DSP48
PORT (
clk : IN STD_LOGIC;
ce : IN STD_LOGIC;
sel : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
a : IN STD_LOGIC_VECTOR(17 DOWNTO 0);
b : IN STD_LOGIC_VECTOR(17 DOWNTO 0);
c : IN STD_LOGIC_VECTOR(47 DOWNTO 0);
p : OUT STD_LOGIC_VECTOR(47 DOWNTO 0)
);
END COMPONENT;
-- Configuration specification
FOR ALL : wrapped_DSP48 USE ENTITY XilinxCoreLib.xbip_dsp48_macro_v2_1(behavioral)
GENERIC MAP (
c_a_width => 18,
c_b_width => 18,
c_c_width => 48,
c_concat_width => 48,
c_constant_1 => 1,
c_d_width => 18,
c_has_a => 1,
c_has_acin => 0,
c_has_acout => 0,
c_has_b => 1,
c_has_bcin => 0,
c_has_bcout => 0,
c_has_c => 1,
c_has_carrycascin => 0,
c_has_carrycascout => 0,
c_has_carryin => 0,
c_has_carryout => 0,
c_has_ce => 1,
c_has_cea => 0,
c_has_ceb => 0,
c_has_cec => 0,
c_has_ceconcat => 0,
c_has_ced => 0,
c_has_cem => 0,
c_has_cep => 0,
c_has_cesel => 0,
c_has_concat => 0,
c_has_d => 0,
c_has_indep_ce => 0,
c_has_indep_sclr => 0,
c_has_pcin => 0,
c_has_pcout => 0,
c_has_sclr => 0,
c_has_sclra => 0,
c_has_sclrb => 0,
c_has_sclrc => 0,
c_has_sclrconcat => 0,
c_has_sclrd => 0,
c_has_sclrm => 0,
c_has_sclrp => 0,
c_has_sclrsel => 0,
c_latency => -1,
c_model_type => 0,
c_opmodes => "0000000000010000000,0000001100010000000",
c_p_lsb => 0,
c_p_msb => 47,
c_reg_config => "00000000000011100111100111100100",
c_sel_width => 1,
c_test_core => 0,
c_verbosity => 0,
c_xdevicefamily => "spartan6"
);
-- synthesis translate_on
BEGIN
-- synthesis translate_off
U0 : wrapped_DSP48
PORT MAP (
clk => clk,
ce => ce,
sel => sel,
a => a,
b => b,
c => c,
p => p
);
-- synthesis translate_on
END DSP48_a;
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<generated_project xmlns="http://www.xilinx.com/XMLSchema" xmlns:xil_pn="http://www.xilinx.com/XMLSchema">
<!-- -->
<!-- For tool use only. Do not edit. -->
<!-- -->
<!-- ProjectNavigator created generated project file. -->
<!-- For use in tracking generated file and other information -->
<!-- allowing preservation of process status. -->
<!-- -->
<!-- Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved. -->
<version xmlns="http://www.xilinx.com/XMLSchema">11.1</version>
<sourceproject xmlns="http://www.xilinx.com/XMLSchema" xil_pn:fileType="FILE_XISE" xil_pn:name="DSP_SLICE.xise"/>
<files xmlns="http://www.xilinx.com/XMLSchema">
<file xil_pn:fileType="FILE_ASY" xil_pn:name="DSP_SLICE.asy" xil_pn:origination="imported"/>
<file xil_pn:fileType="FILE_SYMBOL" xil_pn:name="DSP_SLICE.sym" xil_pn:origination="imported"/>
<file xil_pn:fileType="FILE_VHO" xil_pn:name="DSP_SLICE.vho" xil_pn:origination="imported"/>
</files>
<transforms xmlns="http://www.xilinx.com/XMLSchema"/>
</generated_project>
@@ -0,0 +1,139 @@
--------------------------------------------------------------------------------
-- This file is owned and controlled by Xilinx and must be used solely --
-- for design, simulation, implementation and creation of design files --
-- limited to Xilinx devices or technologies. Use with non-Xilinx --
-- devices or technologies is expressly prohibited and immediately --
-- terminates your license. --
-- --
-- XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" SOLELY --
-- FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR XILINX DEVICES. BY --
-- PROVIDING THIS DESIGN, CODE, OR INFORMATION AS ONE POSSIBLE --
-- IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD, XILINX IS --
-- MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE FROM ANY --
-- CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING ANY --
-- RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY --
-- DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE --
-- IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR --
-- REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF --
-- INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A --
-- PARTICULAR PURPOSE. --
-- --
-- Xilinx products are not intended for use in life support appliances, --
-- devices, or systems. Use in such applications are expressly --
-- prohibited. --
-- --
-- (c) Copyright 1995-2020 Xilinx, Inc. --
-- All rights reserved. --
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- You must compile the wrapper file DSP_SLICE.vhd when simulating
-- the core, DSP_SLICE. When compiling the wrapper file, be sure to
-- reference the XilinxCoreLib VHDL simulation library. For detailed
-- instructions, please refer to the "CORE Generator Help".
-- The synthesis directives "translate_off/translate_on" specified
-- below are supported by Xilinx, Mentor Graphics and Synplicity
-- synthesis tools. Ensure they are correct for your synthesis tool(s).
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- synthesis translate_off
LIBRARY XilinxCoreLib;
-- synthesis translate_on
ENTITY DSP_SLICE IS
PORT (
clk : IN STD_LOGIC;
ce : IN STD_LOGIC;
sel : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
a : IN STD_LOGIC_VECTOR(17 DOWNTO 0);
b : IN STD_LOGIC_VECTOR(17 DOWNTO 0);
c : IN STD_LOGIC_VECTOR(47 DOWNTO 0);
p : OUT STD_LOGIC_VECTOR(47 DOWNTO 0)
);
END DSP_SLICE;
ARCHITECTURE DSP_SLICE_a OF DSP_SLICE IS
-- synthesis translate_off
COMPONENT wrapped_DSP_SLICE
PORT (
clk : IN STD_LOGIC;
ce : IN STD_LOGIC;
sel : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
a : IN STD_LOGIC_VECTOR(17 DOWNTO 0);
b : IN STD_LOGIC_VECTOR(17 DOWNTO 0);
c : IN STD_LOGIC_VECTOR(47 DOWNTO 0);
p : OUT STD_LOGIC_VECTOR(47 DOWNTO 0)
);
END COMPONENT;
-- Configuration specification
FOR ALL : wrapped_DSP_SLICE USE ENTITY XilinxCoreLib.xbip_dsp48_macro_v2_1(behavioral)
GENERIC MAP (
c_a_width => 18,
c_b_width => 18,
c_c_width => 48,
c_concat_width => 48,
c_constant_1 => 1,
c_d_width => 18,
c_has_a => 1,
c_has_acin => 0,
c_has_acout => 0,
c_has_b => 1,
c_has_bcin => 0,
c_has_bcout => 0,
c_has_c => 1,
c_has_carrycascin => 0,
c_has_carrycascout => 0,
c_has_carryin => 0,
c_has_carryout => 0,
c_has_ce => 1,
c_has_cea => 0,
c_has_ceb => 0,
c_has_cec => 0,
c_has_ceconcat => 0,
c_has_ced => 0,
c_has_cem => 0,
c_has_cep => 0,
c_has_cesel => 0,
c_has_concat => 0,
c_has_d => 0,
c_has_indep_ce => 0,
c_has_indep_sclr => 0,
c_has_pcin => 0,
c_has_pcout => 0,
c_has_sclr => 0,
c_has_sclra => 0,
c_has_sclrb => 0,
c_has_sclrc => 0,
c_has_sclrconcat => 0,
c_has_sclrd => 0,
c_has_sclrm => 0,
c_has_sclrp => 0,
c_has_sclrsel => 0,
c_latency => -1,
c_model_type => 0,
c_opmodes => "0000000000010000000,0000001100010000000",
c_p_lsb => 0,
c_p_msb => 47,
c_reg_config => "00000000000011100111100111100100",
c_sel_width => 1,
c_test_core => 0,
c_verbosity => 0,
c_xdevicefamily => "spartan6"
);
-- synthesis translate_on
BEGIN
-- synthesis translate_off
U0 : wrapped_DSP_SLICE
PORT MAP (
clk => clk,
ce => ce,
sel => sel,
a => a,
b => b,
c => c,
p => p
);
-- synthesis translate_on
END DSP_SLICE_a;
@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<generated_project xmlns="http://www.xilinx.com/XMLSchema" xmlns:xil_pn="http://www.xilinx.com/XMLSchema">
<!-- -->
<!-- For tool use only. Do not edit. -->
<!-- -->
<!-- ProjectNavigator created generated project file. -->
<!-- For use in tracking generated file and other information -->
<!-- allowing preservation of process status. -->
<!-- -->
<!-- Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved. -->
<version xmlns="http://www.xilinx.com/XMLSchema">11.1</version>
<sourceproject xmlns="http://www.xilinx.com/XMLSchema" xil_pn:fileType="FILE_XISE" xil_pn:name="ModulationMemory.xise"/>
<files xmlns="http://www.xilinx.com/XMLSchema">
<file xil_pn:fileType="FILE_ASY" xil_pn:name="ModulationMemory.asy" xil_pn:origination="imported"/>
<file xil_pn:fileType="FILE_SYMBOL" xil_pn:name="ModulationMemory.sym" xil_pn:origination="imported"/>
<file xil_pn:fileType="FILE_VHO" xil_pn:name="ModulationMemory.vho" xil_pn:origination="imported"/>
</files>
<transforms xmlns="http://www.xilinx.com/XMLSchema">
<transform xil_pn:end_ts="1654895235" xil_pn:name="TRAN_copyInitialToXSTAbstractSynthesis" xil_pn:start_ts="1654895235">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1654895235" xil_pn:name="TRAN_schematicsToHdl" xil_pn:prop_ck="1122694780993201560" xil_pn:start_ts="1654895235">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1654895235" xil_pn:name="TRAN_regenerateCores" xil_pn:prop_ck="5643155787033519143" xil_pn:start_ts="1654895235">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1654895235" xil_pn:name="TRAN_SubProjectAbstractToPreProxy" xil_pn:start_ts="1654895235">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1654895235" xil_pn:name="TRAN_xawsTohdl" xil_pn:prop_ck="-8675282148687179814" xil_pn:start_ts="1654895235">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
</transforms>
</generated_project>
@@ -0,0 +1,149 @@
--------------------------------------------------------------------------------
-- This file is owned and controlled by Xilinx and must be used solely --
-- for design, simulation, implementation and creation of design files --
-- limited to Xilinx devices or technologies. Use with non-Xilinx --
-- devices or technologies is expressly prohibited and immediately --
-- terminates your license. --
-- --
-- XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" SOLELY --
-- FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR XILINX DEVICES. BY --
-- PROVIDING THIS DESIGN, CODE, OR INFORMATION AS ONE POSSIBLE --
-- IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD, XILINX IS --
-- MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE FROM ANY --
-- CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING ANY --
-- RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY --
-- DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE --
-- IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR --
-- REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF --
-- INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A --
-- PARTICULAR PURPOSE. --
-- --
-- Xilinx products are not intended for use in life support appliances, --
-- devices, or systems. Use in such applications are expressly --
-- prohibited. --
-- --
-- (c) Copyright 1995-2022 Xilinx, Inc. --
-- All rights reserved. --
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- You must compile the wrapper file ModulationMemory.vhd when simulating
-- the core, ModulationMemory. When compiling the wrapper file, be sure to
-- reference the XilinxCoreLib VHDL simulation library. For detailed
-- instructions, please refer to the "CORE Generator Help".
-- The synthesis directives "translate_off/translate_on" specified
-- below are supported by Xilinx, Mentor Graphics and Synplicity
-- synthesis tools. Ensure they are correct for your synthesis tool(s).
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- synthesis translate_off
LIBRARY XilinxCoreLib;
-- synthesis translate_on
ENTITY ModulationMemory IS
PORT (
clka : IN STD_LOGIC;
wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
addra : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
dina : IN STD_LOGIC_VECTOR(143 DOWNTO 0);
clkb : IN STD_LOGIC;
addrb : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
doutb : OUT STD_LOGIC_VECTOR(143 DOWNTO 0)
);
END ModulationMemory;
ARCHITECTURE ModulationMemory_a OF ModulationMemory IS
-- synthesis translate_off
COMPONENT wrapped_ModulationMemory
PORT (
clka : IN STD_LOGIC;
wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
addra : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
dina : IN STD_LOGIC_VECTOR(143 DOWNTO 0);
clkb : IN STD_LOGIC;
addrb : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
doutb : OUT STD_LOGIC_VECTOR(143 DOWNTO 0)
);
END COMPONENT;
-- Configuration specification
FOR ALL : wrapped_ModulationMemory USE ENTITY XilinxCoreLib.blk_mem_gen_v7_3(behavioral)
GENERIC MAP (
c_addra_width => 8,
c_addrb_width => 8,
c_algorithm => 1,
c_axi_id_width => 4,
c_axi_slave_type => 0,
c_axi_type => 1,
c_byte_size => 9,
c_common_clk => 0,
c_default_data => "0",
c_disable_warn_bhv_coll => 0,
c_disable_warn_bhv_range => 0,
c_enable_32bit_address => 0,
c_family => "spartan6",
c_has_axi_id => 0,
c_has_ena => 0,
c_has_enb => 0,
c_has_injecterr => 0,
c_has_mem_output_regs_a => 0,
c_has_mem_output_regs_b => 0,
c_has_mux_output_regs_a => 0,
c_has_mux_output_regs_b => 0,
c_has_regcea => 0,
c_has_regceb => 0,
c_has_rsta => 0,
c_has_rstb => 0,
c_has_softecc_input_regs_a => 0,
c_has_softecc_output_regs_b => 0,
c_init_file => "BlankString",
c_init_file_name => "no_coe_file_loaded",
c_inita_val => "0",
c_initb_val => "0",
c_interface_type => 0,
c_load_init_file => 0,
c_mem_type => 1,
c_mux_pipeline_stages => 0,
c_prim_type => 1,
c_read_depth_a => 256,
c_read_depth_b => 256,
c_read_width_a => 144,
c_read_width_b => 144,
c_rst_priority_a => "CE",
c_rst_priority_b => "CE",
c_rst_type => "SYNC",
c_rstram_a => 0,
c_rstram_b => 0,
c_sim_collision_check => "ALL",
c_use_bram_block => 0,
c_use_byte_wea => 0,
c_use_byte_web => 0,
c_use_default_data => 0,
c_use_ecc => 0,
c_use_softecc => 0,
c_wea_width => 1,
c_web_width => 1,
c_write_depth_a => 256,
c_write_depth_b => 256,
c_write_mode_a => "WRITE_FIRST",
c_write_mode_b => "WRITE_FIRST",
c_write_width_a => 144,
c_write_width_b => 144,
c_xdevicefamily => "spartan6"
);
-- synthesis translate_on
BEGIN
-- synthesis translate_off
U0 : wrapped_ModulationMemory
PORT MAP (
clka => clka,
wea => wea,
addra => addra,
dina => dina,
clkb => clkb,
addrb => addrb,
doutb => doutb
);
-- synthesis translate_on
END ModulationMemory_a;
@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<generated_project xmlns="http://www.xilinx.com/XMLSchema" xmlns:xil_pn="http://www.xilinx.com/XMLSchema">
<!-- -->
<!-- For tool use only. Do not edit. -->
<!-- -->
<!-- ProjectNavigator created generated project file. -->
<!-- For use in tracking generated file and other information -->
<!-- allowing preservation of process status. -->
<!-- -->
<!-- Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved. -->
<version xmlns="http://www.xilinx.com/XMLSchema">11.1</version>
<sourceproject xmlns="http://www.xilinx.com/XMLSchema" xil_pn:fileType="FILE_XISE" xil_pn:name="PLL.xise"/>
<files xmlns="http://www.xilinx.com/XMLSchema">
<file xil_pn:fileType="FILE_ASY" xil_pn:name="PLL.asy" xil_pn:origination="imported"/>
<file xil_pn:fileType="FILE_VHO" xil_pn:name="PLL.vho" xil_pn:origination="imported"/>
</files>
<transforms xmlns="http://www.xilinx.com/XMLSchema">
<transform xil_pn:end_ts="1588801396" xil_pn:name="TRAN_copyInitialToXSTAbstractSynthesis" xil_pn:start_ts="1588801396">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1654895235" xil_pn:name="TRAN_schematicsToHdl" xil_pn:prop_ck="-7485999881756126958" xil_pn:start_ts="1654895235">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1654895235" xil_pn:name="TRAN_regenerateCores" xil_pn:prop_ck="5187593455580750305" xil_pn:start_ts="1654895235">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1654895235" xil_pn:name="TRAN_SubProjectAbstractToPreProxy" xil_pn:start_ts="1654895235">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1654895235" xil_pn:name="TRAN_xawsTohdl" xil_pn:prop_ck="-8519729393005554412" xil_pn:start_ts="1654895235">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
</transforms>
</generated_project>
@@ -0,0 +1,59 @@
# file: PLL.ucf
#
# (c) Copyright 2008 - 2011 Xilinx, Inc. All rights reserved.
#
# This file contains confidential and proprietary information
# of Xilinx, Inc. and is protected under U.S. and
# international copyright and other intellectual property
# laws.
#
# DISCLAIMER
# This disclaimer is not a license and does not grant any
# rights to the materials distributed herewith. Except as
# otherwise provided in a valid license issued to you by
# Xilinx, and to the maximum extent permitted by applicable
# law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
# WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
# AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
# BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
# INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
# (2) Xilinx shall not be liable (whether in contract or tort,
# including negligence, or under any other theory of
# liability) for any loss or damage of any kind or nature
# related to, arising under or in connection with these
# materials, including for any direct, or any indirect,
# special, incidental, or consequential loss or damage
# (including loss of data, profits, goodwill, or any type of
# loss or damage suffered as a result of any action brought
# by a third party) even if such damage or loss was
# reasonably foreseeable or Xilinx had been advised of the
# possibility of the same.
#
# CRITICAL APPLICATIONS
# Xilinx products are not designed or intended to be fail-
# safe, or for use in any application requiring fail-safe
# performance, such as life-support or safety devices or
# systems, Class III medical devices, nuclear facilities,
# applications related to the deployment of airbags, or any
# other applications that could lead to death, personal
# injury, or severe property or environmental damage
# (individually and collectively, "Critical
# Applications"). Customer assumes the sole risk and
# liability of any use of Xilinx products in Critical
# Applications, subject only to applicable laws and
# regulations governing limitations on product liability.
#
# THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
# PART OF THIS FILE AT ALL TIMES.
#
# Input clock periods. These duplicate the values entered for the
# input clocks. You can use these to time your system
#----------------------------------------------------------------
NET "CLK_IN1" TNM_NET = "CLK_IN1";
TIMESPEC "TS_CLK_IN1" = PERIOD "CLK_IN1" 62.5 ns HIGH 50% INPUT_JITTER 625.0ps;
# FALSE PATH constraints
PIN "RESET" TIG;
@@ -0,0 +1,172 @@
-- file: PLL.vhd
--
-- (c) Copyright 2008 - 2011 Xilinx, Inc. All rights reserved.
--
-- This file contains confidential and proprietary information
-- of Xilinx, Inc. and is protected under U.S. and
-- international copyright and other intellectual property
-- laws.
--
-- DISCLAIMER
-- This disclaimer is not a license and does not grant any
-- rights to the materials distributed herewith. Except as
-- otherwise provided in a valid license issued to you by
-- Xilinx, and to the maximum extent permitted by applicable
-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
-- (2) Xilinx shall not be liable (whether in contract or tort,
-- including negligence, or under any other theory of
-- liability) for any loss or damage of any kind or nature
-- related to, arising under or in connection with these
-- materials, including for any direct, or any indirect,
-- special, incidental, or consequential loss or damage
-- (including loss of data, profits, goodwill, or any type of
-- loss or damage suffered as a result of any action brought
-- by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the
-- possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-
-- safe, or for use in any application requiring fail-safe
-- performance, such as life-support or safety devices or
-- systems, Class III medical devices, nuclear facilities,
-- applications related to the deployment of airbags, or any
-- other applications that could lead to death, personal
-- injury, or severe property or environmental damage
-- (individually and collectively, "Critical
-- Applications"). Customer assumes the sole risk and
-- liability of any use of Xilinx products in Critical
-- Applications, subject only to applicable laws and
-- regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
-- PART OF THIS FILE AT ALL TIMES.
--
------------------------------------------------------------------------------
-- User entered comments
------------------------------------------------------------------------------
-- None
--
------------------------------------------------------------------------------
-- "Output Output Phase Duty Pk-to-Pk Phase"
-- "Clock Freq (MHz) (degrees) Cycle (%) Jitter (ps) Error (ps)"
------------------------------------------------------------------------------
-- CLK_OUT1___102.400______0.000______50.0_____1274.405____150.000
--
------------------------------------------------------------------------------
-- "Input Clock Freq (MHz) Input Jitter (UI)"
------------------------------------------------------------------------------
-- __primary______________16____________0.010
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
library unisim;
use unisim.vcomponents.all;
entity PLL is
port
(-- Clock in ports
CLK_IN1 : in std_logic;
-- Clock out ports
CLK_OUT1 : out std_logic;
-- Status and control signals
RESET : in std_logic;
LOCKED : out std_logic
);
end PLL;
architecture xilinx of PLL is
attribute CORE_GENERATION_INFO : string;
attribute CORE_GENERATION_INFO of xilinx : architecture is "PLL,clk_wiz_v3_6,{component_name=PLL,use_phase_alignment=true,use_min_o_jitter=false,use_max_i_jitter=false,use_dyn_phase_shift=false,use_inclk_switchover=false,use_dyn_reconfig=false,feedback_source=FDBK_AUTO,primtype_sel=DCM_SP,num_out_clk=1,clkin1_period=62.5,clkin2_period=62.5,use_power_down=false,use_reset=true,use_locked=true,use_inclk_stopped=false,use_status=false,use_freeze=false,use_clk_valid=false,feedback_type=SINGLE,clock_mgr_type=AUTO,manual_override=false}";
-- Input clock buffering / unused connectors
signal clkin1 : std_logic;
-- Output clock buffering
signal clkfb : std_logic;
signal clk0 : std_logic;
signal clkfx : std_logic;
signal clkfbout : std_logic;
signal locked_internal : std_logic;
signal status_internal : std_logic_vector(7 downto 0);
begin
-- Input buffering
--------------------------------------
clkin1_buf : IBUFG
port map
(O => clkin1,
I => CLK_IN1);
-- Clocking primitive
--------------------------------------
-- Instantiation of the DCM primitive
-- * Unused inputs are tied off
-- * Unused outputs are labeled unused
dcm_sp_inst: DCM_SP
generic map
(CLKDV_DIVIDE => 2.000,
CLKFX_DIVIDE => 5,
CLKFX_MULTIPLY => 32,
CLKIN_DIVIDE_BY_2 => FALSE,
CLKIN_PERIOD => 62.5,
CLKOUT_PHASE_SHIFT => "NONE",
CLK_FEEDBACK => "1X",
DESKEW_ADJUST => "SYSTEM_SYNCHRONOUS",
PHASE_SHIFT => 0,
STARTUP_WAIT => FALSE)
port map
-- Input clock
(CLKIN => clkin1,
CLKFB => clkfb,
-- Output clocks
CLK0 => clk0,
CLK90 => open,
CLK180 => open,
CLK270 => open,
CLK2X => open,
CLK2X180 => open,
CLKFX => clkfx,
CLKFX180 => open,
CLKDV => open,
-- Ports for dynamic phase shift
PSCLK => '0',
PSEN => '0',
PSINCDEC => '0',
PSDONE => open,
-- Other control and status signals
LOCKED => locked_internal,
STATUS => status_internal,
RST => RESET,
-- Unused pin, tie low
DSSEN => '0');
LOCKED <= locked_internal;
-- Output buffering
-------------------------------------
clkf_buf : BUFG
port map
(O => clkfb,
I => clk0);
clkout1_buf : BUFG
port map
(O => CLK_OUT1,
I => clkfx);
end xilinx;
@@ -0,0 +1,60 @@
# file: PLL_exdes.ucf
#
# (c) Copyright 2008 - 2011 Xilinx, Inc. All rights reserved.
#
# This file contains confidential and proprietary information
# of Xilinx, Inc. and is protected under U.S. and
# international copyright and other intellectual property
# laws.
#
# DISCLAIMER
# This disclaimer is not a license and does not grant any
# rights to the materials distributed herewith. Except as
# otherwise provided in a valid license issued to you by
# Xilinx, and to the maximum extent permitted by applicable
# law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
# WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
# AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
# BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
# INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
# (2) Xilinx shall not be liable (whether in contract or tort,
# including negligence, or under any other theory of
# liability) for any loss or damage of any kind or nature
# related to, arising under or in connection with these
# materials, including for any direct, or any indirect,
# special, incidental, or consequential loss or damage
# (including loss of data, profits, goodwill, or any type of
# loss or damage suffered as a result of any action brought
# by a third party) even if such damage or loss was
# reasonably foreseeable or Xilinx had been advised of the
# possibility of the same.
#
# CRITICAL APPLICATIONS
# Xilinx products are not designed or intended to be fail-
# safe, or for use in any application requiring fail-safe
# performance, such as life-support or safety devices or
# systems, Class III medical devices, nuclear facilities,
# applications related to the deployment of airbags, or any
# other applications that could lead to death, personal
# injury, or severe property or environmental damage
# (individually and collectively, "Critical
# Applications"). Customer assumes the sole risk and
# liability of any use of Xilinx products in Critical
# Applications, subject only to applicable laws and
# regulations governing limitations on product liability.
#
# THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
# PART OF THIS FILE AT ALL TIMES.
#
# Input clock periods. These duplicate the values entered for the
# input clocks. You can use these to time your system
#----------------------------------------------------------------
NET "CLK_IN1" TNM_NET = "CLK_IN1";
TIMESPEC "TS_CLK_IN1" = PERIOD "CLK_IN1" 62.5 ns HIGH 50% INPUT_JITTER 625.0ps;
# FALSE PATH constraints
PIN "COUNTER_RESET" TIG;
PIN "RESET" TIG;
@@ -0,0 +1,182 @@
-- file: PLL_exdes.vhd
--
-- (c) Copyright 2008 - 2011 Xilinx, Inc. All rights reserved.
--
-- This file contains confidential and proprietary information
-- of Xilinx, Inc. and is protected under U.S. and
-- international copyright and other intellectual property
-- laws.
--
-- DISCLAIMER
-- This disclaimer is not a license and does not grant any
-- rights to the materials distributed herewith. Except as
-- otherwise provided in a valid license issued to you by
-- Xilinx, and to the maximum extent permitted by applicable
-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
-- (2) Xilinx shall not be liable (whether in contract or tort,
-- including negligence, or under any other theory of
-- liability) for any loss or damage of any kind or nature
-- related to, arising under or in connection with these
-- materials, including for any direct, or any indirect,
-- special, incidental, or consequential loss or damage
-- (including loss of data, profits, goodwill, or any type of
-- loss or damage suffered as a result of any action brought
-- by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the
-- possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-
-- safe, or for use in any application requiring fail-safe
-- performance, such as life-support or safety devices or
-- systems, Class III medical devices, nuclear facilities,
-- applications related to the deployment of airbags, or any
-- other applications that could lead to death, personal
-- injury, or severe property or environmental damage
-- (individually and collectively, "Critical
-- Applications"). Customer assumes the sole risk and
-- liability of any use of Xilinx products in Critical
-- Applications, subject only to applicable laws and
-- regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
-- PART OF THIS FILE AT ALL TIMES.
--
------------------------------------------------------------------------------
-- Clocking wizard example design
------------------------------------------------------------------------------
-- This example design instantiates the created clocking network, where each
-- output clock drives a counter. The high bit of each counter is ported.
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
library unisim;
use unisim.vcomponents.all;
entity PLL_exdes is
generic (
TCQ : in time := 100 ps);
port
(-- Clock in ports
CLK_IN1 : in std_logic;
-- Reset that only drives logic in example design
COUNTER_RESET : in std_logic;
CLK_OUT : out std_logic_vector(1 downto 1) ;
-- High bits of counters driven by clocks
COUNT : out std_logic;
-- Status and control signals
RESET : in std_logic;
LOCKED : out std_logic
);
end PLL_exdes;
architecture xilinx of PLL_exdes is
-- Parameters for the counters
---------------------------------
-- Counter width
constant C_W : integer := 16;
-- When the clock goes out of lock, reset the counters
signal locked_int : std_logic;
signal reset_int : std_logic := '0';
-- Declare the clocks and counter
signal clk : std_logic;
signal clk_int : std_logic;
signal clk_n : std_logic;
signal counter : std_logic_vector(C_W-1 downto 0) := (others => '0');
signal rst_sync : std_logic;
signal rst_sync_int : std_logic;
signal rst_sync_int1 : std_logic;
signal rst_sync_int2 : std_logic;
component PLL is
port
(-- Clock in ports
CLK_IN1 : in std_logic;
-- Clock out ports
CLK_OUT1 : out std_logic;
-- Status and control signals
RESET : in std_logic;
LOCKED : out std_logic
);
end component;
begin
-- Alias output to internally used signal
LOCKED <= locked_int;
-- When the clock goes out of lock, reset the counters
reset_int <= (not locked_int) or RESET or COUNTER_RESET;
process (clk, reset_int) begin
if (reset_int = '1') then
rst_sync <= '1';
rst_sync_int <= '1';
rst_sync_int1 <= '1';
rst_sync_int2 <= '1';
elsif (clk 'event and clk='1') then
rst_sync <= '0';
rst_sync_int <= rst_sync;
rst_sync_int1 <= rst_sync_int;
rst_sync_int2 <= rst_sync_int1;
end if;
end process;
-- Instantiation of the clocking network
----------------------------------------
clknetwork : PLL
port map
(-- Clock in ports
CLK_IN1 => CLK_IN1,
-- Clock out ports
CLK_OUT1 => clk_int,
-- Status and control signals
RESET => RESET,
LOCKED => locked_int);
clk_n <= not clk;
clkout_oddr : ODDR2
port map
(Q => CLK_OUT(1),
C0 => clk,
C1 => clk_n,
CE => '1',
D0 => '1',
D1 => '0',
R => '0',
S => '0');
-- Connect the output clocks to the design
-------------------------------------------
clk <= clk_int;
-- Output clock sampling
-------------------------------------
process (clk, rst_sync_int2) begin
if (rst_sync_int2 = '1') then
counter <= (others => '0') after TCQ;
elsif (rising_edge(clk)) then
counter <= counter + 1 after TCQ;
end if;
end process;
-- alias the high bit to the output
COUNT <= counter(C_W-1);
end xilinx;
@@ -0,0 +1,197 @@
-- file: PLL_tb.vhd
--
-- (c) Copyright 2008 - 2011 Xilinx, Inc. All rights reserved.
--
-- This file contains confidential and proprietary information
-- of Xilinx, Inc. and is protected under U.S. and
-- international copyright and other intellectual property
-- laws.
--
-- DISCLAIMER
-- This disclaimer is not a license and does not grant any
-- rights to the materials distributed herewith. Except as
-- otherwise provided in a valid license issued to you by
-- Xilinx, and to the maximum extent permitted by applicable
-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
-- (2) Xilinx shall not be liable (whether in contract or tort,
-- including negligence, or under any other theory of
-- liability) for any loss or damage of any kind or nature
-- related to, arising under or in connection with these
-- materials, including for any direct, or any indirect,
-- special, incidental, or consequential loss or damage
-- (including loss of data, profits, goodwill, or any type of
-- loss or damage suffered as a result of any action brought
-- by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the
-- possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-
-- safe, or for use in any application requiring fail-safe
-- performance, such as life-support or safety devices or
-- systems, Class III medical devices, nuclear facilities,
-- applications related to the deployment of airbags, or any
-- other applications that could lead to death, personal
-- injury, or severe property or environmental damage
-- (individually and collectively, "Critical
-- Applications"). Customer assumes the sole risk and
-- liability of any use of Xilinx products in Critical
-- Applications, subject only to applicable laws and
-- regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
-- PART OF THIS FILE AT ALL TIMES.
--
------------------------------------------------------------------------------
-- Clocking wizard demonstration testbench
------------------------------------------------------------------------------
-- This demonstration testbench instantiates the example design for the
-- clocking wizard. Input clocks are toggled, which cause the clocking
-- network to lock and the counters to increment.
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
use ieee.std_logic_textio.all;
library std;
use std.textio.all;
library work;
use work.all;
entity PLL_tb is
end PLL_tb;
architecture test of PLL_tb is
-- Clock to Q delay of 100 ps
constant TCQ : time := 100 ps;
-- timescale is 1ps
constant ONE_NS : time := 1 ns;
-- how many cycles to run
constant COUNT_PHASE : integer := 1024 + 1;
-- we'll be using the period in many locations
constant PER1 : time := 62.5 ns;
-- Declare the input clock signals
signal CLK_IN1 : std_logic := '1';
-- The high bit of the sampling counter
signal COUNT : std_logic;
-- Status and control signals
signal RESET : std_logic := '0';
signal LOCKED : std_logic;
signal COUNTER_RESET : std_logic := '0';
-- signal defined to stop mti simulation without severity failure in the report
signal end_of_sim : std_logic := '0';
signal CLK_OUT : std_logic_vector(1 downto 1);
--Freq Check using the M & D values setting and actual Frequency generated
component PLL_exdes
generic (
TCQ : in time := 100 ps);
port
(-- Clock in ports
CLK_IN1 : in std_logic;
-- Reset that only drives logic in example design
COUNTER_RESET : in std_logic;
CLK_OUT : out std_logic_vector(1 downto 1) ;
-- High bits of counters driven by clocks
COUNT : out std_logic;
-- Status and control signals
RESET : in std_logic;
LOCKED : out std_logic
);
end component;
begin
-- Input clock generation
--------------------------------------
process begin
CLK_IN1 <= not CLK_IN1; wait for (PER1/2);
end process;
-- Test sequence
process
procedure simtimeprint is
variable outline : line;
begin
write(outline, string'("## SYSTEM_CYCLE_COUNTER "));
write(outline, NOW/PER1);
write(outline, string'(" ns"));
writeline(output,outline);
end simtimeprint;
procedure simfreqprint (period : time; clk_num : integer) is
variable outputline : LINE;
variable str1 : string(1 to 16);
variable str2 : integer;
variable str3 : string(1 to 2);
variable str4 : integer;
variable str5 : string(1 to 4);
begin
str1 := "Freq of CLK_OUT(";
str2 := clk_num;
str3 := ") ";
str4 := 1000000 ps/period ;
str5 := " MHz" ;
write(outputline, str1 );
write(outputline, str2);
write(outputline, str3);
write(outputline, str4);
write(outputline, str5);
writeline(output, outputline);
end simfreqprint;
begin
RESET <= '1';
wait for (PER1*6);
RESET <= '0';
wait until LOCKED = '1';
COUNTER_RESET <= '1';
wait for (PER1*20);
COUNTER_RESET <= '0';
wait for (PER1*COUNT_PHASE);
simtimeprint;
end_of_sim <= '1';
wait for 1 ps;
report "Simulation Stopped." severity failure;
wait;
end process;
-- Instantiation of the example design containing the clock
-- network and sampling counters
-----------------------------------------------------------
dut : PLL_exdes
generic map (
TCQ => TCQ)
port map
(-- Clock in ports
CLK_IN1 => CLK_IN1,
-- Reset for logic in example design
COUNTER_RESET => COUNTER_RESET,
CLK_OUT => CLK_OUT,
-- High bits of the counters
COUNT => COUNT,
-- Status and control signals
RESET => RESET,
LOCKED => LOCKED);
-- Freq Check
end test;
@@ -0,0 +1,220 @@
-- file: PLL_tb.vhd
--
-- (c) Copyright 2008 - 2011 Xilinx, Inc. All rights reserved.
--
-- This file contains confidential and proprietary information
-- of Xilinx, Inc. and is protected under U.S. and
-- international copyright and other intellectual property
-- laws.
--
-- DISCLAIMER
-- This disclaimer is not a license and does not grant any
-- rights to the materials distributed herewith. Except as
-- otherwise provided in a valid license issued to you by
-- Xilinx, and to the maximum extent permitted by applicable
-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
-- (2) Xilinx shall not be liable (whether in contract or tort,
-- including negligence, or under any other theory of
-- liability) for any loss or damage of any kind or nature
-- related to, arising under or in connection with these
-- materials, including for any direct, or any indirect,
-- special, incidental, or consequential loss or damage
-- (including loss of data, profits, goodwill, or any type of
-- loss or damage suffered as a result of any action brought
-- by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the
-- possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-
-- safe, or for use in any application requiring fail-safe
-- performance, such as life-support or safety devices or
-- systems, Class III medical devices, nuclear facilities,
-- applications related to the deployment of airbags, or any
-- other applications that could lead to death, personal
-- injury, or severe property or environmental damage
-- (individually and collectively, "Critical
-- Applications"). Customer assumes the sole risk and
-- liability of any use of Xilinx products in Critical
-- Applications, subject only to applicable laws and
-- regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
-- PART OF THIS FILE AT ALL TIMES.
--
------------------------------------------------------------------------------
-- Clocking wizard demonstration testbench
------------------------------------------------------------------------------
-- This demonstration testbench instantiates the example design for the
-- clocking wizard. Input clocks are toggled, which cause the clocking
-- network to lock and the counters to increment.
------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
use ieee.std_logic_textio.all;
library std;
use std.textio.all;
library work;
use work.all;
entity PLL_tb is
end PLL_tb;
architecture test of PLL_tb is
-- Clock to Q delay of 100 ps
constant TCQ : time := 100 ps;
-- timescale is 1ps
constant ONE_NS : time := 1 ns;
-- how many cycles to run
constant COUNT_PHASE : integer := 1024 + 1;
-- we'll be using the period in many locations
constant PER1 : time := 62.5 ns;
-- Declare the input clock signals
signal CLK_IN1 : std_logic := '1';
-- The high bit of the sampling counter
signal COUNT : std_logic;
-- Status and control signals
signal RESET : std_logic := '0';
signal LOCKED : std_logic;
signal COUNTER_RESET : std_logic := '0';
signal timeout_counter : std_logic_vector (13 downto 0) := (others => '0');
-- signal defined to stop mti simulation without severity failure in the report
signal end_of_sim : std_logic := '0';
signal CLK_OUT : std_logic_vector(1 downto 1);
--Freq Check using the M & D values setting and actual Frequency generated
component PLL_exdes
port
(-- Clock in ports
CLK_IN1 : in std_logic;
-- Reset that only drives logic in example design
COUNTER_RESET : in std_logic;
CLK_OUT : out std_logic_vector(1 downto 1) ;
-- High bits of counters driven by clocks
COUNT : out std_logic;
-- Status and control signals
RESET : in std_logic;
LOCKED : out std_logic
);
end component;
begin
-- Input clock generation
--------------------------------------
process begin
CLK_IN1 <= not CLK_IN1; wait for (PER1/2);
end process;
-- Test sequence
process
procedure simtimeprint is
variable outline : line;
begin
write(outline, string'("## SYSTEM_CYCLE_COUNTER "));
write(outline, NOW/PER1);
write(outline, string'(" ns"));
writeline(output,outline);
end simtimeprint;
procedure simfreqprint (period : time; clk_num : integer) is
variable outputline : LINE;
variable str1 : string(1 to 16);
variable str2 : integer;
variable str3 : string(1 to 2);
variable str4 : integer;
variable str5 : string(1 to 4);
begin
str1 := "Freq of CLK_OUT(";
str2 := clk_num;
str3 := ") ";
str4 := 1000000 ps/period ;
str5 := " MHz" ;
write(outputline, str1 );
write(outputline, str2);
write(outputline, str3);
write(outputline, str4);
write(outputline, str5);
writeline(output, outputline);
end simfreqprint;
begin
report "Timing checks are not valid" severity note;
RESET <= '1';
wait for (PER1*6);
RESET <= '0';
wait until LOCKED = '1';
wait for (PER1*20);
COUNTER_RESET <= '1';
wait for (PER1*19.5);
COUNTER_RESET <= '0';
wait for (PER1*1);
report "Timing checks are valid" severity note;
wait for (PER1*COUNT_PHASE);
simtimeprint;
end_of_sim <= '1';
wait for 1 ps;
report "Simulation Stopped." severity failure;
wait;
end process;
process (CLK_IN1)
procedure simtimeprint is
variable outline : line;
begin
write(outline, string'("## SYSTEM_CYCLE_COUNTER "));
write(outline, NOW/PER1);
write(outline, string'(" ns"));
writeline(output,outline);
end simtimeprint;
begin
if (CLK_IN1'event and CLK_IN1='1') then
timeout_counter <= timeout_counter + '1';
if (timeout_counter = "10000000000000") then
if (LOCKED /= '1') then
simtimeprint;
report "NO LOCK signal" severity failure;
end if;
end if;
end if;
end process;
-- Instantiation of the example design containing the clock
-- network and sampling counters
-----------------------------------------------------------
dut : PLL_exdes
port map
(-- Clock in ports
CLK_IN1 => CLK_IN1,
-- Reset for logic in example design
COUNTER_RESET => COUNTER_RESET,
CLK_OUT => CLK_OUT,
-- High bits of the counters
COUNT => COUNT,
-- Status and control signals
RESET => RESET,
LOCKED => LOCKED);
-- Freq Check
end test;
@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<generated_project xmlns="http://www.xilinx.com/XMLSchema" xmlns:xil_pn="http://www.xilinx.com/XMLSchema">
<!-- -->
<!-- For tool use only. Do not edit. -->
<!-- -->
<!-- ProjectNavigator created generated project file. -->
<!-- For use in tracking generated file and other information -->
<!-- allowing preservation of process status. -->
<!-- -->
<!-- Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved. -->
<version xmlns="http://www.xilinx.com/XMLSchema">11.1</version>
<sourceproject xmlns="http://www.xilinx.com/XMLSchema" xil_pn:fileType="FILE_XISE" xil_pn:name="SampleMemory.xise"/>
<files xmlns="http://www.xilinx.com/XMLSchema">
<file xil_pn:fileType="FILE_ASY" xil_pn:name="SampleMemory.asy" xil_pn:origination="imported"/>
<file xil_pn:fileType="FILE_SYMBOL" xil_pn:name="SampleMemory.sym" xil_pn:origination="imported"/>
<file xil_pn:fileType="FILE_VHO" xil_pn:name="SampleMemory.vho" xil_pn:origination="imported"/>
</files>
<transforms xmlns="http://www.xilinx.com/XMLSchema">
<transform xil_pn:end_ts="1654646662" xil_pn:name="TRAN_copyInitialToXSTAbstractSynthesis" xil_pn:start_ts="1654646662">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1654895235" xil_pn:name="TRAN_schematicsToHdl" xil_pn:prop_ck="-5346285223313661724" xil_pn:start_ts="1654895235">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1654895235" xil_pn:name="TRAN_regenerateCores" xil_pn:prop_ck="7774384757506685939" xil_pn:start_ts="1654895235">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1654895235" xil_pn:name="TRAN_SubProjectAbstractToPreProxy" xil_pn:start_ts="1654895235">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1654895235" xil_pn:name="TRAN_xawsTohdl" xil_pn:prop_ck="-6611130985775322842" xil_pn:start_ts="1654895235">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
</transforms>
</generated_project>
@@ -0,0 +1,149 @@
--------------------------------------------------------------------------------
-- This file is owned and controlled by Xilinx and must be used solely --
-- for design, simulation, implementation and creation of design files --
-- limited to Xilinx devices or technologies. Use with non-Xilinx --
-- devices or technologies is expressly prohibited and immediately --
-- terminates your license. --
-- --
-- XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" SOLELY --
-- FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR XILINX DEVICES. BY --
-- PROVIDING THIS DESIGN, CODE, OR INFORMATION AS ONE POSSIBLE --
-- IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD, XILINX IS --
-- MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE FROM ANY --
-- CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING ANY --
-- RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY --
-- DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE --
-- IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR --
-- REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF --
-- INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A --
-- PARTICULAR PURPOSE. --
-- --
-- Xilinx products are not intended for use in life support appliances, --
-- devices, or systems. Use in such applications are expressly --
-- prohibited. --
-- --
-- (c) Copyright 1995-2022 Xilinx, Inc. --
-- All rights reserved. --
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- You must compile the wrapper file SampleMemory.vhd when simulating
-- the core, SampleMemory. When compiling the wrapper file, be sure to
-- reference the XilinxCoreLib VHDL simulation library. For detailed
-- instructions, please refer to the "CORE Generator Help".
-- The synthesis directives "translate_off/translate_on" specified
-- below are supported by Xilinx, Mentor Graphics and Synplicity
-- synthesis tools. Ensure they are correct for your synthesis tool(s).
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- synthesis translate_off
LIBRARY XilinxCoreLib;
-- synthesis translate_on
ENTITY SampleMemory IS
PORT (
clka : IN STD_LOGIC;
wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
addra : IN STD_LOGIC_VECTOR(10 DOWNTO 0);
dina : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
clkb : IN STD_LOGIC;
addrb : IN STD_LOGIC_VECTOR(10 DOWNTO 0);
doutb : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END SampleMemory;
ARCHITECTURE SampleMemory_a OF SampleMemory IS
-- synthesis translate_off
COMPONENT wrapped_SampleMemory
PORT (
clka : IN STD_LOGIC;
wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
addra : IN STD_LOGIC_VECTOR(10 DOWNTO 0);
dina : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
clkb : IN STD_LOGIC;
addrb : IN STD_LOGIC_VECTOR(10 DOWNTO 0);
doutb : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END COMPONENT;
-- Configuration specification
FOR ALL : wrapped_SampleMemory USE ENTITY XilinxCoreLib.blk_mem_gen_v7_3(behavioral)
GENERIC MAP (
c_addra_width => 11,
c_addrb_width => 11,
c_algorithm => 1,
c_axi_id_width => 4,
c_axi_slave_type => 0,
c_axi_type => 1,
c_byte_size => 9,
c_common_clk => 0,
c_default_data => "0",
c_disable_warn_bhv_coll => 0,
c_disable_warn_bhv_range => 0,
c_enable_32bit_address => 0,
c_family => "spartan6",
c_has_axi_id => 0,
c_has_ena => 0,
c_has_enb => 0,
c_has_injecterr => 0,
c_has_mem_output_regs_a => 0,
c_has_mem_output_regs_b => 0,
c_has_mux_output_regs_a => 0,
c_has_mux_output_regs_b => 0,
c_has_regcea => 0,
c_has_regceb => 0,
c_has_rsta => 0,
c_has_rstb => 0,
c_has_softecc_input_regs_a => 0,
c_has_softecc_output_regs_b => 0,
c_init_file => "BlankString",
c_init_file_name => "no_coe_file_loaded",
c_inita_val => "0",
c_initb_val => "0",
c_interface_type => 0,
c_load_init_file => 0,
c_mem_type => 1,
c_mux_pipeline_stages => 0,
c_prim_type => 1,
c_read_depth_a => 2048,
c_read_depth_b => 2048,
c_read_width_a => 8,
c_read_width_b => 8,
c_rst_priority_a => "CE",
c_rst_priority_b => "CE",
c_rst_type => "SYNC",
c_rstram_a => 0,
c_rstram_b => 0,
c_sim_collision_check => "ALL",
c_use_bram_block => 0,
c_use_byte_wea => 0,
c_use_byte_web => 0,
c_use_default_data => 0,
c_use_ecc => 0,
c_use_softecc => 0,
c_wea_width => 1,
c_web_width => 1,
c_write_depth_a => 2048,
c_write_depth_b => 2048,
c_write_mode_a => "WRITE_FIRST",
c_write_mode_b => "WRITE_FIRST",
c_write_width_a => 8,
c_write_width_b => 8,
c_xdevicefamily => "spartan6"
);
-- synthesis translate_on
BEGIN
-- synthesis translate_off
U0 : wrapped_SampleMemory
PORT MAP (
clka => clka,
wea => wea,
addra => addra,
dina => dina,
clkb => clkb,
addrb => addrb,
doutb => doutb
);
-- synthesis translate_on
END SampleMemory_a;
@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<generated_project xmlns="http://www.xilinx.com/XMLSchema" xmlns:xil_pn="http://www.xilinx.com/XMLSchema">
<!-- -->
<!-- For tool use only. Do not edit. -->
<!-- -->
<!-- ProjectNavigator created generated project file. -->
<!-- For use in tracking generated file and other information -->
<!-- allowing preservation of process status. -->
<!-- -->
<!-- Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved. -->
<version xmlns="http://www.xilinx.com/XMLSchema">11.1</version>
<sourceproject xmlns="http://www.xilinx.com/XMLSchema" xil_pn:fileType="FILE_XISE" xil_pn:name="SinCos.xise"/>
<files xmlns="http://www.xilinx.com/XMLSchema">
<file xil_pn:fileType="FILE_ASY" xil_pn:name="SinCos.asy" xil_pn:origination="imported"/>
<file xil_pn:fileType="FILE_SYMBOL" xil_pn:name="SinCos.sym" xil_pn:origination="imported"/>
<file xil_pn:fileType="FILE_VHO" xil_pn:name="SinCos.vho" xil_pn:origination="imported"/>
</files>
<transforms xmlns="http://www.xilinx.com/XMLSchema">
<transform xil_pn:end_ts="1588801396" xil_pn:name="TRAN_copyInitialToXSTAbstractSynthesis" xil_pn:start_ts="1588801396">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1600270761" xil_pn:name="TRAN_schematicsToHdl" xil_pn:prop_ck="6318242672365869964" xil_pn:start_ts="1600270761">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1600270761" xil_pn:name="TRAN_regenerateCores" xil_pn:prop_ck="-6896205234688070757" xil_pn:start_ts="1600270761">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1600270761" xil_pn:name="TRAN_SubProjectAbstractToPreProxy" xil_pn:start_ts="1600270761">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1600270761" xil_pn:name="TRAN_xawsTohdl" xil_pn:prop_ck="2493898235901227214" xil_pn:start_ts="1600270761">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
</transforms>
</generated_project>
@@ -0,0 +1,106 @@
--------------------------------------------------------------------------------
-- This file is owned and controlled by Xilinx and must be used solely --
-- for design, simulation, implementation and creation of design files --
-- limited to Xilinx devices or technologies. Use with non-Xilinx --
-- devices or technologies is expressly prohibited and immediately --
-- terminates your license. --
-- --
-- XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" SOLELY --
-- FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR XILINX DEVICES. BY --
-- PROVIDING THIS DESIGN, CODE, OR INFORMATION AS ONE POSSIBLE --
-- IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD, XILINX IS --
-- MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE FROM ANY --
-- CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING ANY --
-- RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY --
-- DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE --
-- IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR --
-- REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF --
-- INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A --
-- PARTICULAR PURPOSE. --
-- --
-- Xilinx products are not intended for use in life support appliances, --
-- devices, or systems. Use in such applications are expressly --
-- prohibited. --
-- --
-- (c) Copyright 1995-2020 Xilinx, Inc. --
-- All rights reserved. --
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- You must compile the wrapper file SinCos.vhd when simulating
-- the core, SinCos. When compiling the wrapper file, be sure to
-- reference the XilinxCoreLib VHDL simulation library. For detailed
-- instructions, please refer to the "CORE Generator Help".
-- The synthesis directives "translate_off/translate_on" specified
-- below are supported by Xilinx, Mentor Graphics and Synplicity
-- synthesis tools. Ensure they are correct for your synthesis tool(s).
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- synthesis translate_off
LIBRARY XilinxCoreLib;
-- synthesis translate_on
ENTITY SinCos IS
PORT (
clk : IN STD_LOGIC;
phase_in : IN STD_LOGIC_VECTOR(11 DOWNTO 0);
cosine : OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
sine : OUT STD_LOGIC_VECTOR(15 DOWNTO 0)
);
END SinCos;
ARCHITECTURE SinCos_a OF SinCos IS
-- synthesis translate_off
COMPONENT wrapped_SinCos
PORT (
clk : IN STD_LOGIC;
phase_in : IN STD_LOGIC_VECTOR(11 DOWNTO 0);
cosine : OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
sine : OUT STD_LOGIC_VECTOR(15 DOWNTO 0)
);
END COMPONENT;
-- Configuration specification
FOR ALL : wrapped_SinCos USE ENTITY XilinxCoreLib.dds_compiler_v4_0(behavioral)
GENERIC MAP (
c_accumulator_width => 12,
c_amplitude => 0,
c_channels => 1,
c_has_ce => 0,
c_has_channel_index => 0,
c_has_phase_out => 0,
c_has_phasegen => 0,
c_has_rdy => 0,
c_has_rfd => 0,
c_has_sclr => 0,
c_has_sincos => 1,
c_latency => -1,
c_mem_type => 1,
c_negative_cosine => 0,
c_negative_sine => 0,
c_noise_shaping => 0,
c_optimise_goal => 0,
c_output_width => 16,
c_outputs_required => 2,
c_phase_angle_width => 12,
c_phase_increment => 2,
c_phase_increment_value => "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
c_phase_offset => 0,
c_phase_offset_value => "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0",
c_por_mode => 0,
c_use_dsp48 => 0,
c_xdevicefamily => "spartan6"
);
-- synthesis translate_on
BEGIN
-- synthesis translate_off
U0 : wrapped_SinCos
PORT MAP (
clk => clk,
phase_in => phase_in,
cosine => cosine,
sine => sine
);
-- synthesis translate_on
END SinCos_a;
@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<generated_project xmlns="http://www.xilinx.com/XMLSchema" xmlns:xil_pn="http://www.xilinx.com/XMLSchema">
<!-- -->
<!-- For tool use only. Do not edit. -->
<!-- -->
<!-- ProjectNavigator created generated project file. -->
<!-- For use in tracking generated file and other information -->
<!-- allowing preservation of process status. -->
<!-- -->
<!-- Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved. -->
<version xmlns="http://www.xilinx.com/XMLSchema">11.1</version>
<sourceproject xmlns="http://www.xilinx.com/XMLSchema" xil_pn:fileType="FILE_XISE" xil_pn:name="SweepConfigMem.xise"/>
<files xmlns="http://www.xilinx.com/XMLSchema">
<file xil_pn:fileType="FILE_ASY" xil_pn:name="SweepConfigMem.asy" xil_pn:origination="imported"/>
<file xil_pn:fileType="FILE_SYMBOL" xil_pn:name="SweepConfigMem.sym" xil_pn:origination="imported"/>
<file xil_pn:fileType="FILE_VHO" xil_pn:name="SweepConfigMem.vho" xil_pn:origination="imported"/>
</files>
<transforms xmlns="http://www.xilinx.com/XMLSchema">
<transform xil_pn:end_ts="1588801396" xil_pn:name="TRAN_copyInitialToXSTAbstractSynthesis" xil_pn:start_ts="1588801396">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1600270761" xil_pn:name="TRAN_schematicsToHdl" xil_pn:prop_ck="-4981023380131313696" xil_pn:start_ts="1600270761">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1600270761" xil_pn:name="TRAN_regenerateCores" xil_pn:prop_ck="7428936449477002095" xil_pn:start_ts="1600270761">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1600270761" xil_pn:name="TRAN_SubProjectAbstractToPreProxy" xil_pn:start_ts="1600270761">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1600270761" xil_pn:name="TRAN_xawsTohdl" xil_pn:prop_ck="3308610090153173282" xil_pn:start_ts="1600270761">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
</transforms>
</generated_project>
@@ -0,0 +1,152 @@
--------------------------------------------------------------------------------
-- This file is owned and controlled by Xilinx and must be used solely --
-- for design, simulation, implementation and creation of design files --
-- limited to Xilinx devices or technologies. Use with non-Xilinx --
-- devices or technologies is expressly prohibited and immediately --
-- terminates your license. --
-- --
-- XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" SOLELY --
-- FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR XILINX DEVICES. BY --
-- PROVIDING THIS DESIGN, CODE, OR INFORMATION AS ONE POSSIBLE --
-- IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD, XILINX IS --
-- MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE FROM ANY --
-- CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING ANY --
-- RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY --
-- DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE --
-- IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR --
-- REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF --
-- INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A --
-- PARTICULAR PURPOSE. --
-- --
-- Xilinx products are not intended for use in life support appliances, --
-- devices, or systems. Use in such applications are expressly --
-- prohibited. --
-- --
-- (c) Copyright 1995-2020 Xilinx, Inc. --
-- All rights reserved. --
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- You must compile the wrapper file SweepConfigMem.vhd when simulating
-- the core, SweepConfigMem. When compiling the wrapper file, be sure to
-- reference the XilinxCoreLib VHDL simulation library. For detailed
-- instructions, please refer to the "CORE Generator Help".
-- The synthesis directives "translate_off/translate_on" specified
-- below are supported by Xilinx, Mentor Graphics and Synplicity
-- synthesis tools. Ensure they are correct for your synthesis tool(s).
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- synthesis translate_off
LIBRARY XilinxCoreLib;
-- synthesis translate_on
ENTITY SweepConfigMem IS
PORT (
clka : IN STD_LOGIC;
ena : IN STD_LOGIC;
wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
addra : IN STD_LOGIC_VECTOR(12 DOWNTO 0);
dina : IN STD_LOGIC_VECTOR(95 DOWNTO 0);
clkb : IN STD_LOGIC;
addrb : IN STD_LOGIC_VECTOR(12 DOWNTO 0);
doutb : OUT STD_LOGIC_VECTOR(95 DOWNTO 0)
);
END SweepConfigMem;
ARCHITECTURE SweepConfigMem_a OF SweepConfigMem IS
-- synthesis translate_off
COMPONENT wrapped_SweepConfigMem
PORT (
clka : IN STD_LOGIC;
ena : IN STD_LOGIC;
wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
addra : IN STD_LOGIC_VECTOR(12 DOWNTO 0);
dina : IN STD_LOGIC_VECTOR(95 DOWNTO 0);
clkb : IN STD_LOGIC;
addrb : IN STD_LOGIC_VECTOR(12 DOWNTO 0);
doutb : OUT STD_LOGIC_VECTOR(95 DOWNTO 0)
);
END COMPONENT;
-- Configuration specification
FOR ALL : wrapped_SweepConfigMem USE ENTITY XilinxCoreLib.blk_mem_gen_v7_3(behavioral)
GENERIC MAP (
c_addra_width => 13,
c_addrb_width => 13,
c_algorithm => 1,
c_axi_id_width => 4,
c_axi_slave_type => 0,
c_axi_type => 1,
c_byte_size => 9,
c_common_clk => 0,
c_default_data => "0",
c_disable_warn_bhv_coll => 0,
c_disable_warn_bhv_range => 0,
c_enable_32bit_address => 0,
c_family => "spartan6",
c_has_axi_id => 0,
c_has_ena => 1,
c_has_enb => 0,
c_has_injecterr => 0,
c_has_mem_output_regs_a => 0,
c_has_mem_output_regs_b => 0,
c_has_mux_output_regs_a => 0,
c_has_mux_output_regs_b => 0,
c_has_regcea => 0,
c_has_regceb => 0,
c_has_rsta => 0,
c_has_rstb => 0,
c_has_softecc_input_regs_a => 0,
c_has_softecc_output_regs_b => 0,
c_init_file => "BlankString",
c_init_file_name => "no_coe_file_loaded",
c_inita_val => "0",
c_initb_val => "0",
c_interface_type => 0,
c_load_init_file => 0,
c_mem_type => 1,
c_mux_pipeline_stages => 0,
c_prim_type => 1,
c_read_depth_a => 4501,
c_read_depth_b => 4501,
c_read_width_a => 96,
c_read_width_b => 96,
c_rst_priority_a => "CE",
c_rst_priority_b => "CE",
c_rst_type => "SYNC",
c_rstram_a => 0,
c_rstram_b => 0,
c_sim_collision_check => "ALL",
c_use_bram_block => 0,
c_use_byte_wea => 0,
c_use_byte_web => 0,
c_use_default_data => 0,
c_use_ecc => 0,
c_use_softecc => 0,
c_wea_width => 1,
c_web_width => 1,
c_write_depth_a => 4501,
c_write_depth_b => 4501,
c_write_mode_a => "WRITE_FIRST",
c_write_mode_b => "WRITE_FIRST",
c_write_width_a => 96,
c_write_width_b => 96,
c_xdevicefamily => "spartan6"
);
-- synthesis translate_on
BEGIN
-- synthesis translate_off
U0 : wrapped_SweepConfigMem
PORT MAP (
clka => clka,
ena => ena,
wea => wea,
addra => addra,
dina => dina,
clkb => clkb,
addrb => addrb,
doutb => doutb
);
-- synthesis translate_on
END SweepConfigMem_a;
@@ -0,0 +1,61 @@
################################################################################
#
# (c) Copyright 2002 - 2010 Xilinx, Inc. All rights reserved.
#
# This file contains confidential and proprietary information
# of Xilinx, Inc. and is protected under U.S. and
# international copyright and other intellectual property
# laws.
#
# DISCLAIMER
# This disclaimer is not a license and does not grant any
# rights to the materials distributed herewith. Except as
# otherwise provided in a valid license issued to you by
# Xilinx, and to the maximum extent permitted by applicable
# law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
# WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
# AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
# BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
# INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
# (2) Xilinx shall not be liable (whether in contract or tort,
# including negligence, or under any other theory of
# liability) for any loss or damage of any kind or nature
# related to, arising under or in connection with these
# materials, including for any direct, or any indirect,
# special, incidental, or consequential loss or damage
# (including loss of data, profits, goodwill, or any type of
# loss or damage suffered as a result of any action brought
# by a third party) even if such damage or loss was
# reasonably foreseeable or Xilinx had been advised of the
# possibility of the same.
#
# CRITICAL APPLICATIONS
# Xilinx products are not designed or intended to be fail-
# safe, or for use in any application requiring fail-safe
# performance, such as life-support or safety devices or
# systems, Class III medical devices, nuclear facilities,
# applications related to the deployment of airbags, or any
# other applications that could lead to death, personal
# injury, or severe property or environmental damage
# (individually and collectively, "Critical
# Applications"). Customer assumes the sole risk and
# liability of any use of Xilinx products in Critical
# Applications, subject only to applicable laws and
# regulations governing limitations on product liability.
#
# THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
# PART OF THIS FILE AT ALL TIMES.
#
################################################################################
# Tx Core Period Constraint. This constraint can be modified, and is
# valid as long as it is met after place and route.
NET "CLKA" TNM_NET = "CLKA";
NET "CLKB" TNM_NET = "CLKB";
TIMESPEC "TS_CLKA" = PERIOD "CLKA" 25 MHZ;
TIMESPEC "TS_CLKB" = PERIOD "CLKB" 25 MHZ;
################################################################################
@@ -0,0 +1,182 @@
--------------------------------------------------------------------------------
--
-- BLK MEM GEN v7.1 Core - Top-level core wrapper
--
--------------------------------------------------------------------------------
--
-- (c) Copyright 2006-2010 Xilinx, Inc. All rights reserved.
--
-- This file contains confidential and proprietary information
-- of Xilinx, Inc. and is protected under U.S. and
-- international copyright and other intellectual property
-- laws.
--
-- DISCLAIMER
-- This disclaimer is not a license and does not grant any
-- rights to the materials distributed herewith. Except as
-- otherwise provided in a valid license issued to you by
-- Xilinx, and to the maximum extent permitted by applicable
-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
-- (2) Xilinx shall not be liable (whether in contract or tort,
-- including negligence, or under any other theory of
-- liability) for any loss or damage of any kind or nature
-- related to, arising under or in connection with these
-- materials, including for any direct, or any indirect,
-- special, incidental, or consequential loss or damage
-- (including loss of data, profits, goodwill, or any type of
-- loss or damage suffered as a result of any action brought
-- by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the
-- possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-
-- safe, or for use in any application requiring fail-safe
-- performance, such as life-support or safety devices or
-- systems, Class III medical devices, nuclear facilities,
-- applications related to the deployment of airbags, or any
-- other applications that could lead to death, personal
-- injury, or severe property or environmental damage
-- (individually and collectively, "Critical
-- Applications"). Customer assumes the sole risk and
-- liability of any use of Xilinx products in Critical
-- Applications, subject only to applicable laws and
-- regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
-- PART OF THIS FILE AT ALL TIMES.
--------------------------------------------------------------------------------
--
-- Filename: SweepConfigMem_exdes.vhd
--
-- Description:
-- This is the actual BMG core wrapper.
--
--------------------------------------------------------------------------------
-- Author: IP Solutions Division
--
-- History: August 31, 2005 - First Release
--------------------------------------------------------------------------------
--
--------------------------------------------------------------------------------
-- Library Declarations
--------------------------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
LIBRARY UNISIM;
USE UNISIM.VCOMPONENTS.ALL;
--------------------------------------------------------------------------------
-- Entity Declaration
--------------------------------------------------------------------------------
ENTITY SweepConfigMem_exdes IS
PORT (
--Inputs - Port A
ENA : IN STD_LOGIC; --opt port
WEA : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
ADDRA : IN STD_LOGIC_VECTOR(12 DOWNTO 0);
DINA : IN STD_LOGIC_VECTOR(95 DOWNTO 0);
CLKA : IN STD_LOGIC;
--Inputs - Port B
ADDRB : IN STD_LOGIC_VECTOR(12 DOWNTO 0);
DOUTB : OUT STD_LOGIC_VECTOR(95 DOWNTO 0);
CLKB : IN STD_LOGIC
);
END SweepConfigMem_exdes;
ARCHITECTURE xilinx OF SweepConfigMem_exdes IS
COMPONENT BUFG IS
PORT (
I : IN STD_ULOGIC;
O : OUT STD_ULOGIC
);
END COMPONENT;
COMPONENT SweepConfigMem IS
PORT (
--Port A
ENA : IN STD_LOGIC; --opt port
WEA : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
ADDRA : IN STD_LOGIC_VECTOR(12 DOWNTO 0);
DINA : IN STD_LOGIC_VECTOR(95 DOWNTO 0);
CLKA : IN STD_LOGIC;
--Port B
ADDRB : IN STD_LOGIC_VECTOR(12 DOWNTO 0);
DOUTB : OUT STD_LOGIC_VECTOR(95 DOWNTO 0);
CLKB : IN STD_LOGIC
);
END COMPONENT;
SIGNAL CLKA_buf : STD_LOGIC;
SIGNAL CLKB_buf : STD_LOGIC;
SIGNAL S_ACLK_buf : STD_LOGIC;
BEGIN
bufg_A : BUFG
PORT MAP (
I => CLKA,
O => CLKA_buf
);
bufg_B : BUFG
PORT MAP (
I => CLKB,
O => CLKB_buf
);
bmg0 : SweepConfigMem
PORT MAP (
--Port A
ENA => ENA,
WEA => WEA,
ADDRA => ADDRA,
DINA => DINA,
CLKA => CLKA_buf,
--Port B
ADDRB => ADDRB,
DOUTB => DOUTB,
CLKB => CLKB_buf
);
END xilinx;
@@ -0,0 +1,277 @@
--------------------------------------------------------------------------------
--
-- BLK MEM GEN v7.1 Core - Top-level wrapper
--
--------------------------------------------------------------------------------
--
-- (c) Copyright 2006-2011 Xilinx, Inc. All rights reserved.
--
-- This file contains confidential and proprietary information
-- of Xilinx, Inc. and is protected under U.S. and
-- international copyright and other intellectual property
-- laws.
--
-- DISCLAIMER
-- This disclaimer is not a license and does not grant any
-- rights to the materials distributed herewith. Except as
-- otherwise provided in a valid license issued to you by
-- Xilinx, and to the maximum extent permitted by applicable
-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
-- (2) Xilinx shall not be liable (whether in contract or tort,
-- including negligence, or under any other theory of
-- liability) for any loss or damage of any kind or nature
-- related to, arising under or in connection with these
-- materials, including for any direct, or any indirect,
-- special, incidental, or consequential loss or damage
-- (including loss of data, profits, goodwill, or any type of
-- loss or damage suffered as a result of any action brought
-- by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the
-- possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-
-- safe, or for use in any application requiring fail-safe
-- performance, such as life-support or safety devices or
-- systems, Class III medical devices, nuclear facilities,
-- applications related to the deployment of airbags, or any
-- other applications that could lead to death, personal
-- injury, or severe property or environmental damage
-- (individually and collectively, "Critical
-- Applications"). Customer assumes the sole risk and
-- liability of any use of Xilinx products in Critical
-- Applications, subject only to applicable laws and
-- regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
-- PART OF THIS FILE AT ALL TIMES.
--
--------------------------------------------------------------------------------
--
-- Filename: SweepConfigMem_prod.vhd
--
-- Description:
-- This is the top-level BMG wrapper (over BMG core).
--
--------------------------------------------------------------------------------
-- Author: IP Solutions Division
--
-- History: August 31, 2005 - First Release
--------------------------------------------------------------------------------
--
-- Configured Core Parameter Values:
-- (Refer to the SIM Parameters table in the datasheet for more information on
-- the these parameters.)
-- C_FAMILY : spartan6
-- C_XDEVICEFAMILY : spartan6
-- C_INTERFACE_TYPE : 0
-- C_ENABLE_32BIT_ADDRESS : 0
-- C_AXI_TYPE : 1
-- C_AXI_SLAVE_TYPE : 0
-- C_AXI_ID_WIDTH : 4
-- C_MEM_TYPE : 1
-- C_BYTE_SIZE : 9
-- C_ALGORITHM : 1
-- C_PRIM_TYPE : 1
-- C_LOAD_INIT_FILE : 0
-- C_INIT_FILE_NAME : no_coe_file_loaded
-- C_USE_DEFAULT_DATA : 0
-- C_DEFAULT_DATA : 0
-- C_RST_TYPE : SYNC
-- C_HAS_RSTA : 0
-- C_RST_PRIORITY_A : CE
-- C_RSTRAM_A : 0
-- C_INITA_VAL : 0
-- C_HAS_ENA : 1
-- C_HAS_REGCEA : 0
-- C_USE_BYTE_WEA : 0
-- C_WEA_WIDTH : 1
-- C_WRITE_MODE_A : WRITE_FIRST
-- C_WRITE_WIDTH_A : 96
-- C_READ_WIDTH_A : 96
-- C_WRITE_DEPTH_A : 4501
-- C_READ_DEPTH_A : 4501
-- C_ADDRA_WIDTH : 13
-- C_HAS_RSTB : 0
-- C_RST_PRIORITY_B : CE
-- C_RSTRAM_B : 0
-- C_INITB_VAL : 0
-- C_HAS_ENB : 0
-- C_HAS_REGCEB : 0
-- C_USE_BYTE_WEB : 0
-- C_WEB_WIDTH : 1
-- C_WRITE_MODE_B : WRITE_FIRST
-- C_WRITE_WIDTH_B : 96
-- C_READ_WIDTH_B : 96
-- C_WRITE_DEPTH_B : 4501
-- C_READ_DEPTH_B : 4501
-- C_ADDRB_WIDTH : 13
-- C_HAS_MEM_OUTPUT_REGS_A : 0
-- C_HAS_MEM_OUTPUT_REGS_B : 0
-- C_HAS_MUX_OUTPUT_REGS_A : 0
-- C_HAS_MUX_OUTPUT_REGS_B : 0
-- C_HAS_SOFTECC_INPUT_REGS_A : 0
-- C_HAS_SOFTECC_OUTPUT_REGS_B : 0
-- C_MUX_PIPELINE_STAGES : 0
-- C_USE_ECC : 0
-- C_USE_SOFTECC : 0
-- C_HAS_INJECTERR : 0
-- C_SIM_COLLISION_CHECK : ALL
-- C_COMMON_CLK : 0
-- C_DISABLE_WARN_BHV_COLL : 0
-- C_DISABLE_WARN_BHV_RANGE : 0
--------------------------------------------------------------------------------
-- Library Declarations
--------------------------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
LIBRARY UNISIM;
USE UNISIM.VCOMPONENTS.ALL;
--------------------------------------------------------------------------------
-- Entity Declaration
--------------------------------------------------------------------------------
ENTITY SweepConfigMem_prod IS
PORT (
--Port A
CLKA : IN STD_LOGIC;
RSTA : IN STD_LOGIC; --opt port
ENA : IN STD_LOGIC; --optional port
REGCEA : IN STD_LOGIC; --optional port
WEA : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
ADDRA : IN STD_LOGIC_VECTOR(12 DOWNTO 0);
DINA : IN STD_LOGIC_VECTOR(95 DOWNTO 0);
DOUTA : OUT STD_LOGIC_VECTOR(95 DOWNTO 0);
--Port B
CLKB : IN STD_LOGIC;
RSTB : IN STD_LOGIC; --opt port
ENB : IN STD_LOGIC; --optional port
REGCEB : IN STD_LOGIC; --optional port
WEB : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
ADDRB : IN STD_LOGIC_VECTOR(12 DOWNTO 0);
DINB : IN STD_LOGIC_VECTOR(95 DOWNTO 0);
DOUTB : OUT STD_LOGIC_VECTOR(95 DOWNTO 0);
--ECC
INJECTSBITERR : IN STD_LOGIC; --optional port
INJECTDBITERR : IN STD_LOGIC; --optional port
SBITERR : OUT STD_LOGIC; --optional port
DBITERR : OUT STD_LOGIC; --optional port
RDADDRECC : OUT STD_LOGIC_VECTOR(12 DOWNTO 0); --optional port
-- AXI BMG Input and Output Port Declarations
-- AXI Global Signals
S_ACLK : IN STD_LOGIC;
S_AXI_AWID : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
S_AXI_AWADDR : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
S_AXI_AWLEN : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
S_AXI_AWSIZE : IN STD_LOGIC_VECTOR(2 DOWNTO 0);
S_AXI_AWBURST : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
S_AXI_AWVALID : IN STD_LOGIC;
S_AXI_AWREADY : OUT STD_LOGIC;
S_AXI_WDATA : IN STD_LOGIC_VECTOR(95 DOWNTO 0);
S_AXI_WSTRB : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
S_AXI_WLAST : IN STD_LOGIC;
S_AXI_WVALID : IN STD_LOGIC;
S_AXI_WREADY : OUT STD_LOGIC;
S_AXI_BID : OUT STD_LOGIC_VECTOR(3 DOWNTO 0):= (OTHERS => '0');
S_AXI_BRESP : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
S_AXI_BVALID : OUT STD_LOGIC;
S_AXI_BREADY : IN STD_LOGIC;
-- AXI Full/Lite Slave Read (Write side)
S_AXI_ARID : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
S_AXI_ARADDR : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
S_AXI_ARLEN : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
S_AXI_ARSIZE : IN STD_LOGIC_VECTOR(2 DOWNTO 0);
S_AXI_ARBURST : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
S_AXI_ARVALID : IN STD_LOGIC;
S_AXI_ARREADY : OUT STD_LOGIC;
S_AXI_RID : OUT STD_LOGIC_VECTOR(3 DOWNTO 0):= (OTHERS => '0');
S_AXI_RDATA : OUT STD_LOGIC_VECTOR(95 DOWNTO 0);
S_AXI_RRESP : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
S_AXI_RLAST : OUT STD_LOGIC;
S_AXI_RVALID : OUT STD_LOGIC;
S_AXI_RREADY : IN STD_LOGIC;
-- AXI Full/Lite Sideband Signals
S_AXI_INJECTSBITERR : IN STD_LOGIC;
S_AXI_INJECTDBITERR : IN STD_LOGIC;
S_AXI_SBITERR : OUT STD_LOGIC;
S_AXI_DBITERR : OUT STD_LOGIC;
S_AXI_RDADDRECC : OUT STD_LOGIC_VECTOR(12 DOWNTO 0);
S_ARESETN : IN STD_LOGIC
);
END SweepConfigMem_prod;
ARCHITECTURE xilinx OF SweepConfigMem_prod IS
COMPONENT SweepConfigMem_exdes IS
PORT (
--Port A
ENA : IN STD_LOGIC; --opt port
WEA : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
ADDRA : IN STD_LOGIC_VECTOR(12 DOWNTO 0);
DINA : IN STD_LOGIC_VECTOR(95 DOWNTO 0);
CLKA : IN STD_LOGIC;
--Port B
ADDRB : IN STD_LOGIC_VECTOR(12 DOWNTO 0);
DOUTB : OUT STD_LOGIC_VECTOR(95 DOWNTO 0);
CLKB : IN STD_LOGIC
);
END COMPONENT;
BEGIN
bmg0 : SweepConfigMem_exdes
PORT MAP (
--Port A
ENA => ENA,
WEA => WEA,
ADDRA => ADDRA,
DINA => DINA,
CLKA => CLKA,
--Port B
ADDRB => ADDRB,
DOUTB => DOUTB,
CLKB => CLKB
);
END xilinx;
@@ -0,0 +1,329 @@
--------------------------------------------------------------------------------
--
-- BLK MEM GEN v7_3 Core - Synthesizable Testbench
--
--------------------------------------------------------------------------------
--
-- (c) Copyright 2006_3010 Xilinx, Inc. All rights reserved.
--
-- This file contains confidential and proprietary information
-- of Xilinx, Inc. and is protected under U.S. and
-- international copyright and other intellectual property
-- laws.
--
-- DISCLAIMER
-- This disclaimer is not a license and does not grant any
-- rights to the materials distributed herewith. Except as
-- otherwise provided in a valid license issued to you by
-- Xilinx, and to the maximum extent permitted by applicable
-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
-- (2) Xilinx shall not be liable (whether in contract or tort,
-- including negligence, or under any other theory of
-- liability) for any loss or damage of any kind or nature
-- related to, arising under or in connection with these
-- materials, including for any direct, or any indirect,
-- special, incidental, or consequential loss or damage
-- (including loss of data, profits, goodwill, or any type of
-- loss or damage suffered as a result of any action brought
-- by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the
-- possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-
-- safe, or for use in any application requiring fail-safe
-- performance, such as life-support or safety devices or
-- systems, Class III medical devices, nuclear facilities,
-- applications related to the deployment of airbags, or any
-- other applications that could lead to death, personal
-- injury, or severe property or environmental damage
-- (individually and collectively, "Critical
-- Applications"). Customer assumes the sole risk and
-- liability of any use of Xilinx products in Critical
-- Applications, subject only to applicable laws and
-- regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
-- PART OF THIS FILE AT ALL TIMES.
--------------------------------------------------------------------------------
--
-- Filename: SweepConfigMem_synth.vhd
--
-- Description:
-- Synthesizable Testbench
--------------------------------------------------------------------------------
-- Author: IP Solutions Division
--
-- History: Sep 12, 2011 - First Release
--------------------------------------------------------------------------------
--
--------------------------------------------------------------------------------
-- Library Declarations
--------------------------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.NUMERIC_STD.ALL;
USE IEEE.STD_LOGIC_MISC.ALL;
LIBRARY STD;
USE STD.TEXTIO.ALL;
--LIBRARY unisim;
--USE unisim.vcomponents.ALL;
LIBRARY work;
USE work.ALL;
USE work.BMG_TB_PKG.ALL;
ENTITY SweepConfigMem_synth IS
PORT(
CLK_IN : IN STD_LOGIC;
CLKB_IN : IN STD_LOGIC;
RESET_IN : IN STD_LOGIC;
STATUS : OUT STD_LOGIC_VECTOR(8 DOWNTO 0) := (OTHERS => '0') --ERROR STATUS OUT OF FPGA
);
END ENTITY;
ARCHITECTURE SweepConfigMem_synth_ARCH OF SweepConfigMem_synth IS
COMPONENT SweepConfigMem_exdes
PORT (
--Inputs - Port A
ENA : IN STD_LOGIC; --opt port
WEA : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
ADDRA : IN STD_LOGIC_VECTOR(12 DOWNTO 0);
DINA : IN STD_LOGIC_VECTOR(95 DOWNTO 0);
CLKA : IN STD_LOGIC;
--Inputs - Port B
ADDRB : IN STD_LOGIC_VECTOR(12 DOWNTO 0);
DOUTB : OUT STD_LOGIC_VECTOR(95 DOWNTO 0);
CLKB : IN STD_LOGIC
);
END COMPONENT;
SIGNAL CLKA: STD_LOGIC := '0';
SIGNAL RSTA: STD_LOGIC := '0';
SIGNAL ENA: STD_LOGIC := '0';
SIGNAL ENA_R: STD_LOGIC := '0';
SIGNAL WEA: STD_LOGIC_VECTOR(0 DOWNTO 0) := (OTHERS => '0');
SIGNAL WEA_R: STD_LOGIC_VECTOR(0 DOWNTO 0) := (OTHERS => '0');
SIGNAL ADDRA: STD_LOGIC_VECTOR(12 DOWNTO 0) := (OTHERS => '0');
SIGNAL ADDRA_R: STD_LOGIC_VECTOR(12 DOWNTO 0) := (OTHERS => '0');
SIGNAL DINA: STD_LOGIC_VECTOR(95 DOWNTO 0) := (OTHERS => '0');
SIGNAL DINA_R: STD_LOGIC_VECTOR(95 DOWNTO 0) := (OTHERS => '0');
SIGNAL CLKB: STD_LOGIC := '0';
SIGNAL RSTB: STD_LOGIC := '0';
SIGNAL ADDRB: STD_LOGIC_VECTOR(12 DOWNTO 0) := (OTHERS => '0');
SIGNAL ADDRB_R: STD_LOGIC_VECTOR(12 DOWNTO 0) := (OTHERS => '0');
SIGNAL DOUTB: STD_LOGIC_VECTOR(95 DOWNTO 0);
SIGNAL CHECKER_EN : STD_LOGIC:='0';
SIGNAL CHECKER_EN_R : STD_LOGIC:='0';
SIGNAL STIMULUS_FLOW : STD_LOGIC_VECTOR(22 DOWNTO 0) := (OTHERS =>'0');
SIGNAL clk_in_i: STD_LOGIC;
SIGNAL RESET_SYNC_R1 : STD_LOGIC:='1';
SIGNAL RESET_SYNC_R2 : STD_LOGIC:='1';
SIGNAL RESET_SYNC_R3 : STD_LOGIC:='1';
SIGNAL clkb_in_i: STD_LOGIC;
SIGNAL RESETB_SYNC_R1 : STD_LOGIC := '1';
SIGNAL RESETB_SYNC_R2 : STD_LOGIC := '1';
SIGNAL RESETB_SYNC_R3 : STD_LOGIC := '1';
SIGNAL ITER_R0 : STD_LOGIC := '0';
SIGNAL ITER_R1 : STD_LOGIC := '0';
SIGNAL ITER_R2 : STD_LOGIC := '0';
SIGNAL ISSUE_FLAG : STD_LOGIC_VECTOR(7 DOWNTO 0) := (OTHERS => '0');
SIGNAL ISSUE_FLAG_STATUS : STD_LOGIC_VECTOR(7 DOWNTO 0) := (OTHERS => '0');
BEGIN
-- clk_buf: bufg
-- PORT map(
-- i => CLK_IN,
-- o => clk_in_i
-- );
clk_in_i <= CLK_IN;
CLKA <= clk_in_i;
-- clkb_buf: bufg
-- PORT map(
-- i => CLKB_IN,
-- o => clkb_in_i
-- );
clkb_in_i <= CLKB_IN;
CLKB <= clkb_in_i;
RSTA <= RESET_SYNC_R3 AFTER 50 ns;
PROCESS(clk_in_i)
BEGIN
IF(RISING_EDGE(clk_in_i)) THEN
RESET_SYNC_R1 <= RESET_IN;
RESET_SYNC_R2 <= RESET_SYNC_R1;
RESET_SYNC_R3 <= RESET_SYNC_R2;
END IF;
END PROCESS;
RSTB <= RESETB_SYNC_R3 AFTER 50 ns;
PROCESS(clkb_in_i)
BEGIN
IF(RISING_EDGE(clkb_in_i)) THEN
RESETB_SYNC_R1 <= RESET_IN;
RESETB_SYNC_R2 <= RESETB_SYNC_R1;
RESETB_SYNC_R3 <= RESETB_SYNC_R2;
END IF;
END PROCESS;
PROCESS(CLKA)
BEGIN
IF(RISING_EDGE(CLKA)) THEN
IF(RESET_SYNC_R3='1') THEN
ISSUE_FLAG_STATUS<= (OTHERS => '0');
ELSE
ISSUE_FLAG_STATUS <= ISSUE_FLAG_STATUS OR ISSUE_FLAG;
END IF;
END IF;
END PROCESS;
STATUS(7 DOWNTO 0) <= ISSUE_FLAG_STATUS;
BMG_DATA_CHECKER_INST: ENTITY work.CHECKER
GENERIC MAP (
WRITE_WIDTH => 96,
READ_WIDTH => 96 )
PORT MAP (
CLK => clkb_in_i,
RST => RSTB,
EN => CHECKER_EN_R,
DATA_IN => DOUTB,
STATUS => ISSUE_FLAG(0)
);
PROCESS(clkb_in_i)
BEGIN
IF(RISING_EDGE(clkb_in_i)) THEN
IF(RSTB='1') THEN
CHECKER_EN_R <= '0';
ELSE
CHECKER_EN_R <= CHECKER_EN AFTER 50 ns;
END IF;
END IF;
END PROCESS;
BMG_STIM_GEN_INST:ENTITY work.BMG_STIM_GEN
PORT MAP(
CLKA => clk_in_i,
CLKB => clkb_in_i,
TB_RST => RSTA,
ADDRA => ADDRA,
DINA => DINA,
ENA => ENA,
WEA => WEA,
ADDRB => ADDRB,
CHECK_DATA => CHECKER_EN
);
PROCESS(CLKA)
BEGIN
IF(RISING_EDGE(CLKA)) THEN
IF(RESET_SYNC_R3='1') THEN
STATUS(8) <= '0';
iter_r2 <= '0';
iter_r1 <= '0';
iter_r0 <= '0';
ELSE
STATUS(8) <= iter_r2;
iter_r2 <= iter_r1;
iter_r1 <= iter_r0;
iter_r0 <= STIMULUS_FLOW(8);
END IF;
END IF;
END PROCESS;
PROCESS(CLKA)
BEGIN
IF(RISING_EDGE(CLKA)) THEN
IF(RESET_SYNC_R3='1') THEN
STIMULUS_FLOW <= (OTHERS => '0');
ELSIF(WEA(0)='1') THEN
STIMULUS_FLOW <= STIMULUS_FLOW+1;
END IF;
END IF;
END PROCESS;
PROCESS(CLKA)
BEGIN
IF(RISING_EDGE(CLKA)) THEN
IF(RESET_SYNC_R3='1') THEN
ENA_R <= '0' AFTER 50 ns;
WEA_R <= (OTHERS=>'0') AFTER 50 ns;
DINA_R <= (OTHERS=>'0') AFTER 50 ns;
ELSE
ENA_R <= ENA AFTER 50 ns;
WEA_R <= WEA AFTER 50 ns;
DINA_R <= DINA AFTER 50 ns;
END IF;
END IF;
END PROCESS;
PROCESS(CLKA)
BEGIN
IF(RISING_EDGE(CLKA)) THEN
IF(RESET_SYNC_R3='1') THEN
ADDRA_R <= (OTHERS=> '0') AFTER 50 ns;
ADDRB_R <= (OTHERS=> '0') AFTER 50 ns;
ELSE
ADDRA_R <= ADDRA AFTER 50 ns;
ADDRB_R <= ADDRB AFTER 50 ns;
END IF;
END IF;
END PROCESS;
BMG_PORT: SweepConfigMem_exdes PORT MAP (
--Port A
ENA => ENA_R,
WEA => WEA_R,
ADDRA => ADDRA_R,
DINA => DINA_R,
CLKA => CLKA,
--Port B
ADDRB => ADDRB_R,
DOUTB => DOUTB,
CLKB => CLKB
);
END ARCHITECTURE;
@@ -0,0 +1,142 @@
--------------------------------------------------------------------------------
--
-- BLK MEM GEN v7_3 Core - Top File for the Example Testbench
--
--------------------------------------------------------------------------------
--
-- (c) Copyright 2006_3010 Xilinx, Inc. All rights reserved.
--
-- This file contains confidential and proprietary information
-- of Xilinx, Inc. and is protected under U.S. and
-- international copyright and other intellectual property
-- laws.
--
-- DISCLAIMER
-- This disclaimer is not a license and does not grant any
-- rights to the materials distributed herewith. Except as
-- otherwise provided in a valid license issued to you by
-- Xilinx, and to the maximum extent permitted by applicable
-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
-- (2) Xilinx shall not be liable (whether in contract or tort,
-- including negligence, or under any other theory of
-- liability) for any loss or damage of any kind or nature
-- related to, arising under or in connection with these
-- materials, including for any direct, or any indirect,
-- special, incidental, or consequential loss or damage
-- (including loss of data, profits, goodwill, or any type of
-- loss or damage suffered as a result of any action brought
-- by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the
-- possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-
-- safe, or for use in any application requiring fail-safe
-- performance, such as life-support or safety devices or
-- systems, Class III medical devices, nuclear facilities,
-- applications related to the deployment of airbags, or any
-- other applications that could lead to death, personal
-- injury, or severe property or environmental damage
-- (individually and collectively, "Critical
-- Applications"). Customer assumes the sole risk and
-- liability of any use of Xilinx products in Critical
-- Applications, subject only to applicable laws and
-- regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
-- PART OF THIS FILE AT ALL TIMES.
--------------------------------------------------------------------------------
-- Filename: SweepConfigMem_tb.vhd
-- Description:
-- Testbench Top
--------------------------------------------------------------------------------
-- Author: IP Solutions Division
--
-- History: Sep 12, 2011 - First Release
--------------------------------------------------------------------------------
--
--------------------------------------------------------------------------------
-- Library Declarations
--------------------------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
LIBRARY work;
USE work.ALL;
ENTITY SweepConfigMem_tb IS
END ENTITY;
ARCHITECTURE SweepConfigMem_tb_ARCH OF SweepConfigMem_tb IS
SIGNAL STATUS : STD_LOGIC_VECTOR(8 DOWNTO 0);
SIGNAL CLK : STD_LOGIC := '1';
SIGNAL CLKB : STD_LOGIC := '1';
SIGNAL RESET : STD_LOGIC;
BEGIN
CLK_GEN: PROCESS BEGIN
CLK <= NOT CLK;
WAIT FOR 100 NS;
CLK <= NOT CLK;
WAIT FOR 100 NS;
END PROCESS;
CLKB_GEN: PROCESS BEGIN
CLKB <= NOT CLKB;
WAIT FOR 100 NS;
CLKB <= NOT CLKB;
WAIT FOR 100 NS;
END PROCESS;
RST_GEN: PROCESS BEGIN
RESET <= '1';
WAIT FOR 1000 NS;
RESET <= '0';
WAIT;
END PROCESS;
--STOP_SIM: PROCESS BEGIN
-- WAIT FOR 200 US; -- STOP SIMULATION AFTER 1 MS
-- ASSERT FALSE
-- REPORT "END SIMULATION TIME REACHED"
-- SEVERITY FAILURE;
--END PROCESS;
--
PROCESS BEGIN
WAIT UNTIL STATUS(8)='1';
IF( STATUS(7 downto 0)/="0") THEN
ASSERT false
REPORT "Test Completed Successfully"
SEVERITY NOTE;
REPORT "Simulation Failed"
SEVERITY FAILURE;
ELSE
ASSERT false
REPORT "TEST PASS"
SEVERITY NOTE;
REPORT "Test Completed Successfully"
SEVERITY FAILURE;
END IF;
END PROCESS;
SweepConfigMem_synth_inst:ENTITY work.SweepConfigMem_synth
PORT MAP(
CLK_IN => CLK,
CLKB_IN => CLK,
RESET_IN => RESET,
STATUS => STATUS
);
END ARCHITECTURE;
@@ -0,0 +1,117 @@
--------------------------------------------------------------------------------
--
-- BLK MEM GEN v7_3 Core - Address Generator
--
--------------------------------------------------------------------------------
--
-- (c) Copyright 2006_3010 Xilinx, Inc. All rights reserved.
--
-- This file contains confidential and proprietary information
-- of Xilinx, Inc. and is protected under U.S. and
-- international copyright and other intellectual property
-- laws.
--
-- DISCLAIMER
-- This disclaimer is not a license and does not grant any
-- rights to the materials distributed herewith. Except as
-- otherwise provided in a valid license issued to you by
-- Xilinx, and to the maximum extent permitted by applicable
-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
-- (2) Xilinx shall not be liable (whether in contract or tort,
-- including negligence, or under any other theory of
-- liability) for any loss or damage of any kind or nature
-- related to, arising under or in connection with these
-- materials, including for any direct, or any indirect,
-- special, incidental, or consequential loss or damage
-- (including loss of data, profits, goodwill, or any type of
-- loss or damage suffered as a result of any action brought
-- by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the
-- possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-
-- safe, or for use in any application requiring fail-safe
-- performance, such as life-support or safety devices or
-- systems, Class III medical devices, nuclear facilities,
-- applications related to the deployment of airbags, or any
-- other applications that could lead to death, personal
-- injury, or severe property or environmental damage
-- (individually and collectively, "Critical
-- Applications"). Customer assumes the sole risk and
-- liability of any use of Xilinx products in Critical
-- Applications, subject only to applicable laws and
-- regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
-- PART OF THIS FILE AT ALL TIMES.
--------------------------------------------------------------------------------
--
-- Filename: addr_gen.vhd
--
-- Description:
-- Address Generator
--
--------------------------------------------------------------------------------
-- Author: IP Solutions Division
--
-- History: Sep 12, 2011 - First Release
--------------------------------------------------------------------------------
--
--------------------------------------------------------------------------------
-- Library Declarations
--------------------------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
LIBRARY work;
USE work.ALL;
ENTITY ADDR_GEN IS
GENERIC ( C_MAX_DEPTH : INTEGER := 1024 ;
RST_VALUE : STD_LOGIC_VECTOR(31 DOWNTO 0) := (OTHERS=> '0');
RST_INC : INTEGER := 0);
PORT (
CLK : IN STD_LOGIC;
RST : IN STD_LOGIC;
EN : IN STD_LOGIC;
LOAD :IN STD_LOGIC;
LOAD_VALUE : IN STD_LOGIC_VECTOR (31 DOWNTO 0) := (OTHERS => '0');
ADDR_OUT : OUT STD_LOGIC_VECTOR (31 DOWNTO 0) --OUTPUT VECTOR
);
END ADDR_GEN;
ARCHITECTURE BEHAVIORAL OF ADDR_GEN IS
SIGNAL ADDR_TEMP : STD_LOGIC_VECTOR(31 DOWNTO 0) := (OTHERS =>'0');
BEGIN
ADDR_OUT <= ADDR_TEMP;
PROCESS(CLK)
BEGIN
IF(RISING_EDGE(CLK)) THEN
IF(RST='1') THEN
ADDR_TEMP<= RST_VALUE + conv_std_logic_vector(RST_INC,32 );
ELSE
IF(EN='1') THEN
IF(LOAD='1') THEN
ADDR_TEMP <=LOAD_VALUE;
ELSE
IF(ADDR_TEMP = C_MAX_DEPTH-1) THEN
ADDR_TEMP<= RST_VALUE + conv_std_logic_vector(RST_INC,32 );
ELSE
ADDR_TEMP <= ADDR_TEMP + '1';
END IF;
END IF;
END IF;
END IF;
END IF;
END PROCESS;
END ARCHITECTURE;
@@ -0,0 +1,436 @@
--------------------------------------------------------------------------------
--
-- BLK MEM GEN v7_3 Core - Stimulus Generator For Simple Dual Port RAM
--
--------------------------------------------------------------------------------
--
-- (c) Copyright 2006_3010 Xilinx, Inc. All rights reserved.
--
-- This file contains confidential and proprietary information
-- of Xilinx, Inc. and is protected under U.S. and
-- international copyright and other intellectual property
-- laws.
--
-- DISCLAIMER
-- This disclaimer is not a license and does not grant any
-- rights to the materials distributed herewith. Except as
-- otherwise provided in a valid license issued to you by
-- Xilinx, and to the maximum extent permitted by applicable
-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
-- (2) Xilinx shall not be liable (whether in contract or tort,
-- including negligence, or under any other theory of
-- liability) for any loss or damage of any kind or nature
-- related to, arising under or in connection with these
-- materials, including for any direct, or any indirect,
-- special, incidental, or consequential loss or damage
-- (including loss of data, profits, goodwill, or any type of
-- loss or damage suffered as a result of any action brought
-- by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the
-- possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-
-- safe, or for use in any application requiring fail-safe
-- performance, such as life-support or safety devices or
-- systems, Class III medical devices, nuclear facilities,
-- applications related to the deployment of airbags, or any
-- other applications that could lead to death, personal
-- injury, or severe property or environmental damage
-- (individually and collectively, "Critical
-- Applications"). Customer assumes the sole risk and
-- liability of any use of Xilinx products in Critical
-- Applications, subject only to applicable laws and
-- regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
-- PART OF THIS FILE AT ALL TIMES.
--------------------------------------------------------------------------------
--
-- Filename: bmg_stim_gen.vhd
--
-- Description:
-- Stimulus Generation For SDP Configuration
-- 100 Writes and 100 Reads will be performed in a repeatitive loop till the
-- simulation ends
--
--------------------------------------------------------------------------------
-- Author: IP Solutions Division
--
-- History: Sep 12, 2011 - First Release
--------------------------------------------------------------------------------
--
--------------------------------------------------------------------------------
-- Library Declarations
--------------------------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.STD_LOGIC_MISC.ALL;
LIBRARY work;
USE work.ALL;
USE work.BMG_TB_PKG.ALL;
ENTITY REGISTER_LOGIC IS
PORT(
Q : OUT STD_LOGIC;
CLK : IN STD_LOGIC;
RST : IN STD_LOGIC;
D : IN STD_LOGIC
);
END REGISTER_LOGIC;
ARCHITECTURE REGISTER_ARCH OF REGISTER_LOGIC IS
SIGNAL Q_O : STD_LOGIC :='0';
BEGIN
Q <= Q_O;
FF_BEH: PROCESS(CLK)
BEGIN
IF(RISING_EDGE(CLK)) THEN
IF(RST ='1') THEN
Q_O <= '0';
ELSE
Q_O <= D;
END IF;
END IF;
END PROCESS;
END REGISTER_ARCH;
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.STD_LOGIC_MISC.ALL;
LIBRARY work;
USE work.ALL;
USE work.BMG_TB_PKG.ALL;
ENTITY BMG_STIM_GEN IS
PORT (
CLKA : IN STD_LOGIC;
CLKB : IN STD_LOGIC;
TB_RST : IN STD_LOGIC;
ADDRA: OUT STD_LOGIC_VECTOR(12 DOWNTO 0) := (OTHERS => '0');
DINA : OUT STD_LOGIC_VECTOR(95 DOWNTO 0) := (OTHERS => '0');
ENA : OUT STD_LOGIC :='0';
WEA : OUT STD_LOGIC_VECTOR (0 DOWNTO 0) := (OTHERS => '0');
ADDRB: OUT STD_LOGIC_VECTOR(12 DOWNTO 0) := (OTHERS => '0');
CHECK_DATA: OUT STD_LOGIC:='0'
);
END BMG_STIM_GEN;
ARCHITECTURE BEHAVIORAL OF BMG_STIM_GEN IS
CONSTANT ZERO : STD_LOGIC_VECTOR(31 DOWNTO 0) := (OTHERS => '0');
SIGNAL WRITE_ADDR : STD_LOGIC_VECTOR(31 DOWNTO 0) := (OTHERS => '0');
SIGNAL READ_ADDR : STD_LOGIC_VECTOR(31 DOWNTO 0) := (OTHERS => '0');
SIGNAL DINA_INT : STD_LOGIC_VECTOR(95 DOWNTO 0) := (OTHERS => '0');
SIGNAL DO_WRITE : STD_LOGIC := '0';
SIGNAL DO_READ : STD_LOGIC := '0';
SIGNAL DO_READ_R : STD_LOGIC := '0';
SIGNAL DO_READ_REG : STD_LOGIC_VECTOR(5 DOWNTO 0) :=(OTHERS => '0');
SIGNAL PORTA_WR : STD_LOGIC:='0';
SIGNAL COUNT : INTEGER :=0;
SIGNAL INCR_WR_CNT : STD_LOGIC:='0';
SIGNAL PORTA_WR_COMPLETE : STD_LOGIC :='0';
SIGNAL PORTB_RD : STD_LOGIC:='0';
SIGNAL COUNT_RD : INTEGER :=0;
SIGNAL INCR_RD_CNT : STD_LOGIC:='0';
SIGNAL PORTB_RD_COMPLETE : STD_LOGIC :='0';
SIGNAL LATCH_PORTA_WR_COMPLETE : STD_LOGIC :='0';
SIGNAL PORTB_RD_HAPPENED : STD_LOGIC := '0';
SIGNAL PORTA_WR_L1 :STD_LOGIC := '0';
SIGNAL PORTA_WR_L2 :STD_LOGIC := '0';
SIGNAL PORTB_RD_R2 :STD_LOGIC := '0';
SIGNAL PORTB_RD_R1 :STD_LOGIC := '0';
SIGNAL LATCH_PORTB_RD_COMPLETE : STD_LOGIC :='0';
SIGNAL PORTA_WR_HAPPENED : STD_LOGIC := '0';
SIGNAL PORTB_RD_L1 : STD_LOGIC := '0';
SIGNAL PORTB_RD_L2 : STD_LOGIC := '0';
SIGNAL PORTA_WR_R2 : STD_LOGIC := '0';
SIGNAL PORTA_WR_R1 : STD_LOGIC := '0';
CONSTANT WR_RD_DEEP_COUNT :INTEGER :=8;
CONSTANT WR_DEEP_COUNT : INTEGER := if_then_else((13 <= 13),WR_RD_DEEP_COUNT,
((96/96)*WR_RD_DEEP_COUNT));
CONSTANT RD_DEEP_COUNT : INTEGER := if_then_else((13 <= 13),WR_RD_DEEP_COUNT,
((96/96)*WR_RD_DEEP_COUNT));
BEGIN
ADDRA <= WRITE_ADDR(12 DOWNTO 0) ;
DINA <= DINA_INT ;
ADDRB <= READ_ADDR(12 DOWNTO 0) when (DO_READ='1') else (OTHERS=>'0');
CHECK_DATA <= DO_READ;
RD_ADDR_GEN_INST:ENTITY work.ADDR_GEN
GENERIC MAP(
C_MAX_DEPTH => 4501 ,
RST_INC => 1 )
PORT MAP(
CLK => CLKB,
RST => TB_RST,
EN => DO_READ,
LOAD => '0',
LOAD_VALUE => ZERO,
ADDR_OUT => READ_ADDR
);
WR_ADDR_GEN_INST:ENTITY work.ADDR_GEN
GENERIC MAP(
C_MAX_DEPTH => 4501,
RST_INC => 1 )
PORT MAP(
CLK => CLKA,
RST => TB_RST,
EN => DO_WRITE,
LOAD => '0',
LOAD_VALUE => ZERO,
ADDR_OUT => WRITE_ADDR
);
WR_DATA_GEN_INST:ENTITY work.DATA_GEN
GENERIC MAP (
DATA_GEN_WIDTH => 96,
DOUT_WIDTH => 96 ,
DATA_PART_CNT => 1,
SEED => 2)
PORT MAP (
CLK => CLKA,
RST => TB_RST,
EN => DO_WRITE,
DATA_OUT => DINA_INT
);
PORTA_WR_PROCESS: PROCESS(CLKA)
BEGIN
IF(RISING_EDGE(CLKA)) THEN
IF(TB_RST='1') THEN
PORTA_WR<='1';
ELSE
PORTA_WR<=PORTB_RD_COMPLETE;
END IF;
END IF;
END PROCESS;
PORTB_RD_PROCESS: PROCESS(CLKB)
BEGIN
IF(RISING_EDGE(CLKB)) THEN
IF(TB_RST='1') THEN
PORTB_RD<='0';
ELSE
PORTB_RD<=PORTA_WR_L2;
END IF;
END IF;
END PROCESS;
PORTB_RD_COMPLETE_LATCH: PROCESS(CLKB)
BEGIN
IF(RISING_EDGE(CLKB)) THEN
IF(TB_RST='1') THEN
LATCH_PORTB_RD_COMPLETE<='0';
ELSIF(PORTB_RD_COMPLETE='1') THEN
LATCH_PORTB_RD_COMPLETE <='1';
ELSIF(PORTA_WR_HAPPENED='1') THEN
LATCH_PORTB_RD_COMPLETE<='0';
END IF;
END IF;
END PROCESS;
PROCESS(CLKA)
BEGIN
IF(RISING_EDGE(CLKA)) THEN
IF(TB_RST='1') THEN
PORTB_RD_L1 <='0';
PORTB_RD_L2 <='0';
ELSE
PORTB_RD_L1 <= LATCH_PORTB_RD_COMPLETE;
PORTB_RD_L2 <= PORTB_RD_L1;
END IF;
END IF;
END PROCESS;
PROCESS(CLKB)
BEGIN
IF(RISING_EDGE(CLKB)) THEN
IF(TB_RST='1') THEN
PORTA_WR_R1 <='0';
PORTA_WR_R2 <='0';
ELSE
PORTA_WR_R1 <= PORTA_WR;
PORTA_WR_R2 <= PORTA_WR_R1;
END IF;
END IF;
END PROCESS;
PORTA_WR_HAPPENED <= PORTA_WR_R2;
PORTA_WR_COMPLETE_LATCH: PROCESS(CLKA)
BEGIN
IF(RISING_EDGE(CLKA)) THEN
IF(TB_RST='1') THEN
LATCH_PORTA_WR_COMPLETE<='0';
ELSIF(PORTA_WR_COMPLETE='1') THEN
LATCH_PORTA_WR_COMPLETE <='1';
--ELSIF(PORTB_RD_HAPPENED='1') THEN
ELSE
LATCH_PORTA_WR_COMPLETE<='0';
END IF;
END IF;
END PROCESS;
PROCESS(CLKB)
BEGIN
IF(RISING_EDGE(CLKB)) THEN
IF(TB_RST='1') THEN
PORTA_WR_L1 <='0';
PORTA_WR_L2 <='0';
ELSE
PORTA_WR_L1 <= LATCH_PORTA_WR_COMPLETE;
PORTA_WR_L2 <= PORTA_WR_L1;
END IF;
END IF;
END PROCESS;
PROCESS(CLKA)
BEGIN
IF(RISING_EDGE(CLKA)) THEN
IF(TB_RST='1') THEN
PORTB_RD_R1 <='0';
PORTB_RD_R2 <='0';
ELSE
PORTB_RD_R1 <= PORTB_RD;
PORTB_RD_R2 <= PORTB_RD_R1;
END IF;
END IF;
END PROCESS;
PORTB_RD_HAPPENED <= PORTB_RD_R2;
PORTB_RD_COMPLETE <= '1' when (count_rd=RD_DEEP_COUNT) else '0';
start_rd_counter: process(clkb)
begin
if(rising_edge(clkb)) then
if(tb_rst='1') then
incr_rd_cnt <= '0';
elsif(portb_rd ='1') then
incr_rd_cnt <='1';
elsif(portb_rd_complete='1') then
incr_rd_cnt <='0';
end if;
end if;
end process;
RD_COUNTER: process(clkb)
begin
if(rising_edge(clkb)) then
if(tb_rst='1') then
count_rd <= 0;
elsif(incr_rd_cnt='1') then
count_rd<=count_rd+1;
end if;
--if(count_rd=(wr_rd_deep_count)) then
if(count_rd=(RD_DEEP_COUNT)) then
count_rd<=0;
end if;
end if;
end process;
DO_READ<='1' when (count_rd <RD_DEEP_COUNT and incr_rd_cnt='1') else '0';
PORTA_WR_COMPLETE <= '1' when (count=WR_DEEP_COUNT) else '0';
start_counter: process(clka)
begin
if(rising_edge(clka)) then
if(tb_rst='1') then
incr_wr_cnt <= '0';
elsif(porta_wr ='1') then
incr_wr_cnt <='1';
elsif(porta_wr_complete='1') then
incr_wr_cnt <='0';
end if;
end if;
end process;
COUNTER: process(clka)
begin
if(rising_edge(clka)) then
if(tb_rst='1') then
count <= 0;
elsif(incr_wr_cnt='1') then
count<=count+1;
end if;
if(count=(WR_DEEP_COUNT)) then
count<=0;
end if;
end if;
end process;
DO_WRITE<='1' when (count <WR_DEEP_COUNT and incr_wr_cnt='1') else '0';
BEGIN_SHIFT_REG: FOR I IN 0 TO 5 GENERATE
BEGIN
DFF_RIGHT: IF I=0 GENERATE
BEGIN
SHIFT_INST_0: ENTITY work.REGISTER_LOGIC
PORT MAP(
Q => DO_READ_REG(0),
CLK => CLKB,
RST => TB_RST,
D => DO_READ
);
END GENERATE DFF_RIGHT;
DFF_OTHERS: IF ((I>0) AND (I<=5)) GENERATE
BEGIN
SHIFT_INST: ENTITY work.REGISTER_LOGIC
PORT MAP(
Q => DO_READ_REG(I),
CLK =>CLKB,
RST =>TB_RST,
D =>DO_READ_REG(I-1)
);
END GENERATE DFF_OTHERS;
END GENERATE BEGIN_SHIFT_REG;
REGCE_PROCESS: PROCESS(CLKB)
BEGIN
IF(RISING_EDGE(CLKB)) THEN
IF(TB_RST='1') THEN
DO_READ_R <= '0';
ELSE
DO_READ_R <= DO_READ;
END IF;
END IF;
END PROCESS;
ENA <= DO_WRITE ;
WEA(0) <= DO_WRITE ;
END ARCHITECTURE;
@@ -0,0 +1,200 @@
--------------------------------------------------------------------------------
--
-- BLK MEM GEN v7_3 Core - Testbench Package
--
--------------------------------------------------------------------------------
--
-- (c) Copyright 2006_3010 Xilinx, Inc. All rights reserved.
--
-- This file contains confidential and proprietary information
-- of Xilinx, Inc. and is protected under U.S. and
-- international copyright and other intellectual property
-- laws.
--
-- DISCLAIMER
-- This disclaimer is not a license and does not grant any
-- rights to the materials distributed herewith. Except as
-- otherwise provided in a valid license issued to you by
-- Xilinx, and to the maximum extent permitted by applicable
-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
-- (2) Xilinx shall not be liable (whether in contract or tort,
-- including negligence, or under any other theory of
-- liability) for any loss or damage of any kind or nature
-- related to, arising under or in connection with these
-- materials, including for any direct, or any indirect,
-- special, incidental, or consequential loss or damage
-- (including loss of data, profits, goodwill, or any type of
-- loss or damage suffered as a result of any action brought
-- by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the
-- possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-
-- safe, or for use in any application requiring fail-safe
-- performance, such as life-support or safety devices or
-- systems, Class III medical devices, nuclear facilities,
-- applications related to the deployment of airbags, or any
-- other applications that could lead to death, personal
-- injury, or severe property or environmental damage
-- (individually and collectively, "Critical
-- Applications"). Customer assumes the sole risk and
-- liability of any use of Xilinx products in Critical
-- Applications, subject only to applicable laws and
-- regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
-- PART OF THIS FILE AT ALL TIMES.
--------------------------------------------------------------------------------
--
-- Filename: bmg_tb_pkg.vhd
--
-- Description:
-- BMG Testbench Package files
--
--------------------------------------------------------------------------------
-- Author: IP Solutions Division
--
-- History: Sep 12, 2011 - First Release
--------------------------------------------------------------------------------
--
--------------------------------------------------------------------------------
-- Library Declarations
--------------------------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
PACKAGE BMG_TB_PKG IS
FUNCTION DIVROUNDUP (
DATA_VALUE : INTEGER;
DIVISOR : INTEGER)
RETURN INTEGER;
------------------------
FUNCTION IF_THEN_ELSE (
CONDITION : BOOLEAN;
TRUE_CASE : STD_LOGIC_VECTOR;
FALSE_CASE : STD_LOGIC_VECTOR)
RETURN STD_LOGIC_VECTOR;
------------------------
FUNCTION IF_THEN_ELSE (
CONDITION : BOOLEAN;
TRUE_CASE : STRING;
FALSE_CASE :STRING)
RETURN STRING;
------------------------
FUNCTION IF_THEN_ELSE (
CONDITION : BOOLEAN;
TRUE_CASE : STD_LOGIC;
FALSE_CASE :STD_LOGIC)
RETURN STD_LOGIC;
------------------------
FUNCTION IF_THEN_ELSE (
CONDITION : BOOLEAN;
TRUE_CASE : INTEGER;
FALSE_CASE : INTEGER)
RETURN INTEGER;
------------------------
FUNCTION LOG2ROUNDUP (
DATA_VALUE : INTEGER)
RETURN INTEGER;
END BMG_TB_PKG;
PACKAGE BODY BMG_TB_PKG IS
FUNCTION DIVROUNDUP (
DATA_VALUE : INTEGER;
DIVISOR : INTEGER)
RETURN INTEGER IS
VARIABLE DIV : INTEGER;
BEGIN
DIV := DATA_VALUE/DIVISOR;
IF ( (DATA_VALUE MOD DIVISOR) /= 0) THEN
DIV := DIV+1;
END IF;
RETURN DIV;
END DIVROUNDUP;
---------------------------------
FUNCTION IF_THEN_ELSE (
CONDITION : BOOLEAN;
TRUE_CASE : STD_LOGIC_VECTOR;
FALSE_CASE : STD_LOGIC_VECTOR)
RETURN STD_LOGIC_VECTOR IS
BEGIN
IF NOT CONDITION THEN
RETURN FALSE_CASE;
ELSE
RETURN TRUE_CASE;
END IF;
END IF_THEN_ELSE;
---------------------------------
FUNCTION IF_THEN_ELSE (
CONDITION : BOOLEAN;
TRUE_CASE : STD_LOGIC;
FALSE_CASE : STD_LOGIC)
RETURN STD_LOGIC IS
BEGIN
IF NOT CONDITION THEN
RETURN FALSE_CASE;
ELSE
RETURN TRUE_CASE;
END IF;
END IF_THEN_ELSE;
---------------------------------
FUNCTION IF_THEN_ELSE (
CONDITION : BOOLEAN;
TRUE_CASE : INTEGER;
FALSE_CASE : INTEGER)
RETURN INTEGER IS
VARIABLE RETVAL : INTEGER := 0;
BEGIN
IF CONDITION=FALSE THEN
RETVAL:=FALSE_CASE;
ELSE
RETVAL:=TRUE_CASE;
END IF;
RETURN RETVAL;
END IF_THEN_ELSE;
---------------------------------
FUNCTION IF_THEN_ELSE (
CONDITION : BOOLEAN;
TRUE_CASE : STRING;
FALSE_CASE : STRING)
RETURN STRING IS
BEGIN
IF NOT CONDITION THEN
RETURN FALSE_CASE;
ELSE
RETURN TRUE_CASE;
END IF;
END IF_THEN_ELSE;
-------------------------------
FUNCTION LOG2ROUNDUP (
DATA_VALUE : INTEGER)
RETURN INTEGER IS
VARIABLE WIDTH : INTEGER := 0;
VARIABLE CNT : INTEGER := 1;
BEGIN
IF (DATA_VALUE <= 1) THEN
WIDTH := 1;
ELSE
WHILE (CNT < DATA_VALUE) LOOP
WIDTH := WIDTH + 1;
CNT := CNT *2;
END LOOP;
END IF;
RETURN WIDTH;
END LOG2ROUNDUP;
END BMG_TB_PKG;
@@ -0,0 +1,161 @@
--------------------------------------------------------------------------------
--
-- BLK MEM GEN v7_3 Core - Checker
--
--------------------------------------------------------------------------------
--
-- (c) Copyright 2006_3010 Xilinx, Inc. All rights reserved.
--
-- This file contains confidential and proprietary information
-- of Xilinx, Inc. and is protected under U.S. and
-- international copyright and other intellectual property
-- laws.
--
-- DISCLAIMER
-- This disclaimer is not a license and does not grant any
-- rights to the materials distributed herewith. Except as
-- otherwise provided in a valid license issued to you by
-- Xilinx, and to the maximum extent permitted by applicable
-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
-- (2) Xilinx shall not be liable (whether in contract or tort,
-- including negligence, or under any other theory of
-- liability) for any loss or damage of any kind or nature
-- related to, arising under or in connection with these
-- materials, including for any direct, or any indirect,
-- special, incidental, or consequential loss or damage
-- (including loss of data, profits, goodwill, or any type of
-- loss or damage suffered as a result of any action brought
-- by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the
-- possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-
-- safe, or for use in any application requiring fail-safe
-- performance, such as life-support or safety devices or
-- systems, Class III medical devices, nuclear facilities,
-- applications related to the deployment of airbags, or any
-- other applications that could lead to death, personal
-- injury, or severe property or environmental damage
-- (individually and collectively, "Critical
-- Applications"). Customer assumes the sole risk and
-- liability of any use of Xilinx products in Critical
-- Applications, subject only to applicable laws and
-- regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
-- PART OF THIS FILE AT ALL TIMES.
--------------------------------------------------------------------------------
--
-- Filename: checker.vhd
--
-- Description:
-- Checker
--
--------------------------------------------------------------------------------
-- Author: IP Solutions Division
--
-- History: Sep 12, 2011 - First Release
--------------------------------------------------------------------------------
--
--------------------------------------------------------------------------------
-- Library Declarations
--------------------------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
LIBRARY work;
USE work.BMG_TB_PKG.ALL;
ENTITY CHECKER IS
GENERIC ( WRITE_WIDTH : INTEGER :=32;
READ_WIDTH : INTEGER :=32
);
PORT (
CLK : IN STD_LOGIC;
RST : IN STD_LOGIC;
EN : IN STD_LOGIC;
DATA_IN : IN STD_LOGIC_VECTOR (READ_WIDTH-1 DOWNTO 0); --OUTPUT VECTOR
STATUS : OUT STD_LOGIC:= '0'
);
END CHECKER;
ARCHITECTURE CHECKER_ARCH OF CHECKER IS
SIGNAL EXPECTED_DATA : STD_LOGIC_VECTOR(READ_WIDTH-1 DOWNTO 0);
SIGNAL DATA_IN_R: STD_LOGIC_VECTOR(READ_WIDTH-1 DOWNTO 0);
SIGNAL EN_R : STD_LOGIC := '0';
SIGNAL EN_2R : STD_LOGIC := '0';
--DATA PART CNT DEFINES THE ASPECT RATIO AND GIVES THE INFO TO THE DATA GENERATOR TO PROVIDE THE DATA EITHER IN PARTS OR COMPLETE DATA IN ONE SHOT
--IF READ_WIDTH > WRITE_WIDTH DIVROUNDUP RESULTS IN '1' AND DATA GENERATOR GIVES THE DATAOUT EQUALS TO MAX OF (WRITE_WIDTH, READ_WIDTH)
--IF READ_WIDTH < WRITE-WIDTH DIVROUNDUP RESULTS IN > '1' AND DATA GENERATOR GIVES THE DATAOUT IN TERMS OF PARTS(EG 4 PARTS WHEN WRITE_WIDTH 32 AND READ WIDTH 8)
CONSTANT DATA_PART_CNT: INTEGER:= DIVROUNDUP(WRITE_WIDTH,READ_WIDTH);
CONSTANT MAX_WIDTH: INTEGER:= IF_THEN_ELSE((WRITE_WIDTH>READ_WIDTH),WRITE_WIDTH,READ_WIDTH);
SIGNAL ERR_HOLD : STD_LOGIC :='0';
SIGNAL ERR_DET : STD_LOGIC :='0';
BEGIN
PROCESS(CLK)
BEGIN
IF(RISING_EDGE(CLK)) THEN
IF(RST= '1') THEN
EN_R <= '0';
EN_2R <= '0';
DATA_IN_R <= (OTHERS=>'0');
ELSE
EN_R <= EN;
EN_2R <= EN_R;
DATA_IN_R <= DATA_IN;
END IF;
END IF;
END PROCESS;
EXPECTED_DATA_GEN_INST:ENTITY work.DATA_GEN
GENERIC MAP ( DATA_GEN_WIDTH =>MAX_WIDTH,
DOUT_WIDTH => READ_WIDTH,
DATA_PART_CNT => DATA_PART_CNT,
SEED => 2
)
PORT MAP (
CLK => CLK,
RST => RST,
EN => EN_2R,
DATA_OUT => EXPECTED_DATA
);
PROCESS(CLK)
BEGIN
IF(RISING_EDGE(CLK)) THEN
IF(EN_2R='1') THEN
IF(EXPECTED_DATA = DATA_IN_R) THEN
ERR_DET<='0';
ELSE
ERR_DET<= '1';
END IF;
END IF;
END IF;
END PROCESS;
PROCESS(CLK,RST)
BEGIN
IF(RST='1') THEN
ERR_HOLD <= '0';
ELSIF(RISING_EDGE(CLK)) THEN
ERR_HOLD <= ERR_HOLD OR ERR_DET ;
END IF;
END PROCESS;
STATUS <= ERR_HOLD;
END ARCHITECTURE;
@@ -0,0 +1,140 @@
--------------------------------------------------------------------------------
--
-- BLK MEM GEN v7_3 Core - Data Generator
--
--------------------------------------------------------------------------------
--
-- (c) Copyright 2006_3010 Xilinx, Inc. All rights reserved.
--
-- This file contains confidential and proprietary information
-- of Xilinx, Inc. and is protected under U.S. and
-- international copyright and other intellectual property
-- laws.
--
-- DISCLAIMER
-- This disclaimer is not a license and does not grant any
-- rights to the materials distributed herewith. Except as
-- otherwise provided in a valid license issued to you by
-- Xilinx, and to the maximum extent permitted by applicable
-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
-- (2) Xilinx shall not be liable (whether in contract or tort,
-- including negligence, or under any other theory of
-- liability) for any loss or damage of any kind or nature
-- related to, arising under or in connection with these
-- materials, including for any direct, or any indirect,
-- special, incidental, or consequential loss or damage
-- (including loss of data, profits, goodwill, or any type of
-- loss or damage suffered as a result of any action brought
-- by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the
-- possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-
-- safe, or for use in any application requiring fail-safe
-- performance, such as life-support or safety devices or
-- systems, Class III medical devices, nuclear facilities,
-- applications related to the deployment of airbags, or any
-- other applications that could lead to death, personal
-- injury, or severe property or environmental damage
-- (individually and collectively, "Critical
-- Applications"). Customer assumes the sole risk and
-- liability of any use of Xilinx products in Critical
-- Applications, subject only to applicable laws and
-- regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
-- PART OF THIS FILE AT ALL TIMES.
--------------------------------------------------------------------------------
--
-- Filename: data_gen.vhd
--
-- Description:
-- Data Generator
--
--------------------------------------------------------------------------------
-- Author: IP Solutions Division
--
-- History: Sep 12, 2011 - First Release
--------------------------------------------------------------------------------
--
--------------------------------------------------------------------------------
-- Library Declarations
--------------------------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
LIBRARY work;
USE work.BMG_TB_PKG.ALL;
ENTITY DATA_GEN IS
GENERIC ( DATA_GEN_WIDTH : INTEGER := 32;
DOUT_WIDTH : INTEGER := 32;
DATA_PART_CNT : INTEGER := 1;
SEED : INTEGER := 2
);
PORT (
CLK : IN STD_LOGIC;
RST : IN STD_LOGIC;
EN : IN STD_LOGIC;
DATA_OUT : OUT STD_LOGIC_VECTOR (DOUT_WIDTH-1 DOWNTO 0) --OUTPUT VECTOR
);
END DATA_GEN;
ARCHITECTURE DATA_GEN_ARCH OF DATA_GEN IS
CONSTANT LOOP_COUNT : INTEGER := DIVROUNDUP(DATA_GEN_WIDTH,8);
SIGNAL RAND_DATA : STD_LOGIC_VECTOR(8*LOOP_COUNT-1 DOWNTO 0);
SIGNAL LOCAL_DATA_OUT : STD_LOGIC_VECTOR(DATA_GEN_WIDTH-1 DOWNTO 0);
SIGNAL LOCAL_CNT : INTEGER :=1;
SIGNAL DATA_GEN_I : STD_LOGIC :='0';
BEGIN
LOCAL_DATA_OUT <= RAND_DATA(DATA_GEN_WIDTH-1 DOWNTO 0);
DATA_OUT <= LOCAL_DATA_OUT(((DOUT_WIDTH*LOCAL_CNT)-1) DOWNTO ((DOUT_WIDTH*LOCAL_CNT)-DOUT_WIDTH));
DATA_GEN_I <= '0' WHEN (LOCAL_CNT < DATA_PART_CNT) ELSE EN;
PROCESS(CLK)
BEGIN
IF(RISING_EDGE (CLK)) THEN
IF(EN ='1' AND (DATA_PART_CNT =1)) THEN
LOCAL_CNT <=1;
ELSIF(EN='1' AND (DATA_PART_CNT>1)) THEN
IF(LOCAL_CNT = 1) THEN
LOCAL_CNT <= LOCAL_CNT+1;
ELSIF(LOCAL_CNT < DATA_PART_CNT) THEN
LOCAL_CNT <= LOCAL_CNT+1;
ELSE
LOCAL_CNT <= 1;
END IF;
ELSE
LOCAL_CNT <= 1;
END IF;
END IF;
END PROCESS;
RAND_GEN:FOR N IN LOOP_COUNT-1 DOWNTO 0 GENERATE
RAND_GEN_INST:ENTITY work.RANDOM
GENERIC MAP(
WIDTH => 8,
SEED => (SEED+N)
)
PORT MAP(
CLK => CLK,
RST => RST,
EN => DATA_GEN_I,
RANDOM_NUM => RAND_DATA(8*(N+1)-1 DOWNTO 8*N)
);
END GENERATE RAND_GEN;
END ARCHITECTURE;
@@ -0,0 +1,112 @@
--------------------------------------------------------------------------------
--
-- BLK MEM GEN v7_3 Core - Random Number Generator
--
--------------------------------------------------------------------------------
--
-- (c) Copyright 2006_3010 Xilinx, Inc. All rights reserved.
--
-- This file contains confidential and proprietary information
-- of Xilinx, Inc. and is protected under U.S. and
-- international copyright and other intellectual property
-- laws.
--
-- DISCLAIMER
-- This disclaimer is not a license and does not grant any
-- rights to the materials distributed herewith. Except as
-- otherwise provided in a valid license issued to you by
-- Xilinx, and to the maximum extent permitted by applicable
-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
-- (2) Xilinx shall not be liable (whether in contract or tort,
-- including negligence, or under any other theory of
-- liability) for any loss or damage of any kind or nature
-- related to, arising under or in connection with these
-- materials, including for any direct, or any indirect,
-- special, incidental, or consequential loss or damage
-- (including loss of data, profits, goodwill, or any type of
-- loss or damage suffered as a result of any action brought
-- by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the
-- possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-
-- safe, or for use in any application requiring fail-safe
-- performance, such as life-support or safety devices or
-- systems, Class III medical devices, nuclear facilities,
-- applications related to the deployment of airbags, or any
-- other applications that could lead to death, personal
-- injury, or severe property or environmental damage
-- (individually and collectively, "Critical
-- Applications"). Customer assumes the sole risk and
-- liability of any use of Xilinx products in Critical
-- Applications, subject only to applicable laws and
-- regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
-- PART OF THIS FILE AT ALL TIMES.
--------------------------------------------------------------------------------
--
-- Filename: random.vhd
--
-- Description:
-- Random Generator
--
--------------------------------------------------------------------------------
-- Author: IP Solutions Division
--
-- History: Sep 12, 2011 - First Release
--------------------------------------------------------------------------------
--
--------------------------------------------------------------------------------
-- Library Declarations
--------------------------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY RANDOM IS
GENERIC ( WIDTH : INTEGER := 32;
SEED : INTEGER :=2
);
PORT (
CLK : IN STD_LOGIC;
RST : IN STD_LOGIC;
EN : IN STD_LOGIC;
RANDOM_NUM : OUT STD_LOGIC_VECTOR (WIDTH-1 DOWNTO 0) --OUTPUT VECTOR
);
END RANDOM;
ARCHITECTURE BEHAVIORAL OF RANDOM IS
BEGIN
PROCESS(CLK)
VARIABLE RAND_TEMP : STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0):=CONV_STD_LOGIC_VECTOR(SEED,WIDTH);
VARIABLE TEMP : STD_LOGIC := '0';
BEGIN
IF(RISING_EDGE(CLK)) THEN
IF(RST='1') THEN
RAND_TEMP := CONV_STD_LOGIC_VECTOR(SEED,WIDTH);
ELSE
IF(EN = '1') THEN
TEMP := RAND_TEMP(WIDTH-1) XOR RAND_TEMP(WIDTH-2);
RAND_TEMP(WIDTH-1 DOWNTO 1) := RAND_TEMP(WIDTH-2 DOWNTO 0);
RAND_TEMP(0) := TEMP;
END IF;
END IF;
END IF;
RANDOM_NUM <= RAND_TEMP;
END PROCESS;
END ARCHITECTURE;
@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<generated_project xmlns="http://www.xilinx.com/XMLSchema" xmlns:xil_pn="http://www.xilinx.com/XMLSchema">
<!-- -->
<!-- For tool use only. Do not edit. -->
<!-- -->
<!-- ProjectNavigator created generated project file. -->
<!-- For use in tracking generated file and other information -->
<!-- allowing preservation of process status. -->
<!-- -->
<!-- Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved. -->
<version xmlns="http://www.xilinx.com/XMLSchema">11.1</version>
<sourceproject xmlns="http://www.xilinx.com/XMLSchema" xil_pn:fileType="FILE_XISE" xil_pn:name="VCO_Mem.xise"/>
<files xmlns="http://www.xilinx.com/XMLSchema">
<file xil_pn:fileType="FILE_ASY" xil_pn:name="VCO_Mem.asy" xil_pn:origination="imported"/>
<file xil_pn:fileType="FILE_SYMBOL" xil_pn:name="VCO_Mem.sym" xil_pn:origination="imported"/>
<file xil_pn:fileType="FILE_VHO" xil_pn:name="VCO_Mem.vho" xil_pn:origination="imported"/>
</files>
<transforms xmlns="http://www.xilinx.com/XMLSchema">
<transform xil_pn:end_ts="1654646662" xil_pn:name="TRAN_copyInitialToXSTAbstractSynthesis" xil_pn:start_ts="1654646662">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1654895235" xil_pn:name="TRAN_schematicsToHdl" xil_pn:prop_ck="9157515098364838426" xil_pn:start_ts="1654895235">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1654895235" xil_pn:name="TRAN_regenerateCores" xil_pn:prop_ck="5794461498655324265" xil_pn:start_ts="1654895235">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1654895235" xil_pn:name="TRAN_SubProjectAbstractToPreProxy" xil_pn:start_ts="1654895235">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1654895235" xil_pn:name="TRAN_xawsTohdl" xil_pn:prop_ck="-5036159626982002724" xil_pn:start_ts="1654895235">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
</transforms>
</generated_project>
@@ -0,0 +1,149 @@
--------------------------------------------------------------------------------
-- This file is owned and controlled by Xilinx and must be used solely --
-- for design, simulation, implementation and creation of design files --
-- limited to Xilinx devices or technologies. Use with non-Xilinx --
-- devices or technologies is expressly prohibited and immediately --
-- terminates your license. --
-- --
-- XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" SOLELY --
-- FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR XILINX DEVICES. BY --
-- PROVIDING THIS DESIGN, CODE, OR INFORMATION AS ONE POSSIBLE --
-- IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD, XILINX IS --
-- MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE FROM ANY --
-- CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING ANY --
-- RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY --
-- DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE --
-- IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR --
-- REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF --
-- INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A --
-- PARTICULAR PURPOSE. --
-- --
-- Xilinx products are not intended for use in life support appliances, --
-- devices, or systems. Use in such applications are expressly --
-- prohibited. --
-- --
-- (c) Copyright 1995-2022 Xilinx, Inc. --
-- All rights reserved. --
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- You must compile the wrapper file VCO_Mem.vhd when simulating
-- the core, VCO_Mem. When compiling the wrapper file, be sure to
-- reference the XilinxCoreLib VHDL simulation library. For detailed
-- instructions, please refer to the "CORE Generator Help".
-- The synthesis directives "translate_off/translate_on" specified
-- below are supported by Xilinx, Mentor Graphics and Synplicity
-- synthesis tools. Ensure they are correct for your synthesis tool(s).
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- synthesis translate_off
LIBRARY XilinxCoreLib;
-- synthesis translate_on
ENTITY VCO_Mem IS
PORT (
clka : IN STD_LOGIC;
wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
addra : IN STD_LOGIC_VECTOR(5 DOWNTO 0);
dina : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
clkb : IN STD_LOGIC;
addrb : IN STD_LOGIC_VECTOR(5 DOWNTO 0);
doutb : OUT STD_LOGIC_VECTOR(15 DOWNTO 0)
);
END VCO_Mem;
ARCHITECTURE VCO_Mem_a OF VCO_Mem IS
-- synthesis translate_off
COMPONENT wrapped_VCO_Mem
PORT (
clka : IN STD_LOGIC;
wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
addra : IN STD_LOGIC_VECTOR(5 DOWNTO 0);
dina : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
clkb : IN STD_LOGIC;
addrb : IN STD_LOGIC_VECTOR(5 DOWNTO 0);
doutb : OUT STD_LOGIC_VECTOR(15 DOWNTO 0)
);
END COMPONENT;
-- Configuration specification
FOR ALL : wrapped_VCO_Mem USE ENTITY XilinxCoreLib.blk_mem_gen_v7_3(behavioral)
GENERIC MAP (
c_addra_width => 6,
c_addrb_width => 6,
c_algorithm => 1,
c_axi_id_width => 4,
c_axi_slave_type => 0,
c_axi_type => 1,
c_byte_size => 9,
c_common_clk => 0,
c_default_data => "0",
c_disable_warn_bhv_coll => 0,
c_disable_warn_bhv_range => 0,
c_enable_32bit_address => 0,
c_family => "spartan6",
c_has_axi_id => 0,
c_has_ena => 0,
c_has_enb => 0,
c_has_injecterr => 0,
c_has_mem_output_regs_a => 0,
c_has_mem_output_regs_b => 0,
c_has_mux_output_regs_a => 0,
c_has_mux_output_regs_b => 0,
c_has_regcea => 0,
c_has_regceb => 0,
c_has_rsta => 0,
c_has_rstb => 0,
c_has_softecc_input_regs_a => 0,
c_has_softecc_output_regs_b => 0,
c_init_file => "BlankString",
c_init_file_name => "no_coe_file_loaded",
c_inita_val => "0",
c_initb_val => "0",
c_interface_type => 0,
c_load_init_file => 0,
c_mem_type => 1,
c_mux_pipeline_stages => 0,
c_prim_type => 1,
c_read_depth_a => 64,
c_read_depth_b => 64,
c_read_width_a => 16,
c_read_width_b => 16,
c_rst_priority_a => "CE",
c_rst_priority_b => "CE",
c_rst_type => "SYNC",
c_rstram_a => 0,
c_rstram_b => 0,
c_sim_collision_check => "ALL",
c_use_bram_block => 0,
c_use_byte_wea => 0,
c_use_byte_web => 0,
c_use_default_data => 0,
c_use_ecc => 0,
c_use_softecc => 0,
c_wea_width => 1,
c_web_width => 1,
c_write_depth_a => 64,
c_write_depth_b => 64,
c_write_mode_a => "WRITE_FIRST",
c_write_mode_b => "WRITE_FIRST",
c_write_width_a => 16,
c_write_width_b => 16,
c_xdevicefamily => "spartan6"
);
-- synthesis translate_on
BEGIN
-- synthesis translate_off
U0 : wrapped_VCO_Mem
PORT MAP (
clka => clka,
wea => wea,
addra => addra,
dina => dina,
clkb => clkb,
addrb => addrb,
doutb => doutb
);
-- synthesis translate_on
END VCO_Mem_a;
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<generated_project xmlns="http://www.xilinx.com/XMLSchema" xmlns:xil_pn="http://www.xilinx.com/XMLSchema">
<!-- -->
<!-- For tool use only. Do not edit. -->
<!-- -->
<!-- ProjectNavigator created generated project file. -->
<!-- For use in tracking generated file and other information -->
<!-- allowing preservation of process status. -->
<!-- -->
<!-- Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved. -->
<version xmlns="http://www.xilinx.com/XMLSchema">11.1</version>
<sourceproject xmlns="http://www.xilinx.com/XMLSchema" xil_pn:fileType="FILE_XISE" xil_pn:name="result_bram.xise"/>
<files xmlns="http://www.xilinx.com/XMLSchema">
<file xil_pn:fileType="FILE_ASY" xil_pn:name="result_bram.asy" xil_pn:origination="imported"/>
<file xil_pn:fileType="FILE_SYMBOL" xil_pn:name="result_bram.sym" xil_pn:origination="imported"/>
<file xil_pn:fileType="FILE_VHO" xil_pn:name="result_bram.vho" xil_pn:origination="imported"/>
</files>
<transforms xmlns="http://www.xilinx.com/XMLSchema"/>
</generated_project>
@@ -0,0 +1,149 @@
--------------------------------------------------------------------------------
-- This file is owned and controlled by Xilinx and must be used solely --
-- for design, simulation, implementation and creation of design files --
-- limited to Xilinx devices or technologies. Use with non-Xilinx --
-- devices or technologies is expressly prohibited and immediately --
-- terminates your license. --
-- --
-- XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" SOLELY --
-- FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR XILINX DEVICES. BY --
-- PROVIDING THIS DESIGN, CODE, OR INFORMATION AS ONE POSSIBLE --
-- IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD, XILINX IS --
-- MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE FROM ANY --
-- CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING ANY --
-- RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY --
-- DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE --
-- IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR --
-- REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF --
-- INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A --
-- PARTICULAR PURPOSE. --
-- --
-- Xilinx products are not intended for use in life support appliances, --
-- devices, or systems. Use in such applications are expressly --
-- prohibited. --
-- --
-- (c) Copyright 1995-2020 Xilinx, Inc. --
-- All rights reserved. --
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- You must compile the wrapper file result_bram.vhd when simulating
-- the core, result_bram. When compiling the wrapper file, be sure to
-- reference the XilinxCoreLib VHDL simulation library. For detailed
-- instructions, please refer to the "CORE Generator Help".
-- The synthesis directives "translate_off/translate_on" specified
-- below are supported by Xilinx, Mentor Graphics and Synplicity
-- synthesis tools. Ensure they are correct for your synthesis tool(s).
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- synthesis translate_off
LIBRARY XilinxCoreLib;
-- synthesis translate_on
ENTITY result_bram IS
PORT (
clka : IN STD_LOGIC;
wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
addra : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
dina : IN STD_LOGIC_VECTOR(191 DOWNTO 0);
clkb : IN STD_LOGIC;
addrb : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
doutb : OUT STD_LOGIC_VECTOR(191 DOWNTO 0)
);
END result_bram;
ARCHITECTURE result_bram_a OF result_bram IS
-- synthesis translate_off
COMPONENT wrapped_result_bram
PORT (
clka : IN STD_LOGIC;
wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
addra : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
dina : IN STD_LOGIC_VECTOR(191 DOWNTO 0);
clkb : IN STD_LOGIC;
addrb : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
doutb : OUT STD_LOGIC_VECTOR(191 DOWNTO 0)
);
END COMPONENT;
-- Configuration specification
FOR ALL : wrapped_result_bram USE ENTITY XilinxCoreLib.blk_mem_gen_v7_3(behavioral)
GENERIC MAP (
c_addra_width => 8,
c_addrb_width => 8,
c_algorithm => 1,
c_axi_id_width => 4,
c_axi_slave_type => 0,
c_axi_type => 1,
c_byte_size => 9,
c_common_clk => 0,
c_default_data => "0",
c_disable_warn_bhv_coll => 0,
c_disable_warn_bhv_range => 0,
c_enable_32bit_address => 0,
c_family => "spartan6",
c_has_axi_id => 0,
c_has_ena => 0,
c_has_enb => 0,
c_has_injecterr => 0,
c_has_mem_output_regs_a => 0,
c_has_mem_output_regs_b => 0,
c_has_mux_output_regs_a => 0,
c_has_mux_output_regs_b => 0,
c_has_regcea => 0,
c_has_regceb => 0,
c_has_rsta => 0,
c_has_rstb => 0,
c_has_softecc_input_regs_a => 0,
c_has_softecc_output_regs_b => 0,
c_init_file => "BlankString",
c_init_file_name => "no_coe_file_loaded",
c_inita_val => "0",
c_initb_val => "0",
c_interface_type => 0,
c_load_init_file => 0,
c_mem_type => 1,
c_mux_pipeline_stages => 0,
c_prim_type => 1,
c_read_depth_a => 256,
c_read_depth_b => 256,
c_read_width_a => 192,
c_read_width_b => 192,
c_rst_priority_a => "CE",
c_rst_priority_b => "CE",
c_rst_type => "SYNC",
c_rstram_a => 0,
c_rstram_b => 0,
c_sim_collision_check => "ALL",
c_use_bram_block => 0,
c_use_byte_wea => 0,
c_use_byte_web => 0,
c_use_default_data => 0,
c_use_ecc => 0,
c_use_softecc => 0,
c_wea_width => 1,
c_web_width => 1,
c_write_depth_a => 256,
c_write_depth_b => 256,
c_write_mode_a => "WRITE_FIRST",
c_write_mode_b => "WRITE_FIRST",
c_write_width_a => 192,
c_write_width_b => 192,
c_xdevicefamily => "spartan6"
);
-- synthesis translate_on
BEGIN
-- synthesis translate_off
U0 : wrapped_result_bram
PORT MAP (
clka => clka,
wea => wea,
addra => addra,
dina => dina,
clkb => clkb,
addrb => addrb,
doutb => doutb
);
-- synthesis translate_on
END result_bram_a;
@@ -0,0 +1,61 @@
################################################################################
#
# (c) Copyright 2002 - 2010 Xilinx, Inc. All rights reserved.
#
# This file contains confidential and proprietary information
# of Xilinx, Inc. and is protected under U.S. and
# international copyright and other intellectual property
# laws.
#
# DISCLAIMER
# This disclaimer is not a license and does not grant any
# rights to the materials distributed herewith. Except as
# otherwise provided in a valid license issued to you by
# Xilinx, and to the maximum extent permitted by applicable
# law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
# WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
# AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
# BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
# INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
# (2) Xilinx shall not be liable (whether in contract or tort,
# including negligence, or under any other theory of
# liability) for any loss or damage of any kind or nature
# related to, arising under or in connection with these
# materials, including for any direct, or any indirect,
# special, incidental, or consequential loss or damage
# (including loss of data, profits, goodwill, or any type of
# loss or damage suffered as a result of any action brought
# by a third party) even if such damage or loss was
# reasonably foreseeable or Xilinx had been advised of the
# possibility of the same.
#
# CRITICAL APPLICATIONS
# Xilinx products are not designed or intended to be fail-
# safe, or for use in any application requiring fail-safe
# performance, such as life-support or safety devices or
# systems, Class III medical devices, nuclear facilities,
# applications related to the deployment of airbags, or any
# other applications that could lead to death, personal
# injury, or severe property or environmental damage
# (individually and collectively, "Critical
# Applications"). Customer assumes the sole risk and
# liability of any use of Xilinx products in Critical
# Applications, subject only to applicable laws and
# regulations governing limitations on product liability.
#
# THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
# PART OF THIS FILE AT ALL TIMES.
#
################################################################################
# Tx Core Period Constraint. This constraint can be modified, and is
# valid as long as it is met after place and route.
NET "CLKA" TNM_NET = "CLKA";
NET "CLKB" TNM_NET = "CLKB";
TIMESPEC "TS_CLKA" = PERIOD "CLKA" 25 MHZ;
TIMESPEC "TS_CLKB" = PERIOD "CLKB" 25 MHZ;
################################################################################
@@ -0,0 +1,179 @@
--------------------------------------------------------------------------------
--
-- BLK MEM GEN v7.1 Core - Top-level core wrapper
--
--------------------------------------------------------------------------------
--
-- (c) Copyright 2006-2010 Xilinx, Inc. All rights reserved.
--
-- This file contains confidential and proprietary information
-- of Xilinx, Inc. and is protected under U.S. and
-- international copyright and other intellectual property
-- laws.
--
-- DISCLAIMER
-- This disclaimer is not a license and does not grant any
-- rights to the materials distributed herewith. Except as
-- otherwise provided in a valid license issued to you by
-- Xilinx, and to the maximum extent permitted by applicable
-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
-- (2) Xilinx shall not be liable (whether in contract or tort,
-- including negligence, or under any other theory of
-- liability) for any loss or damage of any kind or nature
-- related to, arising under or in connection with these
-- materials, including for any direct, or any indirect,
-- special, incidental, or consequential loss or damage
-- (including loss of data, profits, goodwill, or any type of
-- loss or damage suffered as a result of any action brought
-- by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the
-- possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-
-- safe, or for use in any application requiring fail-safe
-- performance, such as life-support or safety devices or
-- systems, Class III medical devices, nuclear facilities,
-- applications related to the deployment of airbags, or any
-- other applications that could lead to death, personal
-- injury, or severe property or environmental damage
-- (individually and collectively, "Critical
-- Applications"). Customer assumes the sole risk and
-- liability of any use of Xilinx products in Critical
-- Applications, subject only to applicable laws and
-- regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
-- PART OF THIS FILE AT ALL TIMES.
--------------------------------------------------------------------------------
--
-- Filename: result_bram_exdes.vhd
--
-- Description:
-- This is the actual BMG core wrapper.
--
--------------------------------------------------------------------------------
-- Author: IP Solutions Division
--
-- History: August 31, 2005 - First Release
--------------------------------------------------------------------------------
--
--------------------------------------------------------------------------------
-- Library Declarations
--------------------------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
LIBRARY UNISIM;
USE UNISIM.VCOMPONENTS.ALL;
--------------------------------------------------------------------------------
-- Entity Declaration
--------------------------------------------------------------------------------
ENTITY result_bram_exdes IS
PORT (
--Inputs - Port A
WEA : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
ADDRA : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
DINA : IN STD_LOGIC_VECTOR(191 DOWNTO 0);
CLKA : IN STD_LOGIC;
--Inputs - Port B
ADDRB : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
DOUTB : OUT STD_LOGIC_VECTOR(191 DOWNTO 0);
CLKB : IN STD_LOGIC
);
END result_bram_exdes;
ARCHITECTURE xilinx OF result_bram_exdes IS
COMPONENT BUFG IS
PORT (
I : IN STD_ULOGIC;
O : OUT STD_ULOGIC
);
END COMPONENT;
COMPONENT result_bram IS
PORT (
--Port A
WEA : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
ADDRA : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
DINA : IN STD_LOGIC_VECTOR(191 DOWNTO 0);
CLKA : IN STD_LOGIC;
--Port B
ADDRB : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
DOUTB : OUT STD_LOGIC_VECTOR(191 DOWNTO 0);
CLKB : IN STD_LOGIC
);
END COMPONENT;
SIGNAL CLKA_buf : STD_LOGIC;
SIGNAL CLKB_buf : STD_LOGIC;
SIGNAL S_ACLK_buf : STD_LOGIC;
BEGIN
bufg_A : BUFG
PORT MAP (
I => CLKA,
O => CLKA_buf
);
bufg_B : BUFG
PORT MAP (
I => CLKB,
O => CLKB_buf
);
bmg0 : result_bram
PORT MAP (
--Port A
WEA => WEA,
ADDRA => ADDRA,
DINA => DINA,
CLKA => CLKA_buf,
--Port B
ADDRB => ADDRB,
DOUTB => DOUTB,
CLKB => CLKB_buf
);
END xilinx;
@@ -0,0 +1,275 @@
--------------------------------------------------------------------------------
--
-- BLK MEM GEN v7.1 Core - Top-level wrapper
--
--------------------------------------------------------------------------------
--
-- (c) Copyright 2006-2011 Xilinx, Inc. All rights reserved.
--
-- This file contains confidential and proprietary information
-- of Xilinx, Inc. and is protected under U.S. and
-- international copyright and other intellectual property
-- laws.
--
-- DISCLAIMER
-- This disclaimer is not a license and does not grant any
-- rights to the materials distributed herewith. Except as
-- otherwise provided in a valid license issued to you by
-- Xilinx, and to the maximum extent permitted by applicable
-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
-- (2) Xilinx shall not be liable (whether in contract or tort,
-- including negligence, or under any other theory of
-- liability) for any loss or damage of any kind or nature
-- related to, arising under or in connection with these
-- materials, including for any direct, or any indirect,
-- special, incidental, or consequential loss or damage
-- (including loss of data, profits, goodwill, or any type of
-- loss or damage suffered as a result of any action brought
-- by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the
-- possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-
-- safe, or for use in any application requiring fail-safe
-- performance, such as life-support or safety devices or
-- systems, Class III medical devices, nuclear facilities,
-- applications related to the deployment of airbags, or any
-- other applications that could lead to death, personal
-- injury, or severe property or environmental damage
-- (individually and collectively, "Critical
-- Applications"). Customer assumes the sole risk and
-- liability of any use of Xilinx products in Critical
-- Applications, subject only to applicable laws and
-- regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
-- PART OF THIS FILE AT ALL TIMES.
--
--------------------------------------------------------------------------------
--
-- Filename: result_bram_prod.vhd
--
-- Description:
-- This is the top-level BMG wrapper (over BMG core).
--
--------------------------------------------------------------------------------
-- Author: IP Solutions Division
--
-- History: August 31, 2005 - First Release
--------------------------------------------------------------------------------
--
-- Configured Core Parameter Values:
-- (Refer to the SIM Parameters table in the datasheet for more information on
-- the these parameters.)
-- C_FAMILY : spartan6
-- C_XDEVICEFAMILY : spartan6
-- C_INTERFACE_TYPE : 0
-- C_ENABLE_32BIT_ADDRESS : 0
-- C_AXI_TYPE : 1
-- C_AXI_SLAVE_TYPE : 0
-- C_AXI_ID_WIDTH : 4
-- C_MEM_TYPE : 1
-- C_BYTE_SIZE : 9
-- C_ALGORITHM : 1
-- C_PRIM_TYPE : 1
-- C_LOAD_INIT_FILE : 0
-- C_INIT_FILE_NAME : no_coe_file_loaded
-- C_USE_DEFAULT_DATA : 0
-- C_DEFAULT_DATA : 0
-- C_RST_TYPE : SYNC
-- C_HAS_RSTA : 0
-- C_RST_PRIORITY_A : CE
-- C_RSTRAM_A : 0
-- C_INITA_VAL : 0
-- C_HAS_ENA : 0
-- C_HAS_REGCEA : 0
-- C_USE_BYTE_WEA : 0
-- C_WEA_WIDTH : 1
-- C_WRITE_MODE_A : WRITE_FIRST
-- C_WRITE_WIDTH_A : 192
-- C_READ_WIDTH_A : 192
-- C_WRITE_DEPTH_A : 256
-- C_READ_DEPTH_A : 256
-- C_ADDRA_WIDTH : 8
-- C_HAS_RSTB : 0
-- C_RST_PRIORITY_B : CE
-- C_RSTRAM_B : 0
-- C_INITB_VAL : 0
-- C_HAS_ENB : 0
-- C_HAS_REGCEB : 0
-- C_USE_BYTE_WEB : 0
-- C_WEB_WIDTH : 1
-- C_WRITE_MODE_B : WRITE_FIRST
-- C_WRITE_WIDTH_B : 192
-- C_READ_WIDTH_B : 192
-- C_WRITE_DEPTH_B : 256
-- C_READ_DEPTH_B : 256
-- C_ADDRB_WIDTH : 8
-- C_HAS_MEM_OUTPUT_REGS_A : 0
-- C_HAS_MEM_OUTPUT_REGS_B : 0
-- C_HAS_MUX_OUTPUT_REGS_A : 0
-- C_HAS_MUX_OUTPUT_REGS_B : 0
-- C_HAS_SOFTECC_INPUT_REGS_A : 0
-- C_HAS_SOFTECC_OUTPUT_REGS_B : 0
-- C_MUX_PIPELINE_STAGES : 0
-- C_USE_ECC : 0
-- C_USE_SOFTECC : 0
-- C_HAS_INJECTERR : 0
-- C_SIM_COLLISION_CHECK : ALL
-- C_COMMON_CLK : 0
-- C_DISABLE_WARN_BHV_COLL : 0
-- C_DISABLE_WARN_BHV_RANGE : 0
--------------------------------------------------------------------------------
-- Library Declarations
--------------------------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
LIBRARY UNISIM;
USE UNISIM.VCOMPONENTS.ALL;
--------------------------------------------------------------------------------
-- Entity Declaration
--------------------------------------------------------------------------------
ENTITY result_bram_prod IS
PORT (
--Port A
CLKA : IN STD_LOGIC;
RSTA : IN STD_LOGIC; --opt port
ENA : IN STD_LOGIC; --optional port
REGCEA : IN STD_LOGIC; --optional port
WEA : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
ADDRA : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
DINA : IN STD_LOGIC_VECTOR(191 DOWNTO 0);
DOUTA : OUT STD_LOGIC_VECTOR(191 DOWNTO 0);
--Port B
CLKB : IN STD_LOGIC;
RSTB : IN STD_LOGIC; --opt port
ENB : IN STD_LOGIC; --optional port
REGCEB : IN STD_LOGIC; --optional port
WEB : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
ADDRB : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
DINB : IN STD_LOGIC_VECTOR(191 DOWNTO 0);
DOUTB : OUT STD_LOGIC_VECTOR(191 DOWNTO 0);
--ECC
INJECTSBITERR : IN STD_LOGIC; --optional port
INJECTDBITERR : IN STD_LOGIC; --optional port
SBITERR : OUT STD_LOGIC; --optional port
DBITERR : OUT STD_LOGIC; --optional port
RDADDRECC : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); --optional port
-- AXI BMG Input and Output Port Declarations
-- AXI Global Signals
S_ACLK : IN STD_LOGIC;
S_AXI_AWID : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
S_AXI_AWADDR : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
S_AXI_AWLEN : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
S_AXI_AWSIZE : IN STD_LOGIC_VECTOR(2 DOWNTO 0);
S_AXI_AWBURST : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
S_AXI_AWVALID : IN STD_LOGIC;
S_AXI_AWREADY : OUT STD_LOGIC;
S_AXI_WDATA : IN STD_LOGIC_VECTOR(191 DOWNTO 0);
S_AXI_WSTRB : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
S_AXI_WLAST : IN STD_LOGIC;
S_AXI_WVALID : IN STD_LOGIC;
S_AXI_WREADY : OUT STD_LOGIC;
S_AXI_BID : OUT STD_LOGIC_VECTOR(3 DOWNTO 0):= (OTHERS => '0');
S_AXI_BRESP : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
S_AXI_BVALID : OUT STD_LOGIC;
S_AXI_BREADY : IN STD_LOGIC;
-- AXI Full/Lite Slave Read (Write side)
S_AXI_ARID : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
S_AXI_ARADDR : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
S_AXI_ARLEN : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
S_AXI_ARSIZE : IN STD_LOGIC_VECTOR(2 DOWNTO 0);
S_AXI_ARBURST : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
S_AXI_ARVALID : IN STD_LOGIC;
S_AXI_ARREADY : OUT STD_LOGIC;
S_AXI_RID : OUT STD_LOGIC_VECTOR(3 DOWNTO 0):= (OTHERS => '0');
S_AXI_RDATA : OUT STD_LOGIC_VECTOR(191 DOWNTO 0);
S_AXI_RRESP : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
S_AXI_RLAST : OUT STD_LOGIC;
S_AXI_RVALID : OUT STD_LOGIC;
S_AXI_RREADY : IN STD_LOGIC;
-- AXI Full/Lite Sideband Signals
S_AXI_INJECTSBITERR : IN STD_LOGIC;
S_AXI_INJECTDBITERR : IN STD_LOGIC;
S_AXI_SBITERR : OUT STD_LOGIC;
S_AXI_DBITERR : OUT STD_LOGIC;
S_AXI_RDADDRECC : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
S_ARESETN : IN STD_LOGIC
);
END result_bram_prod;
ARCHITECTURE xilinx OF result_bram_prod IS
COMPONENT result_bram_exdes IS
PORT (
--Port A
WEA : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
ADDRA : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
DINA : IN STD_LOGIC_VECTOR(191 DOWNTO 0);
CLKA : IN STD_LOGIC;
--Port B
ADDRB : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
DOUTB : OUT STD_LOGIC_VECTOR(191 DOWNTO 0);
CLKB : IN STD_LOGIC
);
END COMPONENT;
BEGIN
bmg0 : result_bram_exdes
PORT MAP (
--Port A
WEA => WEA,
ADDRA => ADDRA,
DINA => DINA,
CLKA => CLKA,
--Port B
ADDRB => ADDRB,
DOUTB => DOUTB,
CLKB => CLKB
);
END xilinx;
@@ -0,0 +1,117 @@
--------------------------------------------------------------------------------
--
-- BLK MEM GEN v7_3 Core - Address Generator
--
--------------------------------------------------------------------------------
--
-- (c) Copyright 2006_3010 Xilinx, Inc. All rights reserved.
--
-- This file contains confidential and proprietary information
-- of Xilinx, Inc. and is protected under U.S. and
-- international copyright and other intellectual property
-- laws.
--
-- DISCLAIMER
-- This disclaimer is not a license and does not grant any
-- rights to the materials distributed herewith. Except as
-- otherwise provided in a valid license issued to you by
-- Xilinx, and to the maximum extent permitted by applicable
-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
-- (2) Xilinx shall not be liable (whether in contract or tort,
-- including negligence, or under any other theory of
-- liability) for any loss or damage of any kind or nature
-- related to, arising under or in connection with these
-- materials, including for any direct, or any indirect,
-- special, incidental, or consequential loss or damage
-- (including loss of data, profits, goodwill, or any type of
-- loss or damage suffered as a result of any action brought
-- by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the
-- possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-
-- safe, or for use in any application requiring fail-safe
-- performance, such as life-support or safety devices or
-- systems, Class III medical devices, nuclear facilities,
-- applications related to the deployment of airbags, or any
-- other applications that could lead to death, personal
-- injury, or severe property or environmental damage
-- (individually and collectively, "Critical
-- Applications"). Customer assumes the sole risk and
-- liability of any use of Xilinx products in Critical
-- Applications, subject only to applicable laws and
-- regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
-- PART OF THIS FILE AT ALL TIMES.
--------------------------------------------------------------------------------
--
-- Filename: addr_gen.vhd
--
-- Description:
-- Address Generator
--
--------------------------------------------------------------------------------
-- Author: IP Solutions Division
--
-- History: Sep 12, 2011 - First Release
--------------------------------------------------------------------------------
--
--------------------------------------------------------------------------------
-- Library Declarations
--------------------------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
LIBRARY work;
USE work.ALL;
ENTITY ADDR_GEN IS
GENERIC ( C_MAX_DEPTH : INTEGER := 1024 ;
RST_VALUE : STD_LOGIC_VECTOR(31 DOWNTO 0) := (OTHERS=> '0');
RST_INC : INTEGER := 0);
PORT (
CLK : IN STD_LOGIC;
RST : IN STD_LOGIC;
EN : IN STD_LOGIC;
LOAD :IN STD_LOGIC;
LOAD_VALUE : IN STD_LOGIC_VECTOR (31 DOWNTO 0) := (OTHERS => '0');
ADDR_OUT : OUT STD_LOGIC_VECTOR (31 DOWNTO 0) --OUTPUT VECTOR
);
END ADDR_GEN;
ARCHITECTURE BEHAVIORAL OF ADDR_GEN IS
SIGNAL ADDR_TEMP : STD_LOGIC_VECTOR(31 DOWNTO 0) := (OTHERS =>'0');
BEGIN
ADDR_OUT <= ADDR_TEMP;
PROCESS(CLK)
BEGIN
IF(RISING_EDGE(CLK)) THEN
IF(RST='1') THEN
ADDR_TEMP<= RST_VALUE + conv_std_logic_vector(RST_INC,32 );
ELSE
IF(EN='1') THEN
IF(LOAD='1') THEN
ADDR_TEMP <=LOAD_VALUE;
ELSE
IF(ADDR_TEMP = C_MAX_DEPTH-1) THEN
ADDR_TEMP<= RST_VALUE + conv_std_logic_vector(RST_INC,32 );
ELSE
ADDR_TEMP <= ADDR_TEMP + '1';
END IF;
END IF;
END IF;
END IF;
END IF;
END PROCESS;
END ARCHITECTURE;
@@ -0,0 +1,434 @@
--------------------------------------------------------------------------------
--
-- BLK MEM GEN v7_3 Core - Stimulus Generator For Simple Dual Port RAM
--
--------------------------------------------------------------------------------
--
-- (c) Copyright 2006_3010 Xilinx, Inc. All rights reserved.
--
-- This file contains confidential and proprietary information
-- of Xilinx, Inc. and is protected under U.S. and
-- international copyright and other intellectual property
-- laws.
--
-- DISCLAIMER
-- This disclaimer is not a license and does not grant any
-- rights to the materials distributed herewith. Except as
-- otherwise provided in a valid license issued to you by
-- Xilinx, and to the maximum extent permitted by applicable
-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
-- (2) Xilinx shall not be liable (whether in contract or tort,
-- including negligence, or under any other theory of
-- liability) for any loss or damage of any kind or nature
-- related to, arising under or in connection with these
-- materials, including for any direct, or any indirect,
-- special, incidental, or consequential loss or damage
-- (including loss of data, profits, goodwill, or any type of
-- loss or damage suffered as a result of any action brought
-- by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the
-- possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-
-- safe, or for use in any application requiring fail-safe
-- performance, such as life-support or safety devices or
-- systems, Class III medical devices, nuclear facilities,
-- applications related to the deployment of airbags, or any
-- other applications that could lead to death, personal
-- injury, or severe property or environmental damage
-- (individually and collectively, "Critical
-- Applications"). Customer assumes the sole risk and
-- liability of any use of Xilinx products in Critical
-- Applications, subject only to applicable laws and
-- regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
-- PART OF THIS FILE AT ALL TIMES.
--------------------------------------------------------------------------------
--
-- Filename: bmg_stim_gen.vhd
--
-- Description:
-- Stimulus Generation For SDP Configuration
-- 100 Writes and 100 Reads will be performed in a repeatitive loop till the
-- simulation ends
--
--------------------------------------------------------------------------------
-- Author: IP Solutions Division
--
-- History: Sep 12, 2011 - First Release
--------------------------------------------------------------------------------
--
--------------------------------------------------------------------------------
-- Library Declarations
--------------------------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.STD_LOGIC_MISC.ALL;
LIBRARY work;
USE work.ALL;
USE work.BMG_TB_PKG.ALL;
ENTITY REGISTER_LOGIC IS
PORT(
Q : OUT STD_LOGIC;
CLK : IN STD_LOGIC;
RST : IN STD_LOGIC;
D : IN STD_LOGIC
);
END REGISTER_LOGIC;
ARCHITECTURE REGISTER_ARCH OF REGISTER_LOGIC IS
SIGNAL Q_O : STD_LOGIC :='0';
BEGIN
Q <= Q_O;
FF_BEH: PROCESS(CLK)
BEGIN
IF(RISING_EDGE(CLK)) THEN
IF(RST ='1') THEN
Q_O <= '0';
ELSE
Q_O <= D;
END IF;
END IF;
END PROCESS;
END REGISTER_ARCH;
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.STD_LOGIC_MISC.ALL;
LIBRARY work;
USE work.ALL;
USE work.BMG_TB_PKG.ALL;
ENTITY BMG_STIM_GEN IS
PORT (
CLKA : IN STD_LOGIC;
CLKB : IN STD_LOGIC;
TB_RST : IN STD_LOGIC;
ADDRA: OUT STD_LOGIC_VECTOR(7 DOWNTO 0) := (OTHERS => '0');
DINA : OUT STD_LOGIC_VECTOR(191 DOWNTO 0) := (OTHERS => '0');
WEA : OUT STD_LOGIC_VECTOR (0 DOWNTO 0) := (OTHERS => '0');
ADDRB: OUT STD_LOGIC_VECTOR(7 DOWNTO 0) := (OTHERS => '0');
CHECK_DATA: OUT STD_LOGIC:='0'
);
END BMG_STIM_GEN;
ARCHITECTURE BEHAVIORAL OF BMG_STIM_GEN IS
CONSTANT ZERO : STD_LOGIC_VECTOR(31 DOWNTO 0) := (OTHERS => '0');
SIGNAL WRITE_ADDR : STD_LOGIC_VECTOR(31 DOWNTO 0) := (OTHERS => '0');
SIGNAL READ_ADDR : STD_LOGIC_VECTOR(31 DOWNTO 0) := (OTHERS => '0');
SIGNAL DINA_INT : STD_LOGIC_VECTOR(191 DOWNTO 0) := (OTHERS => '0');
SIGNAL DO_WRITE : STD_LOGIC := '0';
SIGNAL DO_READ : STD_LOGIC := '0';
SIGNAL DO_READ_R : STD_LOGIC := '0';
SIGNAL DO_READ_REG : STD_LOGIC_VECTOR(5 DOWNTO 0) :=(OTHERS => '0');
SIGNAL PORTA_WR : STD_LOGIC:='0';
SIGNAL COUNT : INTEGER :=0;
SIGNAL INCR_WR_CNT : STD_LOGIC:='0';
SIGNAL PORTA_WR_COMPLETE : STD_LOGIC :='0';
SIGNAL PORTB_RD : STD_LOGIC:='0';
SIGNAL COUNT_RD : INTEGER :=0;
SIGNAL INCR_RD_CNT : STD_LOGIC:='0';
SIGNAL PORTB_RD_COMPLETE : STD_LOGIC :='0';
SIGNAL LATCH_PORTA_WR_COMPLETE : STD_LOGIC :='0';
SIGNAL PORTB_RD_HAPPENED : STD_LOGIC := '0';
SIGNAL PORTA_WR_L1 :STD_LOGIC := '0';
SIGNAL PORTA_WR_L2 :STD_LOGIC := '0';
SIGNAL PORTB_RD_R2 :STD_LOGIC := '0';
SIGNAL PORTB_RD_R1 :STD_LOGIC := '0';
SIGNAL LATCH_PORTB_RD_COMPLETE : STD_LOGIC :='0';
SIGNAL PORTA_WR_HAPPENED : STD_LOGIC := '0';
SIGNAL PORTB_RD_L1 : STD_LOGIC := '0';
SIGNAL PORTB_RD_L2 : STD_LOGIC := '0';
SIGNAL PORTA_WR_R2 : STD_LOGIC := '0';
SIGNAL PORTA_WR_R1 : STD_LOGIC := '0';
CONSTANT WR_RD_DEEP_COUNT :INTEGER :=8;
CONSTANT WR_DEEP_COUNT : INTEGER := if_then_else((8 <= 8),WR_RD_DEEP_COUNT,
((192/192)*WR_RD_DEEP_COUNT));
CONSTANT RD_DEEP_COUNT : INTEGER := if_then_else((8 <= 8),WR_RD_DEEP_COUNT,
((192/192)*WR_RD_DEEP_COUNT));
BEGIN
ADDRA <= WRITE_ADDR(7 DOWNTO 0) ;
DINA <= DINA_INT ;
ADDRB <= READ_ADDR(7 DOWNTO 0) when (DO_READ='1') else (OTHERS=>'0');
CHECK_DATA <= DO_READ;
RD_ADDR_GEN_INST:ENTITY work.ADDR_GEN
GENERIC MAP(
C_MAX_DEPTH => 256 ,
RST_INC => 1 )
PORT MAP(
CLK => CLKB,
RST => TB_RST,
EN => DO_READ,
LOAD => '0',
LOAD_VALUE => ZERO,
ADDR_OUT => READ_ADDR
);
WR_ADDR_GEN_INST:ENTITY work.ADDR_GEN
GENERIC MAP(
C_MAX_DEPTH => 256,
RST_INC => 1 )
PORT MAP(
CLK => CLKA,
RST => TB_RST,
EN => DO_WRITE,
LOAD => '0',
LOAD_VALUE => ZERO,
ADDR_OUT => WRITE_ADDR
);
WR_DATA_GEN_INST:ENTITY work.DATA_GEN
GENERIC MAP (
DATA_GEN_WIDTH => 192,
DOUT_WIDTH => 192 ,
DATA_PART_CNT => 1,
SEED => 2)
PORT MAP (
CLK => CLKA,
RST => TB_RST,
EN => DO_WRITE,
DATA_OUT => DINA_INT
);
PORTA_WR_PROCESS: PROCESS(CLKA)
BEGIN
IF(RISING_EDGE(CLKA)) THEN
IF(TB_RST='1') THEN
PORTA_WR<='1';
ELSE
PORTA_WR<=PORTB_RD_COMPLETE;
END IF;
END IF;
END PROCESS;
PORTB_RD_PROCESS: PROCESS(CLKB)
BEGIN
IF(RISING_EDGE(CLKB)) THEN
IF(TB_RST='1') THEN
PORTB_RD<='0';
ELSE
PORTB_RD<=PORTA_WR_L2;
END IF;
END IF;
END PROCESS;
PORTB_RD_COMPLETE_LATCH: PROCESS(CLKB)
BEGIN
IF(RISING_EDGE(CLKB)) THEN
IF(TB_RST='1') THEN
LATCH_PORTB_RD_COMPLETE<='0';
ELSIF(PORTB_RD_COMPLETE='1') THEN
LATCH_PORTB_RD_COMPLETE <='1';
ELSIF(PORTA_WR_HAPPENED='1') THEN
LATCH_PORTB_RD_COMPLETE<='0';
END IF;
END IF;
END PROCESS;
PROCESS(CLKA)
BEGIN
IF(RISING_EDGE(CLKA)) THEN
IF(TB_RST='1') THEN
PORTB_RD_L1 <='0';
PORTB_RD_L2 <='0';
ELSE
PORTB_RD_L1 <= LATCH_PORTB_RD_COMPLETE;
PORTB_RD_L2 <= PORTB_RD_L1;
END IF;
END IF;
END PROCESS;
PROCESS(CLKB)
BEGIN
IF(RISING_EDGE(CLKB)) THEN
IF(TB_RST='1') THEN
PORTA_WR_R1 <='0';
PORTA_WR_R2 <='0';
ELSE
PORTA_WR_R1 <= PORTA_WR;
PORTA_WR_R2 <= PORTA_WR_R1;
END IF;
END IF;
END PROCESS;
PORTA_WR_HAPPENED <= PORTA_WR_R2;
PORTA_WR_COMPLETE_LATCH: PROCESS(CLKA)
BEGIN
IF(RISING_EDGE(CLKA)) THEN
IF(TB_RST='1') THEN
LATCH_PORTA_WR_COMPLETE<='0';
ELSIF(PORTA_WR_COMPLETE='1') THEN
LATCH_PORTA_WR_COMPLETE <='1';
--ELSIF(PORTB_RD_HAPPENED='1') THEN
ELSE
LATCH_PORTA_WR_COMPLETE<='0';
END IF;
END IF;
END PROCESS;
PROCESS(CLKB)
BEGIN
IF(RISING_EDGE(CLKB)) THEN
IF(TB_RST='1') THEN
PORTA_WR_L1 <='0';
PORTA_WR_L2 <='0';
ELSE
PORTA_WR_L1 <= LATCH_PORTA_WR_COMPLETE;
PORTA_WR_L2 <= PORTA_WR_L1;
END IF;
END IF;
END PROCESS;
PROCESS(CLKA)
BEGIN
IF(RISING_EDGE(CLKA)) THEN
IF(TB_RST='1') THEN
PORTB_RD_R1 <='0';
PORTB_RD_R2 <='0';
ELSE
PORTB_RD_R1 <= PORTB_RD;
PORTB_RD_R2 <= PORTB_RD_R1;
END IF;
END IF;
END PROCESS;
PORTB_RD_HAPPENED <= PORTB_RD_R2;
PORTB_RD_COMPLETE <= '1' when (count_rd=RD_DEEP_COUNT) else '0';
start_rd_counter: process(clkb)
begin
if(rising_edge(clkb)) then
if(tb_rst='1') then
incr_rd_cnt <= '0';
elsif(portb_rd ='1') then
incr_rd_cnt <='1';
elsif(portb_rd_complete='1') then
incr_rd_cnt <='0';
end if;
end if;
end process;
RD_COUNTER: process(clkb)
begin
if(rising_edge(clkb)) then
if(tb_rst='1') then
count_rd <= 0;
elsif(incr_rd_cnt='1') then
count_rd<=count_rd+1;
end if;
--if(count_rd=(wr_rd_deep_count)) then
if(count_rd=(RD_DEEP_COUNT)) then
count_rd<=0;
end if;
end if;
end process;
DO_READ<='1' when (count_rd <RD_DEEP_COUNT and incr_rd_cnt='1') else '0';
PORTA_WR_COMPLETE <= '1' when (count=WR_DEEP_COUNT) else '0';
start_counter: process(clka)
begin
if(rising_edge(clka)) then
if(tb_rst='1') then
incr_wr_cnt <= '0';
elsif(porta_wr ='1') then
incr_wr_cnt <='1';
elsif(porta_wr_complete='1') then
incr_wr_cnt <='0';
end if;
end if;
end process;
COUNTER: process(clka)
begin
if(rising_edge(clka)) then
if(tb_rst='1') then
count <= 0;
elsif(incr_wr_cnt='1') then
count<=count+1;
end if;
if(count=(WR_DEEP_COUNT)) then
count<=0;
end if;
end if;
end process;
DO_WRITE<='1' when (count <WR_DEEP_COUNT and incr_wr_cnt='1') else '0';
BEGIN_SHIFT_REG: FOR I IN 0 TO 5 GENERATE
BEGIN
DFF_RIGHT: IF I=0 GENERATE
BEGIN
SHIFT_INST_0: ENTITY work.REGISTER_LOGIC
PORT MAP(
Q => DO_READ_REG(0),
CLK => CLKB,
RST => TB_RST,
D => DO_READ
);
END GENERATE DFF_RIGHT;
DFF_OTHERS: IF ((I>0) AND (I<=5)) GENERATE
BEGIN
SHIFT_INST: ENTITY work.REGISTER_LOGIC
PORT MAP(
Q => DO_READ_REG(I),
CLK =>CLKB,
RST =>TB_RST,
D =>DO_READ_REG(I-1)
);
END GENERATE DFF_OTHERS;
END GENERATE BEGIN_SHIFT_REG;
REGCE_PROCESS: PROCESS(CLKB)
BEGIN
IF(RISING_EDGE(CLKB)) THEN
IF(TB_RST='1') THEN
DO_READ_R <= '0';
ELSE
DO_READ_R <= DO_READ;
END IF;
END IF;
END PROCESS;
WEA(0) <= DO_WRITE ;
END ARCHITECTURE;
@@ -0,0 +1,200 @@
--------------------------------------------------------------------------------
--
-- BLK MEM GEN v7_3 Core - Testbench Package
--
--------------------------------------------------------------------------------
--
-- (c) Copyright 2006_3010 Xilinx, Inc. All rights reserved.
--
-- This file contains confidential and proprietary information
-- of Xilinx, Inc. and is protected under U.S. and
-- international copyright and other intellectual property
-- laws.
--
-- DISCLAIMER
-- This disclaimer is not a license and does not grant any
-- rights to the materials distributed herewith. Except as
-- otherwise provided in a valid license issued to you by
-- Xilinx, and to the maximum extent permitted by applicable
-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
-- (2) Xilinx shall not be liable (whether in contract or tort,
-- including negligence, or under any other theory of
-- liability) for any loss or damage of any kind or nature
-- related to, arising under or in connection with these
-- materials, including for any direct, or any indirect,
-- special, incidental, or consequential loss or damage
-- (including loss of data, profits, goodwill, or any type of
-- loss or damage suffered as a result of any action brought
-- by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the
-- possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-
-- safe, or for use in any application requiring fail-safe
-- performance, such as life-support or safety devices or
-- systems, Class III medical devices, nuclear facilities,
-- applications related to the deployment of airbags, or any
-- other applications that could lead to death, personal
-- injury, or severe property or environmental damage
-- (individually and collectively, "Critical
-- Applications"). Customer assumes the sole risk and
-- liability of any use of Xilinx products in Critical
-- Applications, subject only to applicable laws and
-- regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
-- PART OF THIS FILE AT ALL TIMES.
--------------------------------------------------------------------------------
--
-- Filename: bmg_tb_pkg.vhd
--
-- Description:
-- BMG Testbench Package files
--
--------------------------------------------------------------------------------
-- Author: IP Solutions Division
--
-- History: Sep 12, 2011 - First Release
--------------------------------------------------------------------------------
--
--------------------------------------------------------------------------------
-- Library Declarations
--------------------------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
PACKAGE BMG_TB_PKG IS
FUNCTION DIVROUNDUP (
DATA_VALUE : INTEGER;
DIVISOR : INTEGER)
RETURN INTEGER;
------------------------
FUNCTION IF_THEN_ELSE (
CONDITION : BOOLEAN;
TRUE_CASE : STD_LOGIC_VECTOR;
FALSE_CASE : STD_LOGIC_VECTOR)
RETURN STD_LOGIC_VECTOR;
------------------------
FUNCTION IF_THEN_ELSE (
CONDITION : BOOLEAN;
TRUE_CASE : STRING;
FALSE_CASE :STRING)
RETURN STRING;
------------------------
FUNCTION IF_THEN_ELSE (
CONDITION : BOOLEAN;
TRUE_CASE : STD_LOGIC;
FALSE_CASE :STD_LOGIC)
RETURN STD_LOGIC;
------------------------
FUNCTION IF_THEN_ELSE (
CONDITION : BOOLEAN;
TRUE_CASE : INTEGER;
FALSE_CASE : INTEGER)
RETURN INTEGER;
------------------------
FUNCTION LOG2ROUNDUP (
DATA_VALUE : INTEGER)
RETURN INTEGER;
END BMG_TB_PKG;
PACKAGE BODY BMG_TB_PKG IS
FUNCTION DIVROUNDUP (
DATA_VALUE : INTEGER;
DIVISOR : INTEGER)
RETURN INTEGER IS
VARIABLE DIV : INTEGER;
BEGIN
DIV := DATA_VALUE/DIVISOR;
IF ( (DATA_VALUE MOD DIVISOR) /= 0) THEN
DIV := DIV+1;
END IF;
RETURN DIV;
END DIVROUNDUP;
---------------------------------
FUNCTION IF_THEN_ELSE (
CONDITION : BOOLEAN;
TRUE_CASE : STD_LOGIC_VECTOR;
FALSE_CASE : STD_LOGIC_VECTOR)
RETURN STD_LOGIC_VECTOR IS
BEGIN
IF NOT CONDITION THEN
RETURN FALSE_CASE;
ELSE
RETURN TRUE_CASE;
END IF;
END IF_THEN_ELSE;
---------------------------------
FUNCTION IF_THEN_ELSE (
CONDITION : BOOLEAN;
TRUE_CASE : STD_LOGIC;
FALSE_CASE : STD_LOGIC)
RETURN STD_LOGIC IS
BEGIN
IF NOT CONDITION THEN
RETURN FALSE_CASE;
ELSE
RETURN TRUE_CASE;
END IF;
END IF_THEN_ELSE;
---------------------------------
FUNCTION IF_THEN_ELSE (
CONDITION : BOOLEAN;
TRUE_CASE : INTEGER;
FALSE_CASE : INTEGER)
RETURN INTEGER IS
VARIABLE RETVAL : INTEGER := 0;
BEGIN
IF CONDITION=FALSE THEN
RETVAL:=FALSE_CASE;
ELSE
RETVAL:=TRUE_CASE;
END IF;
RETURN RETVAL;
END IF_THEN_ELSE;
---------------------------------
FUNCTION IF_THEN_ELSE (
CONDITION : BOOLEAN;
TRUE_CASE : STRING;
FALSE_CASE : STRING)
RETURN STRING IS
BEGIN
IF NOT CONDITION THEN
RETURN FALSE_CASE;
ELSE
RETURN TRUE_CASE;
END IF;
END IF_THEN_ELSE;
-------------------------------
FUNCTION LOG2ROUNDUP (
DATA_VALUE : INTEGER)
RETURN INTEGER IS
VARIABLE WIDTH : INTEGER := 0;
VARIABLE CNT : INTEGER := 1;
BEGIN
IF (DATA_VALUE <= 1) THEN
WIDTH := 1;
ELSE
WHILE (CNT < DATA_VALUE) LOOP
WIDTH := WIDTH + 1;
CNT := CNT *2;
END LOOP;
END IF;
RETURN WIDTH;
END LOG2ROUNDUP;
END BMG_TB_PKG;
@@ -0,0 +1,161 @@
--------------------------------------------------------------------------------
--
-- BLK MEM GEN v7_3 Core - Checker
--
--------------------------------------------------------------------------------
--
-- (c) Copyright 2006_3010 Xilinx, Inc. All rights reserved.
--
-- This file contains confidential and proprietary information
-- of Xilinx, Inc. and is protected under U.S. and
-- international copyright and other intellectual property
-- laws.
--
-- DISCLAIMER
-- This disclaimer is not a license and does not grant any
-- rights to the materials distributed herewith. Except as
-- otherwise provided in a valid license issued to you by
-- Xilinx, and to the maximum extent permitted by applicable
-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
-- (2) Xilinx shall not be liable (whether in contract or tort,
-- including negligence, or under any other theory of
-- liability) for any loss or damage of any kind or nature
-- related to, arising under or in connection with these
-- materials, including for any direct, or any indirect,
-- special, incidental, or consequential loss or damage
-- (including loss of data, profits, goodwill, or any type of
-- loss or damage suffered as a result of any action brought
-- by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the
-- possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-
-- safe, or for use in any application requiring fail-safe
-- performance, such as life-support or safety devices or
-- systems, Class III medical devices, nuclear facilities,
-- applications related to the deployment of airbags, or any
-- other applications that could lead to death, personal
-- injury, or severe property or environmental damage
-- (individually and collectively, "Critical
-- Applications"). Customer assumes the sole risk and
-- liability of any use of Xilinx products in Critical
-- Applications, subject only to applicable laws and
-- regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
-- PART OF THIS FILE AT ALL TIMES.
--------------------------------------------------------------------------------
--
-- Filename: checker.vhd
--
-- Description:
-- Checker
--
--------------------------------------------------------------------------------
-- Author: IP Solutions Division
--
-- History: Sep 12, 2011 - First Release
--------------------------------------------------------------------------------
--
--------------------------------------------------------------------------------
-- Library Declarations
--------------------------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
LIBRARY work;
USE work.BMG_TB_PKG.ALL;
ENTITY CHECKER IS
GENERIC ( WRITE_WIDTH : INTEGER :=32;
READ_WIDTH : INTEGER :=32
);
PORT (
CLK : IN STD_LOGIC;
RST : IN STD_LOGIC;
EN : IN STD_LOGIC;
DATA_IN : IN STD_LOGIC_VECTOR (READ_WIDTH-1 DOWNTO 0); --OUTPUT VECTOR
STATUS : OUT STD_LOGIC:= '0'
);
END CHECKER;
ARCHITECTURE CHECKER_ARCH OF CHECKER IS
SIGNAL EXPECTED_DATA : STD_LOGIC_VECTOR(READ_WIDTH-1 DOWNTO 0);
SIGNAL DATA_IN_R: STD_LOGIC_VECTOR(READ_WIDTH-1 DOWNTO 0);
SIGNAL EN_R : STD_LOGIC := '0';
SIGNAL EN_2R : STD_LOGIC := '0';
--DATA PART CNT DEFINES THE ASPECT RATIO AND GIVES THE INFO TO THE DATA GENERATOR TO PROVIDE THE DATA EITHER IN PARTS OR COMPLETE DATA IN ONE SHOT
--IF READ_WIDTH > WRITE_WIDTH DIVROUNDUP RESULTS IN '1' AND DATA GENERATOR GIVES THE DATAOUT EQUALS TO MAX OF (WRITE_WIDTH, READ_WIDTH)
--IF READ_WIDTH < WRITE-WIDTH DIVROUNDUP RESULTS IN > '1' AND DATA GENERATOR GIVES THE DATAOUT IN TERMS OF PARTS(EG 4 PARTS WHEN WRITE_WIDTH 32 AND READ WIDTH 8)
CONSTANT DATA_PART_CNT: INTEGER:= DIVROUNDUP(WRITE_WIDTH,READ_WIDTH);
CONSTANT MAX_WIDTH: INTEGER:= IF_THEN_ELSE((WRITE_WIDTH>READ_WIDTH),WRITE_WIDTH,READ_WIDTH);
SIGNAL ERR_HOLD : STD_LOGIC :='0';
SIGNAL ERR_DET : STD_LOGIC :='0';
BEGIN
PROCESS(CLK)
BEGIN
IF(RISING_EDGE(CLK)) THEN
IF(RST= '1') THEN
EN_R <= '0';
EN_2R <= '0';
DATA_IN_R <= (OTHERS=>'0');
ELSE
EN_R <= EN;
EN_2R <= EN_R;
DATA_IN_R <= DATA_IN;
END IF;
END IF;
END PROCESS;
EXPECTED_DATA_GEN_INST:ENTITY work.DATA_GEN
GENERIC MAP ( DATA_GEN_WIDTH =>MAX_WIDTH,
DOUT_WIDTH => READ_WIDTH,
DATA_PART_CNT => DATA_PART_CNT,
SEED => 2
)
PORT MAP (
CLK => CLK,
RST => RST,
EN => EN_2R,
DATA_OUT => EXPECTED_DATA
);
PROCESS(CLK)
BEGIN
IF(RISING_EDGE(CLK)) THEN
IF(EN_2R='1') THEN
IF(EXPECTED_DATA = DATA_IN_R) THEN
ERR_DET<='0';
ELSE
ERR_DET<= '1';
END IF;
END IF;
END IF;
END PROCESS;
PROCESS(CLK,RST)
BEGIN
IF(RST='1') THEN
ERR_HOLD <= '0';
ELSIF(RISING_EDGE(CLK)) THEN
ERR_HOLD <= ERR_HOLD OR ERR_DET ;
END IF;
END PROCESS;
STATUS <= ERR_HOLD;
END ARCHITECTURE;
@@ -0,0 +1,140 @@
--------------------------------------------------------------------------------
--
-- BLK MEM GEN v7_3 Core - Data Generator
--
--------------------------------------------------------------------------------
--
-- (c) Copyright 2006_3010 Xilinx, Inc. All rights reserved.
--
-- This file contains confidential and proprietary information
-- of Xilinx, Inc. and is protected under U.S. and
-- international copyright and other intellectual property
-- laws.
--
-- DISCLAIMER
-- This disclaimer is not a license and does not grant any
-- rights to the materials distributed herewith. Except as
-- otherwise provided in a valid license issued to you by
-- Xilinx, and to the maximum extent permitted by applicable
-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
-- (2) Xilinx shall not be liable (whether in contract or tort,
-- including negligence, or under any other theory of
-- liability) for any loss or damage of any kind or nature
-- related to, arising under or in connection with these
-- materials, including for any direct, or any indirect,
-- special, incidental, or consequential loss or damage
-- (including loss of data, profits, goodwill, or any type of
-- loss or damage suffered as a result of any action brought
-- by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the
-- possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-
-- safe, or for use in any application requiring fail-safe
-- performance, such as life-support or safety devices or
-- systems, Class III medical devices, nuclear facilities,
-- applications related to the deployment of airbags, or any
-- other applications that could lead to death, personal
-- injury, or severe property or environmental damage
-- (individually and collectively, "Critical
-- Applications"). Customer assumes the sole risk and
-- liability of any use of Xilinx products in Critical
-- Applications, subject only to applicable laws and
-- regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
-- PART OF THIS FILE AT ALL TIMES.
--------------------------------------------------------------------------------
--
-- Filename: data_gen.vhd
--
-- Description:
-- Data Generator
--
--------------------------------------------------------------------------------
-- Author: IP Solutions Division
--
-- History: Sep 12, 2011 - First Release
--------------------------------------------------------------------------------
--
--------------------------------------------------------------------------------
-- Library Declarations
--------------------------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
LIBRARY work;
USE work.BMG_TB_PKG.ALL;
ENTITY DATA_GEN IS
GENERIC ( DATA_GEN_WIDTH : INTEGER := 32;
DOUT_WIDTH : INTEGER := 32;
DATA_PART_CNT : INTEGER := 1;
SEED : INTEGER := 2
);
PORT (
CLK : IN STD_LOGIC;
RST : IN STD_LOGIC;
EN : IN STD_LOGIC;
DATA_OUT : OUT STD_LOGIC_VECTOR (DOUT_WIDTH-1 DOWNTO 0) --OUTPUT VECTOR
);
END DATA_GEN;
ARCHITECTURE DATA_GEN_ARCH OF DATA_GEN IS
CONSTANT LOOP_COUNT : INTEGER := DIVROUNDUP(DATA_GEN_WIDTH,8);
SIGNAL RAND_DATA : STD_LOGIC_VECTOR(8*LOOP_COUNT-1 DOWNTO 0);
SIGNAL LOCAL_DATA_OUT : STD_LOGIC_VECTOR(DATA_GEN_WIDTH-1 DOWNTO 0);
SIGNAL LOCAL_CNT : INTEGER :=1;
SIGNAL DATA_GEN_I : STD_LOGIC :='0';
BEGIN
LOCAL_DATA_OUT <= RAND_DATA(DATA_GEN_WIDTH-1 DOWNTO 0);
DATA_OUT <= LOCAL_DATA_OUT(((DOUT_WIDTH*LOCAL_CNT)-1) DOWNTO ((DOUT_WIDTH*LOCAL_CNT)-DOUT_WIDTH));
DATA_GEN_I <= '0' WHEN (LOCAL_CNT < DATA_PART_CNT) ELSE EN;
PROCESS(CLK)
BEGIN
IF(RISING_EDGE (CLK)) THEN
IF(EN ='1' AND (DATA_PART_CNT =1)) THEN
LOCAL_CNT <=1;
ELSIF(EN='1' AND (DATA_PART_CNT>1)) THEN
IF(LOCAL_CNT = 1) THEN
LOCAL_CNT <= LOCAL_CNT+1;
ELSIF(LOCAL_CNT < DATA_PART_CNT) THEN
LOCAL_CNT <= LOCAL_CNT+1;
ELSE
LOCAL_CNT <= 1;
END IF;
ELSE
LOCAL_CNT <= 1;
END IF;
END IF;
END PROCESS;
RAND_GEN:FOR N IN LOOP_COUNT-1 DOWNTO 0 GENERATE
RAND_GEN_INST:ENTITY work.RANDOM
GENERIC MAP(
WIDTH => 8,
SEED => (SEED+N)
)
PORT MAP(
CLK => CLK,
RST => RST,
EN => DATA_GEN_I,
RANDOM_NUM => RAND_DATA(8*(N+1)-1 DOWNTO 8*N)
);
END GENERATE RAND_GEN;
END ARCHITECTURE;
@@ -0,0 +1,112 @@
--------------------------------------------------------------------------------
--
-- BLK MEM GEN v7_3 Core - Random Number Generator
--
--------------------------------------------------------------------------------
--
-- (c) Copyright 2006_3010 Xilinx, Inc. All rights reserved.
--
-- This file contains confidential and proprietary information
-- of Xilinx, Inc. and is protected under U.S. and
-- international copyright and other intellectual property
-- laws.
--
-- DISCLAIMER
-- This disclaimer is not a license and does not grant any
-- rights to the materials distributed herewith. Except as
-- otherwise provided in a valid license issued to you by
-- Xilinx, and to the maximum extent permitted by applicable
-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
-- (2) Xilinx shall not be liable (whether in contract or tort,
-- including negligence, or under any other theory of
-- liability) for any loss or damage of any kind or nature
-- related to, arising under or in connection with these
-- materials, including for any direct, or any indirect,
-- special, incidental, or consequential loss or damage
-- (including loss of data, profits, goodwill, or any type of
-- loss or damage suffered as a result of any action brought
-- by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the
-- possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-
-- safe, or for use in any application requiring fail-safe
-- performance, such as life-support or safety devices or
-- systems, Class III medical devices, nuclear facilities,
-- applications related to the deployment of airbags, or any
-- other applications that could lead to death, personal
-- injury, or severe property or environmental damage
-- (individually and collectively, "Critical
-- Applications"). Customer assumes the sole risk and
-- liability of any use of Xilinx products in Critical
-- Applications, subject only to applicable laws and
-- regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
-- PART OF THIS FILE AT ALL TIMES.
--------------------------------------------------------------------------------
--
-- Filename: random.vhd
--
-- Description:
-- Random Generator
--
--------------------------------------------------------------------------------
-- Author: IP Solutions Division
--
-- History: Sep 12, 2011 - First Release
--------------------------------------------------------------------------------
--
--------------------------------------------------------------------------------
-- Library Declarations
--------------------------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY RANDOM IS
GENERIC ( WIDTH : INTEGER := 32;
SEED : INTEGER :=2
);
PORT (
CLK : IN STD_LOGIC;
RST : IN STD_LOGIC;
EN : IN STD_LOGIC;
RANDOM_NUM : OUT STD_LOGIC_VECTOR (WIDTH-1 DOWNTO 0) --OUTPUT VECTOR
);
END RANDOM;
ARCHITECTURE BEHAVIORAL OF RANDOM IS
BEGIN
PROCESS(CLK)
VARIABLE RAND_TEMP : STD_LOGIC_VECTOR(WIDTH-1 DOWNTO 0):=CONV_STD_LOGIC_VECTOR(SEED,WIDTH);
VARIABLE TEMP : STD_LOGIC := '0';
BEGIN
IF(RISING_EDGE(CLK)) THEN
IF(RST='1') THEN
RAND_TEMP := CONV_STD_LOGIC_VECTOR(SEED,WIDTH);
ELSE
IF(EN = '1') THEN
TEMP := RAND_TEMP(WIDTH-1) XOR RAND_TEMP(WIDTH-2);
RAND_TEMP(WIDTH-1 DOWNTO 1) := RAND_TEMP(WIDTH-2 DOWNTO 0);
RAND_TEMP(0) := TEMP;
END IF;
END IF;
END IF;
RANDOM_NUM <= RAND_TEMP;
END PROCESS;
END ARCHITECTURE;
@@ -0,0 +1,322 @@
--------------------------------------------------------------------------------
--
-- BLK MEM GEN v7_3 Core - Synthesizable Testbench
--
--------------------------------------------------------------------------------
--
-- (c) Copyright 2006_3010 Xilinx, Inc. All rights reserved.
--
-- This file contains confidential and proprietary information
-- of Xilinx, Inc. and is protected under U.S. and
-- international copyright and other intellectual property
-- laws.
--
-- DISCLAIMER
-- This disclaimer is not a license and does not grant any
-- rights to the materials distributed herewith. Except as
-- otherwise provided in a valid license issued to you by
-- Xilinx, and to the maximum extent permitted by applicable
-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
-- (2) Xilinx shall not be liable (whether in contract or tort,
-- including negligence, or under any other theory of
-- liability) for any loss or damage of any kind or nature
-- related to, arising under or in connection with these
-- materials, including for any direct, or any indirect,
-- special, incidental, or consequential loss or damage
-- (including loss of data, profits, goodwill, or any type of
-- loss or damage suffered as a result of any action brought
-- by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the
-- possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-
-- safe, or for use in any application requiring fail-safe
-- performance, such as life-support or safety devices or
-- systems, Class III medical devices, nuclear facilities,
-- applications related to the deployment of airbags, or any
-- other applications that could lead to death, personal
-- injury, or severe property or environmental damage
-- (individually and collectively, "Critical
-- Applications"). Customer assumes the sole risk and
-- liability of any use of Xilinx products in Critical
-- Applications, subject only to applicable laws and
-- regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
-- PART OF THIS FILE AT ALL TIMES.
--------------------------------------------------------------------------------
--
-- Filename: result_bram_synth.vhd
--
-- Description:
-- Synthesizable Testbench
--------------------------------------------------------------------------------
-- Author: IP Solutions Division
--
-- History: Sep 12, 2011 - First Release
--------------------------------------------------------------------------------
--
--------------------------------------------------------------------------------
-- Library Declarations
--------------------------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.NUMERIC_STD.ALL;
USE IEEE.STD_LOGIC_MISC.ALL;
LIBRARY STD;
USE STD.TEXTIO.ALL;
--LIBRARY unisim;
--USE unisim.vcomponents.ALL;
LIBRARY work;
USE work.ALL;
USE work.BMG_TB_PKG.ALL;
ENTITY result_bram_synth IS
PORT(
CLK_IN : IN STD_LOGIC;
CLKB_IN : IN STD_LOGIC;
RESET_IN : IN STD_LOGIC;
STATUS : OUT STD_LOGIC_VECTOR(8 DOWNTO 0) := (OTHERS => '0') --ERROR STATUS OUT OF FPGA
);
END ENTITY;
ARCHITECTURE result_bram_synth_ARCH OF result_bram_synth IS
COMPONENT result_bram_exdes
PORT (
--Inputs - Port A
WEA : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
ADDRA : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
DINA : IN STD_LOGIC_VECTOR(191 DOWNTO 0);
CLKA : IN STD_LOGIC;
--Inputs - Port B
ADDRB : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
DOUTB : OUT STD_LOGIC_VECTOR(191 DOWNTO 0);
CLKB : IN STD_LOGIC
);
END COMPONENT;
SIGNAL CLKA: STD_LOGIC := '0';
SIGNAL RSTA: STD_LOGIC := '0';
SIGNAL WEA: STD_LOGIC_VECTOR(0 DOWNTO 0) := (OTHERS => '0');
SIGNAL WEA_R: STD_LOGIC_VECTOR(0 DOWNTO 0) := (OTHERS => '0');
SIGNAL ADDRA: STD_LOGIC_VECTOR(7 DOWNTO 0) := (OTHERS => '0');
SIGNAL ADDRA_R: STD_LOGIC_VECTOR(7 DOWNTO 0) := (OTHERS => '0');
SIGNAL DINA: STD_LOGIC_VECTOR(191 DOWNTO 0) := (OTHERS => '0');
SIGNAL DINA_R: STD_LOGIC_VECTOR(191 DOWNTO 0) := (OTHERS => '0');
SIGNAL CLKB: STD_LOGIC := '0';
SIGNAL RSTB: STD_LOGIC := '0';
SIGNAL ADDRB: STD_LOGIC_VECTOR(7 DOWNTO 0) := (OTHERS => '0');
SIGNAL ADDRB_R: STD_LOGIC_VECTOR(7 DOWNTO 0) := (OTHERS => '0');
SIGNAL DOUTB: STD_LOGIC_VECTOR(191 DOWNTO 0);
SIGNAL CHECKER_EN : STD_LOGIC:='0';
SIGNAL CHECKER_EN_R : STD_LOGIC:='0';
SIGNAL STIMULUS_FLOW : STD_LOGIC_VECTOR(22 DOWNTO 0) := (OTHERS =>'0');
SIGNAL clk_in_i: STD_LOGIC;
SIGNAL RESET_SYNC_R1 : STD_LOGIC:='1';
SIGNAL RESET_SYNC_R2 : STD_LOGIC:='1';
SIGNAL RESET_SYNC_R3 : STD_LOGIC:='1';
SIGNAL clkb_in_i: STD_LOGIC;
SIGNAL RESETB_SYNC_R1 : STD_LOGIC := '1';
SIGNAL RESETB_SYNC_R2 : STD_LOGIC := '1';
SIGNAL RESETB_SYNC_R3 : STD_LOGIC := '1';
SIGNAL ITER_R0 : STD_LOGIC := '0';
SIGNAL ITER_R1 : STD_LOGIC := '0';
SIGNAL ITER_R2 : STD_LOGIC := '0';
SIGNAL ISSUE_FLAG : STD_LOGIC_VECTOR(7 DOWNTO 0) := (OTHERS => '0');
SIGNAL ISSUE_FLAG_STATUS : STD_LOGIC_VECTOR(7 DOWNTO 0) := (OTHERS => '0');
BEGIN
-- clk_buf: bufg
-- PORT map(
-- i => CLK_IN,
-- o => clk_in_i
-- );
clk_in_i <= CLK_IN;
CLKA <= clk_in_i;
-- clkb_buf: bufg
-- PORT map(
-- i => CLKB_IN,
-- o => clkb_in_i
-- );
clkb_in_i <= CLKB_IN;
CLKB <= clkb_in_i;
RSTA <= RESET_SYNC_R3 AFTER 50 ns;
PROCESS(clk_in_i)
BEGIN
IF(RISING_EDGE(clk_in_i)) THEN
RESET_SYNC_R1 <= RESET_IN;
RESET_SYNC_R2 <= RESET_SYNC_R1;
RESET_SYNC_R3 <= RESET_SYNC_R2;
END IF;
END PROCESS;
RSTB <= RESETB_SYNC_R3 AFTER 50 ns;
PROCESS(clkb_in_i)
BEGIN
IF(RISING_EDGE(clkb_in_i)) THEN
RESETB_SYNC_R1 <= RESET_IN;
RESETB_SYNC_R2 <= RESETB_SYNC_R1;
RESETB_SYNC_R3 <= RESETB_SYNC_R2;
END IF;
END PROCESS;
PROCESS(CLKA)
BEGIN
IF(RISING_EDGE(CLKA)) THEN
IF(RESET_SYNC_R3='1') THEN
ISSUE_FLAG_STATUS<= (OTHERS => '0');
ELSE
ISSUE_FLAG_STATUS <= ISSUE_FLAG_STATUS OR ISSUE_FLAG;
END IF;
END IF;
END PROCESS;
STATUS(7 DOWNTO 0) <= ISSUE_FLAG_STATUS;
BMG_DATA_CHECKER_INST: ENTITY work.CHECKER
GENERIC MAP (
WRITE_WIDTH => 192,
READ_WIDTH => 192 )
PORT MAP (
CLK => clkb_in_i,
RST => RSTB,
EN => CHECKER_EN_R,
DATA_IN => DOUTB,
STATUS => ISSUE_FLAG(0)
);
PROCESS(clkb_in_i)
BEGIN
IF(RISING_EDGE(clkb_in_i)) THEN
IF(RSTB='1') THEN
CHECKER_EN_R <= '0';
ELSE
CHECKER_EN_R <= CHECKER_EN AFTER 50 ns;
END IF;
END IF;
END PROCESS;
BMG_STIM_GEN_INST:ENTITY work.BMG_STIM_GEN
PORT MAP(
CLKA => clk_in_i,
CLKB => clkb_in_i,
TB_RST => RSTA,
ADDRA => ADDRA,
DINA => DINA,
WEA => WEA,
ADDRB => ADDRB,
CHECK_DATA => CHECKER_EN
);
PROCESS(CLKA)
BEGIN
IF(RISING_EDGE(CLKA)) THEN
IF(RESET_SYNC_R3='1') THEN
STATUS(8) <= '0';
iter_r2 <= '0';
iter_r1 <= '0';
iter_r0 <= '0';
ELSE
STATUS(8) <= iter_r2;
iter_r2 <= iter_r1;
iter_r1 <= iter_r0;
iter_r0 <= STIMULUS_FLOW(8);
END IF;
END IF;
END PROCESS;
PROCESS(CLKA)
BEGIN
IF(RISING_EDGE(CLKA)) THEN
IF(RESET_SYNC_R3='1') THEN
STIMULUS_FLOW <= (OTHERS => '0');
ELSIF(WEA(0)='1') THEN
STIMULUS_FLOW <= STIMULUS_FLOW+1;
END IF;
END IF;
END PROCESS;
PROCESS(CLKA)
BEGIN
IF(RISING_EDGE(CLKA)) THEN
IF(RESET_SYNC_R3='1') THEN
WEA_R <= (OTHERS=>'0') AFTER 50 ns;
DINA_R <= (OTHERS=>'0') AFTER 50 ns;
ELSE
WEA_R <= WEA AFTER 50 ns;
DINA_R <= DINA AFTER 50 ns;
END IF;
END IF;
END PROCESS;
PROCESS(CLKA)
BEGIN
IF(RISING_EDGE(CLKA)) THEN
IF(RESET_SYNC_R3='1') THEN
ADDRA_R <= (OTHERS=> '0') AFTER 50 ns;
ADDRB_R <= (OTHERS=> '0') AFTER 50 ns;
ELSE
ADDRA_R <= ADDRA AFTER 50 ns;
ADDRB_R <= ADDRB AFTER 50 ns;
END IF;
END IF;
END PROCESS;
BMG_PORT: result_bram_exdes PORT MAP (
--Port A
WEA => WEA_R,
ADDRA => ADDRA_R,
DINA => DINA_R,
CLKA => CLKA,
--Port B
ADDRB => ADDRB_R,
DOUTB => DOUTB,
CLKB => CLKB
);
END ARCHITECTURE;
@@ -0,0 +1,142 @@
--------------------------------------------------------------------------------
--
-- BLK MEM GEN v7_3 Core - Top File for the Example Testbench
--
--------------------------------------------------------------------------------
--
-- (c) Copyright 2006_3010 Xilinx, Inc. All rights reserved.
--
-- This file contains confidential and proprietary information
-- of Xilinx, Inc. and is protected under U.S. and
-- international copyright and other intellectual property
-- laws.
--
-- DISCLAIMER
-- This disclaimer is not a license and does not grant any
-- rights to the materials distributed herewith. Except as
-- otherwise provided in a valid license issued to you by
-- Xilinx, and to the maximum extent permitted by applicable
-- law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND
-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
-- (2) Xilinx shall not be liable (whether in contract or tort,
-- including negligence, or under any other theory of
-- liability) for any loss or damage of any kind or nature
-- related to, arising under or in connection with these
-- materials, including for any direct, or any indirect,
-- special, incidental, or consequential loss or damage
-- (including loss of data, profits, goodwill, or any type of
-- loss or damage suffered as a result of any action brought
-- by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the
-- possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-
-- safe, or for use in any application requiring fail-safe
-- performance, such as life-support or safety devices or
-- systems, Class III medical devices, nuclear facilities,
-- applications related to the deployment of airbags, or any
-- other applications that could lead to death, personal
-- injury, or severe property or environmental damage
-- (individually and collectively, "Critical
-- Applications"). Customer assumes the sole risk and
-- liability of any use of Xilinx products in Critical
-- Applications, subject only to applicable laws and
-- regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
-- PART OF THIS FILE AT ALL TIMES.
--------------------------------------------------------------------------------
-- Filename: result_bram_tb.vhd
-- Description:
-- Testbench Top
--------------------------------------------------------------------------------
-- Author: IP Solutions Division
--
-- History: Sep 12, 2011 - First Release
--------------------------------------------------------------------------------
--
--------------------------------------------------------------------------------
-- Library Declarations
--------------------------------------------------------------------------------
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
LIBRARY work;
USE work.ALL;
ENTITY result_bram_tb IS
END ENTITY;
ARCHITECTURE result_bram_tb_ARCH OF result_bram_tb IS
SIGNAL STATUS : STD_LOGIC_VECTOR(8 DOWNTO 0);
SIGNAL CLK : STD_LOGIC := '1';
SIGNAL CLKB : STD_LOGIC := '1';
SIGNAL RESET : STD_LOGIC;
BEGIN
CLK_GEN: PROCESS BEGIN
CLK <= NOT CLK;
WAIT FOR 100 NS;
CLK <= NOT CLK;
WAIT FOR 100 NS;
END PROCESS;
CLKB_GEN: PROCESS BEGIN
CLKB <= NOT CLKB;
WAIT FOR 100 NS;
CLKB <= NOT CLKB;
WAIT FOR 100 NS;
END PROCESS;
RST_GEN: PROCESS BEGIN
RESET <= '1';
WAIT FOR 1000 NS;
RESET <= '0';
WAIT;
END PROCESS;
--STOP_SIM: PROCESS BEGIN
-- WAIT FOR 200 US; -- STOP SIMULATION AFTER 1 MS
-- ASSERT FALSE
-- REPORT "END SIMULATION TIME REACHED"
-- SEVERITY FAILURE;
--END PROCESS;
--
PROCESS BEGIN
WAIT UNTIL STATUS(8)='1';
IF( STATUS(7 downto 0)/="0") THEN
ASSERT false
REPORT "Test Completed Successfully"
SEVERITY NOTE;
REPORT "Simulation Failed"
SEVERITY FAILURE;
ELSE
ASSERT false
REPORT "TEST PASS"
SEVERITY NOTE;
REPORT "Test Completed Successfully"
SEVERITY FAILURE;
END IF;
END PROCESS;
result_bram_synth_inst:ENTITY work.result_bram_synth
PORT MAP(
CLK_IN => CLK,
CLKB_IN => CLK,
RESET_IN => RESET,
STATUS => STATUS
);
END ARCHITECTURE;
@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<generated_project xmlns="http://www.xilinx.com/XMLSchema" xmlns:xil_pn="http://www.xilinx.com/XMLSchema">
<!-- -->
<!-- For tool use only. Do not edit. -->
<!-- -->
<!-- ProjectNavigator created generated project file. -->
<!-- For use in tracking generated file and other information -->
<!-- allowing preservation of process status. -->
<!-- -->
<!-- Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved. -->
<version xmlns="http://www.xilinx.com/XMLSchema">11.1</version>
<sourceproject xmlns="http://www.xilinx.com/XMLSchema" xil_pn:fileType="FILE_XISE" xil_pn:name="wide_mult.xise"/>
<files xmlns="http://www.xilinx.com/XMLSchema">
<file xil_pn:fileType="FILE_ASY" xil_pn:name="wide_mult.asy" xil_pn:origination="imported"/>
<file xil_pn:fileType="FILE_SYMBOL" xil_pn:name="wide_mult.sym" xil_pn:origination="imported"/>
<file xil_pn:fileType="FILE_VHO" xil_pn:name="wide_mult.vho" xil_pn:origination="imported"/>
</files>
<transforms xmlns="http://www.xilinx.com/XMLSchema">
<transform xil_pn:end_ts="1654646662" xil_pn:name="TRAN_copyInitialToXSTAbstractSynthesis" xil_pn:start_ts="1654646662">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1654895235" xil_pn:name="TRAN_schematicsToHdl" xil_pn:prop_ck="4659816854749047906" xil_pn:start_ts="1654895235">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1654895235" xil_pn:name="TRAN_regenerateCores" xil_pn:prop_ck="-5812453015497774159" xil_pn:start_ts="1654895235">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1654895235" xil_pn:name="TRAN_SubProjectAbstractToPreProxy" xil_pn:start_ts="1654895235">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
<transform xil_pn:end_ts="1654895235" xil_pn:name="TRAN_xawsTohdl" xil_pn:prop_ck="7916142474556992292" xil_pn:start_ts="1654895235">
<status xil_pn:value="SuccessfullyRun"/>
<status xil_pn:value="ReadyToRun"/>
</transform>
</transforms>
</generated_project>
@@ -0,0 +1,102 @@
--------------------------------------------------------------------------------
-- This file is owned and controlled by Xilinx and must be used solely --
-- for design, simulation, implementation and creation of design files --
-- limited to Xilinx devices or technologies. Use with non-Xilinx --
-- devices or technologies is expressly prohibited and immediately --
-- terminates your license. --
-- --
-- XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" SOLELY --
-- FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR XILINX DEVICES. BY --
-- PROVIDING THIS DESIGN, CODE, OR INFORMATION AS ONE POSSIBLE --
-- IMPLEMENTATION OF THIS FEATURE, APPLICATION OR STANDARD, XILINX IS --
-- MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION IS FREE FROM ANY --
-- CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE FOR OBTAINING ANY --
-- RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY --
-- DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE --
-- IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR --
-- REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF --
-- INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A --
-- PARTICULAR PURPOSE. --
-- --
-- Xilinx products are not intended for use in life support appliances, --
-- devices, or systems. Use in such applications are expressly --
-- prohibited. --
-- --
-- (c) Copyright 1995-2022 Xilinx, Inc. --
-- All rights reserved. --
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- You must compile the wrapper file wide_mult.vhd when simulating
-- the core, wide_mult. When compiling the wrapper file, be sure to
-- reference the XilinxCoreLib VHDL simulation library. For detailed
-- instructions, please refer to the "CORE Generator Help".
-- The synthesis directives "translate_off/translate_on" specified
-- below are supported by Xilinx, Mentor Graphics and Synplicity
-- synthesis tools. Ensure they are correct for your synthesis tool(s).
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
-- synthesis translate_off
LIBRARY XilinxCoreLib;
-- synthesis translate_on
ENTITY wide_mult IS
PORT (
clk : IN STD_LOGIC;
a : IN STD_LOGIC_VECTOR(12 DOWNTO 0);
b : IN STD_LOGIC_VECTOR(26 DOWNTO 0);
ce : IN STD_LOGIC;
p : OUT STD_LOGIC_VECTOR(39 DOWNTO 0)
);
END wide_mult;
ARCHITECTURE wide_mult_a OF wide_mult IS
-- synthesis translate_off
COMPONENT wrapped_wide_mult
PORT (
clk : IN STD_LOGIC;
a : IN STD_LOGIC_VECTOR(12 DOWNTO 0);
b : IN STD_LOGIC_VECTOR(26 DOWNTO 0);
ce : IN STD_LOGIC;
p : OUT STD_LOGIC_VECTOR(39 DOWNTO 0)
);
END COMPONENT;
-- Configuration specification
FOR ALL : wrapped_wide_mult USE ENTITY XilinxCoreLib.mult_gen_v11_2(behavioral)
GENERIC MAP (
c_a_type => 1,
c_a_width => 13,
c_b_type => 1,
c_b_value => "10000001",
c_b_width => 27,
c_ccm_imp => 0,
c_ce_overrides_sclr => 0,
c_has_ce => 1,
c_has_sclr => 0,
c_has_zero_detect => 0,
c_latency => 5,
c_model_type => 0,
c_mult_type => 1,
c_optimize_goal => 1,
c_out_high => 39,
c_out_low => 0,
c_round_output => 0,
c_round_pt => 0,
c_verbosity => 0,
c_xdevicefamily => "spartan6"
);
-- synthesis translate_on
BEGIN
-- synthesis translate_off
U0 : wrapped_wide_mult
PORT MAP (
clk => clk,
a => a,
b => b,
ce => ce,
p => p
);
-- synthesis translate_on
END wide_mult_a;
@@ -0,0 +1,6 @@
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
package BuildConfig is
constant EXTERNAL_MASTER_LO_SLAVE : boolean := false;
end package BuildConfig;
@@ -0,0 +1,6 @@
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
package BuildConfig is
constant EXTERNAL_MASTER_LO_SLAVE : boolean := true;
end package BuildConfig;
@@ -0,0 +1,358 @@
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 20:38:37 09/18/2020
-- Design Name:
-- Module Name: DFT - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity DFT is
Generic (BINS : integer);
Port ( CLK : in STD_LOGIC;
RESET : in STD_LOGIC;
PORT1 : in STD_LOGIC_VECTOR (17 downto 0);
PORT2 : in STD_LOGIC_VECTOR (17 downto 0);
NEW_SAMPLE : in STD_LOGIC;
NSAMPLES : in STD_LOGIC_VECTOR (12 downto 0);
BIN1_PHASEINC : in STD_LOGIC_VECTOR (15 downto 0);
DIFFBIN_PHASEINC : in STD_LOGIC_VECTOR (15 downto 0);
RESULT_READY : out STD_LOGIC;
OUTPUT : out STD_LOGIC_VECTOR (191 downto 0);
NEXT_OUTPUT : in STD_LOGIC);
end DFT;
architecture Behavioral of DFT is
COMPONENT result_bram
PORT (
clka : IN STD_LOGIC;
wea : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
addra : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
dina : IN STD_LOGIC_VECTOR(191 DOWNTO 0);
clkb : IN STD_LOGIC;
addrb : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
doutb : OUT STD_LOGIC_VECTOR(191 DOWNTO 0)
);
END COMPONENT;
COMPONENT SinCos
PORT (
clk : IN STD_LOGIC;
phase_in : IN STD_LOGIC_VECTOR(11 DOWNTO 0);
cosine : OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
sine : OUT STD_LOGIC_VECTOR(15 DOWNTO 0)
);
END COMPONENT;
COMPONENT DSP_SLICE
PORT (
clk : IN STD_LOGIC;
ce : IN STD_LOGIC;
sel : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
a : IN STD_LOGIC_VECTOR(17 DOWNTO 0);
b : IN STD_LOGIC_VECTOR(17 DOWNTO 0);
c : IN STD_LOGIC_VECTOR(47 DOWNTO 0);
p : OUT STD_LOGIC_VECTOR(47 DOWNTO 0)
);
END COMPONENT;
COMPONENT window
PORT(
CLK : IN std_logic;
INDEX : IN std_logic_vector(6 downto 0);
WINDOW_TYPE : IN std_logic_vector(1 downto 0);
VALUE : OUT std_logic_vector(15 downto 0)
);
END COMPONENT;
--type result is array(BINS-1 downto 0) of std_logic_vector(47 downto 0);
--signal port1_real : result;
--signal port1_imag : result;
--signal port2_real : result;
--signal port2_imag : result;
--signal port1_real_read : std_logic_vector(47 downto 0);
--signal port1_imag_read : std_logic_vector(47 downto 0);
--signal port2_real_read : std_logic_vector(47 downto 0);
--signal port2_imag_read : std_logic_vector(47 downto 0);
signal sample_cnt : integer range 0 to 131072;
signal samples_to_take : integer range 0 to 131072;
signal bin_cnt : integer range 0 to BINS+2;
signal read_address : integer range 0 to BINS-1;
signal write_address : integer range 0 to BINS-1;
signal read_address_vector : std_logic_vector(7 downto 0);
signal write_address_vector : std_logic_vector(7 downto 0);
signal we : std_logic_vector(0 downto 0);
signal ram_in : std_logic_vector(191 downto 0);
signal ram_out : std_logic_vector(191 downto 0);
type States is (WaitingForSample, WaitMult, WaitSinCos, Busy, Ready);
signal state : States;
signal port1_latch : std_logic_vector(17 downto 0);
signal port2_latch : std_logic_vector(17 downto 0);
signal phase : std_logic_vector(31 downto 0);
signal phase_inc : std_logic_vector(31 downto 0);
signal sine : std_logic_vector(15 downto 0);
signal cosine : std_logic_vector(15 downto 0);
signal mult1_a : std_logic_vector(17 downto 0);
signal mult1_b : std_logic_vector(17 downto 0);
signal mult1_c : std_logic_vector(47 downto 0);
signal mult1_p : std_logic_vector(47 downto 0);
signal mult2_a : std_logic_vector(17 downto 0);
signal mult2_b : std_logic_vector(17 downto 0);
signal mult2_c : std_logic_vector(47 downto 0);
signal mult2_p : std_logic_vector(47 downto 0);
signal mult3_a : std_logic_vector(17 downto 0);
signal mult3_b : std_logic_vector(17 downto 0);
signal mult3_c : std_logic_vector(47 downto 0);
signal mult3_p : std_logic_vector(47 downto 0);
signal mult4_a : std_logic_vector(17 downto 0);
signal mult4_b : std_logic_vector(17 downto 0);
signal mult4_c : std_logic_vector(47 downto 0);
signal mult4_p : std_logic_vector(47 downto 0);
signal mult_enable : std_logic;
signal mult_accumulate : std_logic_vector(0 downto 0);
begin
LookupTable : SinCos
PORT MAP (
clk => CLK,
phase_in => phase(31 downto 20),
cosine => cosine,
sine => sine
);
Mult1 : DSP_SLICE
PORT MAP (
clk => CLK,
ce => mult_enable,
sel => mult_accumulate,
a => mult1_a,
b => mult1_b,
c => mult1_c,
p => mult1_p
);
Mult2 : DSP_SLICE
PORT MAP (
clk => CLK,
ce => mult_enable,
sel => mult_accumulate,
a => mult2_a,
b => mult2_b,
c => mult2_c,
p => mult2_p
);
Mult3 : DSP_SLICE
PORT MAP (
clk => CLK,
ce => mult_enable,
sel => mult_accumulate,
a => mult3_a,
b => mult3_b,
c => mult3_c,
p => mult3_p
);
Mult4 : DSP_SLICE
PORT MAP (
clk => CLK,
ce => mult_enable,
sel => mult_accumulate,
a => mult4_a,
b => mult4_b,
c => mult4_c,
p => mult4_p
);
result_ram: result_bram
PORT MAP (
clka => CLK,
wea => we,
addra => write_address_vector,
dina => ram_in,
clkb => CLK,
addrb => read_address_vector,
doutb => ram_out
);
read_address_vector <= std_logic_vector(to_unsigned(read_address, 8));
write_address_vector <= std_logic_vector(to_unsigned(write_address, 8));
OUTPUT <= ram_out;
mult1_c <= ram_out(191 downto 144);
mult2_c <= ram_out(143 downto 96);
mult3_c <= ram_out(95 downto 48);
mult4_c <= ram_out(47 downto 0);
ram_in <= mult1_p & mult2_p & mult3_p & mult4_p;
process(CLK, RESET)
begin
if rising_edge(CLK) then
if RESET = '1' then
mult_enable <= '0';
mult_accumulate <= "0";
sample_cnt <= 0;
RESULT_READY <= '0';
read_address <= 0;
write_address <= 0;
we <= "0";
state <= WaitingForSample;
else
samples_to_take <= to_integer(unsigned(NSAMPLES & "0000")) - 1;
case state is
when WaitingForSample =>
we <= "0";
mult_enable <= '0';
mult_accumulate <= "0";
read_address <= 0;
write_address <= 0;
if NEW_SAMPLE = '1' then
-- calculate phase for initial bin
mult1_a <= std_logic_vector(to_unsigned(sample_cnt, 18));
mult1_b <= "00" & BIN1_PHASEINC;
mult2_a <= std_logic_vector(to_unsigned(sample_cnt, 18));
mult2_b <= "00" & DIFFBIN_PHASEINC;
state <= WaitMult;
bin_cnt <= 0;
mult_enable <= '1';
end if;
when WaitMult =>
RESULT_READY <= '0';
we <= "0";
mult_enable <= '1';
mult_accumulate <= "0";
read_address <= 0;
write_address <= 0;
if bin_cnt < 4 then
bin_cnt <= bin_cnt + 1;
else
bin_cnt <= 0;
mult_enable <= '0';
state <= WaitSinCos;
phase <= mult1_p(15 downto 0) & "0000000000000000";
phase_inc <= mult2_p(23 downto 0) & "00000000";
port1_latch <= PORT1;
port2_latch <= PORT2;
end if;
when WaitSinCos =>
phase <= std_logic_vector(unsigned(phase)+unsigned(phase_inc));
RESULT_READY <= '0';
we <= "0";
mult_enable <= '0';
mult_accumulate <= "0";
read_address <= 0;
write_address <= 0;
if bin_cnt < 6 then
bin_cnt <= bin_cnt + 1;
else
bin_cnt <= 0;
mult_enable <= '1';
read_address <= 1;
-- sign extended multiplication
mult1_a <= port1_latch;
mult1_b <= sine(15) & sine(15) & sine;
mult2_a <= port1_latch;
mult2_b <= cosine(15) & cosine(15) & cosine;
mult3_a <= port2_latch;
mult3_b <= sine(15) & sine(15) & sine;
mult4_a <= port2_latch;
mult4_b <= cosine(15) & cosine(15) & cosine;
state <= BUSY;
if sample_cnt = 0 then
mult_accumulate <= "0";
else
mult_accumulate <= "1";
end if;
end if;
when BUSY =>
mult_enable <= '1';
if sample_cnt = 0 then
mult_accumulate <= "0";
else
mult_accumulate <= "1";
end if;
RESULT_READY <= '0';
phase <= std_logic_vector(unsigned(phase)+unsigned(phase_inc));
-- sign extended multiplication
mult1_a <= port1_latch;
mult1_b <= sine(15) & sine(15) & sine;
mult2_a <= port1_latch;
mult2_b <= cosine(15) & cosine(15) & cosine;
mult3_a <= port2_latch;
mult3_b <= sine(15) & sine(15) & sine;
mult4_a <= port2_latch;
mult4_b <= cosine(15) & cosine(15) & cosine;
if bin_cnt >= 3 then
-- multiplier result is available, advance write address
we <= "1";
write_address <= bin_cnt - 3;
else
we <= "0";
write_address <= 0;
end if;
if bin_cnt >= BINS+2 then
read_address <= 0;
if sample_cnt < samples_to_take then
sample_cnt <= sample_cnt + 1;
state <= WaitingForSample;
else
state <= Ready;
end if;
else
bin_cnt <= bin_cnt + 1;
if bin_cnt < BINS - 2 then
read_address <= bin_cnt + 2;
end if;
end if;
when Ready =>
we <= "0";
RESULT_READY <= '1';
write_address <= 0;
if NEXT_OUTPUT = '1' then
-- fetch next entry from RAM
if read_address < BINS - 1 then
read_address <= read_address + 1;
else
RESULT_READY <= '0';
sample_cnt <= 0;
mult_enable <= '0';
state <= WaitingForSample;
read_address <= 0;
end if;
end if;
when others =>
state <= WaitingForSample;
end case;
end if;
end if;
end process;
end Behavioral;
@@ -0,0 +1,128 @@
1111111111111000
1111111111110110
1111111111110001
1111111111101001
1111111111011111
1111111111010001
1111111110111111
1111111110101001
1111111110001110
1111111101101110
1111111101001000
1111111100011100
1111111011101001
1111111010101111
1111111001101111
1111111000101000
1111110111011011
1111110110001000
1111110100110001
1111110011011000
1111110001111101
1111110000100011
1111101111001101
1111101101111101
1111101100110111
1111101011111110
1111101011010111
1111101011000100
1111101011001011
1111101011110001
1111101100111001
1111101110101000
1111110001000011
1111110100001110
1111111000001100
1111111101000001
0000000010101110
0000001001011001
0000010001000000
0000011001100100
0000100011000101
0000101101100010
0000111000111000
0001000101000100
0001010010000000
0001011111100111
0001101101110011
0001111100011100
0010001011011001
0010011010100001
0010101001101011
0010111000101100
0011000111011001
0011010101101000
0011100011001110
0011110000000000
0011111011110100
0100000110100001
0100001111111101
0100011000000010
0100011110101000
0100100011101001
0100100111000010
0100101000101111
0100101000101111
0100100111000010
0100100011101001
0100011110101000
0100011000000010
0100001111111101
0100000110100001
0011111011110100
0011110000000000
0011100011001110
0011010101101000
0011000111011001
0010111000101100
0010101001101011
0010011010100001
0010001011011001
0001111100011100
0001101101110011
0001011111100111
0001010010000000
0001000101000100
0000111000111000
0000101101100010
0000100011000101
0000011001100100
0000010001000000
0000001001011001
0000000010101110
1111111101000001
1111111000001100
1111110100001110
1111110001000011
1111101110101000
1111101100111001
1111101011110001
1111101011001011
1111101011000100
1111101011010111
1111101011111110
1111101100110111
1111101101111101
1111101111001101
1111110000100011
1111110001111101
1111110011011000
1111110100110001
1111110110001000
1111110111011011
1111111000101000
1111111001101111
1111111010101111
1111111011101001
1111111100011100
1111111101001000
1111111101101110
1111111110001110
1111111110101001
1111111110111111
1111111111010001
1111111111011111
1111111111101001
1111111111110001
1111111111110110
1111111111111000
@@ -0,0 +1,128 @@
0000000000000001
0000000000001011
0000000000011110
0000000000111100
0000000001100011
0000000010010100
0000000011001110
0000000100010010
0000000101011111
0000000110110101
0000001000010100
0000001001111011
0000001011101011
0000001101100010
0000001111100010
0000010001101001
0000010011110111
0000010110001100
0000011000101000
0000011011001001
0000011101110000
0000100000011101
0000100011001110
0000100110000100
0000101000111101
0000101011111011
0000101110111011
0000110001111110
0000110101000011
0000111000001010
0000111011010010
0000111110011011
0001000001100100
0001000100101101
0001000111110101
0001001010111100
0001001110000001
0001010001000100
0001010100000100
0001010111000010
0001011001111011
0001011100110001
0001011111100010
0001100010001111
0001100100110110
0001100111010111
0001101001110011
0001101100001000
0001101110010110
0001110000011101
0001110010011101
0001110100010100
0001110110000100
0001110111101011
0001111001001010
0001111010100000
0001111011101101
0001111100110001
0001111101101011
0001111110011100
0001111111000011
0001111111100001
0001111111110100
0001111111111110
0001111111111110
0001111111110100
0001111111100001
0001111111000011
0001111110011100
0001111101101011
0001111100110001
0001111011101101
0001111010100000
0001111001001010
0001110111101011
0001110110000100
0001110100010100
0001110010011101
0001110000011101
0001101110010110
0001101100001000
0001101001110011
0001100111010111
0001100100110110
0001100010001111
0001011111100010
0001011100110001
0001011001111011
0001010111000010
0001010100000100
0001010001000100
0001001110000001
0001001010111100
0001000111110101
0001000100101101
0001000001100100
0000111110011011
0000111011010010
0000111000001010
0000110101000011
0000110001111110
0000101110111011
0000101011111011
0000101000111101
0000100110000100
0000100011001110
0000100000011101
0000011101110000
0000011011001001
0000011000101000
0000010110001100
0000010011110111
0000010001101001
0000001111100010
0000001101100010
0000001011101011
0000001001111011
0000001000010100
0000000110110101
0000000101011111
0000000100010010
0000000011001110
0000000010010100
0000000001100011
0000000000111100
0000000000011110
0000000000001011
0000000000000001

Some files were not shown because too many files have changed in this diff Show More