diff --git a/.gitignore b/.gitignore index 307a966..73c459c 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,10 @@ work/ xvlog.* *simgen.tcl *.log + +# B210 Kintex-7 reproducible Vivado build products +/build/ +*.jou +*.str +*.pb +*.wdb diff --git a/vivado/b210_k7/Makefile b/vivado/b210_k7/Makefile new file mode 100644 index 0000000..a7c5de4 --- /dev/null +++ b/vivado/b210_k7/Makefile @@ -0,0 +1,19 @@ +VIVADO ?= vivado +JOBS ?= 8 + +.PHONY: check project build gui clean + +check: + tclsh check_manifest.tcl + +project: + B210_JOBS=$(JOBS) $(VIVADO) -mode batch -source create_project.tcl + +build: + B210_JOBS=$(JOBS) $(VIVADO) -mode batch -source build.tcl + +gui: + B210_JOBS=$(JOBS) $(VIVADO) -mode gui -source create_project.tcl + +clean: + rm -rf ../../build diff --git a/vivado/b210_k7/README.md b/vivado/b210_k7/README.md new file mode 100644 index 0000000..02e7012 --- /dev/null +++ b/vivado/b210_k7/README.md @@ -0,0 +1,88 @@ +# Kintex-7 B210 Vivado build + +This directory recreates the clone's Vivado project from the canonical source +files stored in Git. The generated `.xpr`, `.srcs`, `.runs`, `.gen`, IP output +products, reports, and bitstreams live under `build/` and are disposable. + +## Historical baseline + +At the `clone-vivado-2024.1` point in history, `sources.tcl` intentionally +matches the original Vivado 2024.1 project source set exactly. In particular it +contains: + +``` +lib/sim/fifo/axi_fifo_2clk_sim.v +``` + +as a synthesis source because that is what the original clone project used. +Do **not** "clean up" that line in the historical baseline commit. The FIFO +repair should be a later Git commit that replaces it with the hardware FIFO/XPM +implementation, making the bug and fix visible in history. + +## Files + +- `project_config.tcl` -- part, top, expected Vivado version, default jobs. +- `sources.tcl` -- explicit source manifest; no recursive globs. +- `create_project.tcl` -- creates a disposable Project-Mode Vivado project. +- `build.tcl` -- full OOC-IP/synthesis/implementation/bitstream build. +- `reports.tcl` -- timing, route, bus-skew, CDC, methodology, utilization, + power, and operating-condition reports. +- `ip/b200_clk_gen/b200_clk_gen.xci` -- version-controlled clock-wizard + customization. It is imported into the generated project so the canonical + XCI is never modified by a build. + +## Check the manifest + +Before starting Vivado: + +```bash +cd vivado/b210_k7 +make check +``` + +For the reconstructed 2024.1 baseline this should report 99 entries and zero missing files. The count is expected to change in later commits when the FIFO/XPM sources are added. + +## Build + +For the historical baseline, use Vivado 2024.1: + +```bash +cd vivado/b210_k7 +make build JOBS=8 +``` + +Equivalent direct command: + +```bash +B210_JOBS=8 vivado -mode batch -source vivado/b210_k7/build.tcl +``` + +Build products are written to: + +``` +build/images/usrp_b210_fpga.bit +build/images/usrp_b210_fpga.bin +build/reports/*.rpt +build/vivado/B210_Project_Firmwire/... +``` + +The `.bin` file is the raw image suitable for UHD's `usrp_b210_fpga.bin`. + +## Intentional Vivado migration + +`project_config.tcl` rejects a different Vivado version by default. During an +explicit migration you can temporarily run: + +```bash +B210_ALLOW_VIVADO_MISMATCH=1 vivado -mode batch -source vivado/b210_k7/create_project.tcl +``` + +Once the migration is validated, change `B210_EXPECTED_VIVADO` in +`project_config.tcl` in the migration commit (for example from `2024.1` to +`2026.1`). + +## Source-control rule + +Edit files under `lib/`, `top/`, and `vivado/b210_k7/`. Never edit a copy under +`build/`. If deleting `build/` prevents a clean rebuild from a fresh checkout, +then a required source is missing from Git or from `sources.tcl`. diff --git a/vivado/b210_k7/build.tcl b/vivado/b210_k7/build.tcl new file mode 100644 index 0000000..5435a0c --- /dev/null +++ b/vivado/b210_k7/build.tcl @@ -0,0 +1,66 @@ +# SPDX-License-Identifier: GPL-3.0-or-later +# Full reproducible build: project -> IP -> synthesis -> implementation -> +# bitstream/bin -> reports -> UHD-named image. + +set B210_SCRIPT_DIR [file dirname [file normalize [info script]]] +source [file join $B210_SCRIPT_DIR create_project.tcl] + +if {[info exists ::env(B210_JOBS)] && $::env(B210_JOBS) ne ""} { + set B210_JOBS $::env(B210_JOBS) +} else { + set B210_JOBS $B210_DEFAULT_JOBS +} + +proc b210_require_run_complete {run_name} { + set status [get_property STATUS [get_runs $run_name]] + if {![string match "*Complete*" $status]} { + error "Vivado run $run_name did not complete successfully: $status" + } +} + +# Reproduce the original project's out-of-context clock-IP synthesis. +foreach ip_obj [get_ips] { + set ip_name [get_property NAME $ip_obj] + create_ip_run -force $ip_obj + set ip_run_name "${ip_name}_synth_1" + if {[llength [get_runs -quiet $ip_run_name]] == 0} { + error "Expected IP synthesis run was not created: $ip_run_name" + } + launch_runs $ip_run_name -jobs $B210_JOBS + wait_on_run $ip_run_name + b210_require_run_complete $ip_run_name +} + +launch_runs synth_1 -jobs $B210_JOBS +wait_on_run synth_1 +b210_require_run_complete synth_1 + +launch_runs impl_1 -to_step write_bitstream -jobs $B210_JOBS +wait_on_run impl_1 +b210_require_run_complete impl_1 + +open_run impl_1 +source [file join $B210_SCRIPT_DIR reports.tcl] + +set B210_IMAGE_DIR [file join $B210_REPO_ROOT build images] +file mkdir $B210_IMAGE_DIR + +set impl_dir [get_property DIRECTORY [get_runs impl_1]] +set bit_src [file join $impl_dir ${B210_TOP}.bit] +set bin_src [file join $impl_dir ${B210_TOP}.bin] + +if {![file exists $bit_src]} { + error "Expected bitstream not found: $bit_src" +} +if {![file exists $bin_src]} { + error "Expected raw bin image not found: $bin_src" +} + +file copy -force $bit_src [file join $B210_IMAGE_DIR usrp_b210_fpga.bit] +file copy -force $bin_src [file join $B210_IMAGE_DIR usrp_b210_fpga.bin] + +puts "" +puts "Build complete." +puts "BIT: [file join $B210_IMAGE_DIR usrp_b210_fpga.bit]" +puts "BIN: [file join $B210_IMAGE_DIR usrp_b210_fpga.bin]" +puts "Reports: $B210_REPORT_DIR" diff --git a/vivado/b210_k7/check_manifest.tcl b/vivado/b210_k7/check_manifest.tcl new file mode 100644 index 0000000..84382d8 --- /dev/null +++ b/vivado/b210_k7/check_manifest.tcl @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: GPL-3.0-or-later +# Lightweight manifest validation. Runs with plain tclsh; Vivado is not needed. + +set B210_SCRIPT_DIR [file dirname [file normalize [info script]]] +set B210_REPO_ROOT [file normalize [file join $B210_SCRIPT_DIR ../..]] +source [file join $B210_SCRIPT_DIR sources.tcl] + +set groups { + B210_GLOBAL_INCLUDE_SOURCES + B210_HDL_SOURCES + B210_NETLIST_SOURCES + B210_MEMORY_SOURCES + B210_IP_SOURCES + B210_CONSTRAINT_SOURCES +} + +set total 0 +set missing 0 +foreach group $groups { + set entries [set $group] + puts [format "%-31s %3d" $group [llength $entries]] + foreach rel $entries { + incr total + set p [file normalize [file join $B210_REPO_ROOT $rel]] + if {![file exists $p]} { + puts stderr "MISSING: $rel" + incr missing + } + } +} + +puts "---------------------------------------" +puts "Manifest entries: $total" +puts "Missing files: $missing" + +if {$missing != 0} { + exit 1 +} diff --git a/vivado/b210_k7/create_project.tcl b/vivado/b210_k7/create_project.tcl new file mode 100644 index 0000000..a9d1e12 --- /dev/null +++ b/vivado/b210_k7/create_project.tcl @@ -0,0 +1,99 @@ +# SPDX-License-Identifier: GPL-3.0-or-later +# Recreate the B210 Kintex-7 Vivado project from version-controlled sources. +# +# This is Project Mode on purpose: it retains Vivado's normal run management +# while keeping the Git tree authoritative and the generated .xpr disposable. + +set B210_SCRIPT_DIR [file dirname [file normalize [info script]]] +set B210_REPO_ROOT [file normalize [file join $B210_SCRIPT_DIR ../..]] + +source [file join $B210_SCRIPT_DIR project_config.tcl] +source [file join $B210_SCRIPT_DIR sources.tcl] + +if {[info exists ::env(B210_BUILD_ROOT)] && $::env(B210_BUILD_ROOT) ne ""} { + set B210_BUILD_ROOT [file normalize $::env(B210_BUILD_ROOT)] +} else { + set B210_BUILD_ROOT [file join $B210_REPO_ROOT build vivado] +} +set B210_PROJECT_DIR [file join $B210_BUILD_ROOT $B210_PROJECT_NAME] + +proc b210_repo_file {relpath} { + global B210_REPO_ROOT + set p [file normalize [file join $B210_REPO_ROOT $relpath]] + if {![file exists $p]} { + error "Manifest source does not exist: $relpath\nResolved path: $p" + } + return $p +} + +# Reproducibility guard. Set B210_ALLOW_VIVADO_MISMATCH=1 only for deliberate +# migration work; once migration is committed, update project_config.tcl. +set actual_vivado [version -short] +if {$actual_vivado ne $B210_EXPECTED_VIVADO} { + set allow 0 + if {[info exists ::env(B210_ALLOW_VIVADO_MISMATCH)]} { + set allow $::env(B210_ALLOW_VIVADO_MISMATCH) + } + if {!$allow} { + error "Expected Vivado $B210_EXPECTED_VIVADO, found $actual_vivado. Set B210_ALLOW_VIVADO_MISMATCH=1 only for intentional migration work." + } + puts "WARNING: expected Vivado $B210_EXPECTED_VIVADO, running $actual_vivado because B210_ALLOW_VIVADO_MISMATCH is set" +} + +file mkdir $B210_BUILD_ROOT +create_project $B210_PROJECT_NAME $B210_PROJECT_DIR \ + -part $B210_PART \ + -force + +set_property target_language Verilog [current_project] +set_property default_lib xil_defaultlib [current_project] + +# Add RTL/netlist/memory files by reference. Nothing is copied into .srcs. +foreach rel $B210_GLOBAL_INCLUDE_SOURCES { + set f [b210_repo_file $rel] + set added [add_files -fileset sources_1 -norecurse $f] + set_property IS_GLOBAL_INCLUDE true $added +} + +foreach rel $B210_HDL_SOURCES { + add_files -fileset sources_1 -norecurse [b210_repo_file $rel] +} + +foreach rel $B210_NETLIST_SOURCES { + add_files -fileset sources_1 -norecurse [b210_repo_file $rel] +} + +foreach rel $B210_MEMORY_SOURCES { + add_files -fileset sources_1 -norecurse [b210_repo_file $rel] +} + +# Import the canonical XCI into the disposable generated project. AMD documents +# import_ip as the Project-Mode command that copies an XCI into the project; +# generated IP state therefore stays below build/ rather than beside the +# canonical version-controlled XCI. +foreach rel $B210_IP_SOURCES { + import_ip [b210_repo_file $rel] +} + +foreach rel $B210_CONSTRAINT_SOURCES { + add_files -fileset constrs_1 -norecurse [b210_repo_file $rel] +} + +set_property top $B210_TOP [get_filesets sources_1] +set_property top $B210_TOP [get_filesets sim_1] + +# Match the original project behavior: generate a raw .bin alongside .bit. +set_property STEPS.WRITE_BITSTREAM.ARGS.BIN_FILE true [get_runs impl_1] + +# Generate IP output products from the imported XCI. An OOC synthesis run is +# created/started by build.tcl before top-level synthesis. +foreach ip_obj [get_ips] { + generate_target all $ip_obj +} + +update_compile_order -fileset sources_1 +update_compile_order -fileset sim_1 + +puts "Created reproducible project: $B210_PROJECT_DIR" +puts "Top: $B210_TOP" +puts "Part: $B210_PART" diff --git a/vivado/b210_k7/project_config.tcl b/vivado/b210_k7/project_config.tcl new file mode 100644 index 0000000..df0bf47 --- /dev/null +++ b/vivado/b210_k7/project_config.tcl @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-3.0-or-later +# Project configuration kept separate so Vivado-version migration is an +# explicit, reviewable Git change. + +set B210_PROJECT_NAME "B210_Project_Firmwire" +set B210_TOP "b200" +set B210_PART "xc7k325tffg676-2" + +# Historical baseline. Change this to 2026.1 in the Vivado migration commit. +set B210_EXPECTED_VIVADO "2024.1" + +# Default parallelism. Override with environment variable B210_JOBS. +set B210_DEFAULT_JOBS 8 diff --git a/vivado/b210_k7/reports.tcl b/vivado/b210_k7/reports.tcl new file mode 100644 index 0000000..52f391f --- /dev/null +++ b/vivado/b210_k7/reports.tcl @@ -0,0 +1,41 @@ +# SPDX-License-Identifier: GPL-3.0-or-later +# Generate sign-off reports from an already-open implemented design. + +if {![info exists B210_REPO_ROOT]} { + set B210_SCRIPT_DIR [file dirname [file normalize [info script]]] + set B210_REPO_ROOT [file normalize [file join $B210_SCRIPT_DIR ../..]] +} + +set B210_REPORT_DIR [file join $B210_REPO_ROOT build reports] +file mkdir $B210_REPORT_DIR + +report_timing_summary \ + -delay_type min_max \ + -report_unconstrained \ + -check_timing_verbose \ + -file [file join $B210_REPORT_DIR timing_summary.rpt] + +report_route_status \ + -file [file join $B210_REPORT_DIR route_status.rpt] + +report_bus_skew \ + -file [file join $B210_REPORT_DIR bus_skew.rpt] + +report_methodology \ + -file [file join $B210_REPORT_DIR methodology.rpt] + +report_cdc \ + -details \ + -file [file join $B210_REPORT_DIR cdc.rpt] + +report_utilization \ + -hierarchical \ + -file [file join $B210_REPORT_DIR utilization.rpt] + +report_power \ + -file [file join $B210_REPORT_DIR power.rpt] + +report_operating_conditions \ + -file [file join $B210_REPORT_DIR operating_conditions.rpt] + +puts "Reports written to: $B210_REPORT_DIR" diff --git a/vivado/b210_k7/sources.tcl b/vivado/b210_k7/sources.tcl new file mode 100644 index 0000000..f77d302 --- /dev/null +++ b/vivado/b210_k7/sources.tcl @@ -0,0 +1,136 @@ +# SPDX-License-Identifier: GPL-3.0-or-later +# +# Exact source manifest for the reconstructed Kintex-7 B210 clone. +# +# IMPORTANT: This initial manifest intentionally reproduces the original +# Vivado 2024.1 project, including its use of lib/sim/fifo/axi_fifo_2clk_sim.v +# for synthesis. A later Git commit should replace that entry with the real +# hardware FIFO hierarchy and XPM wrappers. Keeping the historical mistake in +# this baseline makes the Git history accurately describe the repair. +# +# Paths are repository-relative and are deliberately explicit. Do not replace +# these lists with recursive globs; doing so can accidentally pull simulation +# sources into synthesis. + +# Headers active in synthesis +set B210_GLOBAL_INCLUDE_SOURCES { + top/b200/Define.vh +} + +# RTL active in the original sources_1 fileset, in original XPR order +set B210_HDL_SOURCES { + lib/dsp/acc.v + lib/dsp/add2.v + lib/dsp/add2_and_clip.v + lib/dsp/add2_and_clip_reg.v + lib/dsp/add2_and_round.v + lib/dsp/add2_and_round_reg.v + lib/dsp/add2_reg.v + lib/dsp/add_then_mac.v + lib/fifo/axi_demux4.v + lib/fifo/axi_fifo.v + lib/fifo/axi_fifo32_to_fifo64.v + lib/fifo/axi_fifo64_to_fifo32.v + lib/sim/fifo/axi_fifo_2clk_sim.v + lib/fifo/axi_fifo_bram.v + lib/fifo/axi_fifo_flop.v + lib/fifo/axi_fifo_flop2.v + lib/fifo_200/axi_fifo_legacy.v + lib/fifo/axi_fifo_short.v + lib/fifo/axi_mux4.v + lib/fifo/axi_packet_gate.v + top/b200/b200_core.v + top/b200/b200_io.v + lib/control/bin2gray.v + lib/control/binary_encoder.v + lib/vita_200/chdr_12sc_to_16sc.v + lib/vita_200/chdr_16sc_to_12sc.v + lib/vita_200/chdr_16sc_to_32f.v + lib/vita_200/chdr_16sc_to_8sc.v + lib/vita_200/chdr_16sc_to_xxxx_chain.v + lib/vita_200/chdr_32f_to_16sc.v + lib/vita_200/chdr_8sc_to_16sc.v + lib/vita_200/chdr_xxxx_to_16sc_chain.v + lib/dsp/cic_dec_shifter.v + lib/dsp/cic_decim.v + lib/dsp/cic_int_shifter.v + lib/dsp/cic_interp.v + lib/dsp/cic_strober.v + lib/dsp/clip.v + lib/dsp/clip_reg.v + lib/vita_200/context_packet_gen.v + lib/dsp/cordic_stage.v + lib/dsp/cordic_z24.v + lib/control_200/cvita_uart.v + lib/dsp/ddc_chain.v + lib/dsp/duc_chain.v + top/b200/edge_detect.v + lib/gpif2/fifo64_to_gpif2.v + lib/vita_200/float_to_iq.v + lib/gpif2/gpif2_error_checker.v + lib/gpif2/gpif2_slave_fifo32.v + lib/gpif2/gpif2_to_fifo64.v + lib/control/gpio_atr.v + lib/control/gpio_atr_io.v + lib/control/gray2bin.v + lib/dsp/hb47_int.v + lib/dsp/hb_dec.v + lib/dsp/hb_interp.v + top/b200/coregen_dsp/hbdec1.v + top/b200/coregen_dsp/hbdec2.v + lib/vita_200/iq_to_float.v + lib/vita_200/new_rx_control.v + lib/vita_200/new_rx_framer.v + lib/vita_200/new_tx_control.v + lib/vita_200/new_tx_deframer.v + lib/timing/pps_generator.v + top/b200/pps_switch.v + lib/control_200/radio_ctrl_proc.v + lib/radio_200/radio_legacy.v + lib/control/ram_2port.v + lib/control/reset_sync.v + lib/dsp/round.v + lib/dsp/round_reg.v + lib/dsp/round_sd.v + lib/control/serial_to_settings.v + lib/control/setting_reg.v + lib/dsp/sign_extend.v + lib/control/simple_spi_core.v + lib/wishbone/simple_uart.v + lib/wishbone/simple_uart_rx.v + lib/wishbone/simple_uart_tx.v + lib/dsp/small_hb_dec.v + lib/dsp/small_hb_int.v + lib/packet_proc_200/source_flow_control_legacy.v + lib/dsp/srl.v + lib/control/synchronizer.v + lib/control/synchronizer_impl.v + lib/timing/time_compare.v + lib/timing/timekeeper_legacy.v + lib/vita_200/trigger_context_pkt.v + lib/vita_200/tx_responder.v + lib/control/user_settings.v + top/b200/b200.v +} + +# Legacy netlists required by the clone port +set B210_NETLIST_SOURCES { + top/b200/coregen_dsp/hbdec2.edif + top/b200/coregen_dsp/hbdec1.edif +} + +# Memory initialization files present in the original synthesis fileset +set B210_MEMORY_SOURCES { + lib/white_rabbit/wr_cores_v4_2/bin/wrpc/wrc_phy8_sim.mif + lib/white_rabbit/wr_cores_v4_2/bin/wrpc/wrc_phy8.mif +} + +# Canonical version-controlled Vivado IP customization +set B210_IP_SOURCES { + vivado/b210_k7/ip/b200_clk_gen/b200_clk_gen.xci +} + +# Board/timing constraints +set B210_CONSTRAINT_SOURCES { + top/b200/b210.xdc +}