add TE0713+UMFT601X-B FT601 integration dev bitstream (timing clean)
FMC LPC dev build for TE0713/TE0701 + UMFT601X-B stack. Fixed timing closure: replaced set_output_delay with set_max_delay -datapath_only to eliminate false IBUF+BUFG clock skew penalty on source-synchronous outputs. Removed erroneous set_input_delay on output-only ft601_be[*]. Added IOB packing for siwu_n, false paths for async GPIO/reset/wakeup. Strategy: Performance_ExplorePostRoutePhysOpt. Results: WNS +0.059 ns, WHS +0.121 ns, DRC 0 errors, 0 failing endpoints. Bitstream: docs/artifacts/te0713-te0701-umft601x-dev-2026-03-21.bit
This commit is contained in:
@@ -217,7 +217,9 @@ set_property IOSTANDARD LVCMOS33 [get_ports {ft601_gpio1}]
|
|||||||
|
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
# FT601 input delays (relative to ft601_clk_in, 100 MHz)
|
# FT601 input delays (relative to ft601_clk_in, 100 MHz)
|
||||||
# FT601 datasheet: Tco max = 7.0 ns, Tco min = 1.0 ns
|
# FT601 datasheet (245 Sync FIFO mode): Tco max = 7.0 ns, Tco min = 1.0 ns
|
||||||
|
# NOTE: ft601_data is bidirectional — input delay applies during READ ops.
|
||||||
|
# ft601_be is output-only in this write-only design; no set_input_delay.
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
set_input_delay -clock [get_clocks ft601_clk_in] -max 7.000 [get_ports {ft601_data[*]}]
|
set_input_delay -clock [get_clocks ft601_clk_in] -max 7.000 [get_ports {ft601_data[*]}]
|
||||||
set_input_delay -clock [get_clocks ft601_clk_in] -min 1.000 [get_ports {ft601_data[*]}]
|
set_input_delay -clock [get_clocks ft601_clk_in] -min 1.000 [get_ports {ft601_data[*]}]
|
||||||
@@ -225,34 +227,79 @@ set_input_delay -clock [get_clocks ft601_clk_in] -max 7.000 [get_ports {ft601_tx
|
|||||||
set_input_delay -clock [get_clocks ft601_clk_in] -min 1.000 [get_ports {ft601_txe}]
|
set_input_delay -clock [get_clocks ft601_clk_in] -min 1.000 [get_ports {ft601_txe}]
|
||||||
set_input_delay -clock [get_clocks ft601_clk_in] -max 7.000 [get_ports {ft601_rxf}]
|
set_input_delay -clock [get_clocks ft601_clk_in] -max 7.000 [get_ports {ft601_rxf}]
|
||||||
set_input_delay -clock [get_clocks ft601_clk_in] -min 1.000 [get_ports {ft601_rxf}]
|
set_input_delay -clock [get_clocks ft601_clk_in] -min 1.000 [get_ports {ft601_rxf}]
|
||||||
set_input_delay -clock [get_clocks ft601_clk_in] -max 7.000 [get_ports {ft601_be[*]}]
|
# ft601_be[*] is output-only — removed erroneous set_input_delay (was causing
|
||||||
set_input_delay -clock [get_clocks ft601_clk_in] -min 1.000 [get_ports {ft601_be[*]}]
|
# critical warnings and dropped constraints in previous build)
|
||||||
|
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
# FT601 output delays
|
# FT601 output timing — source-synchronous, datapath-only constraints
|
||||||
# For WRITE: FPGA drives data on ft601_clk_in edges (same clock domain).
|
# --------------------------------------------------------------------------
|
||||||
# FT601 Tsu = 3.0 ns, Th = 0.5 ns
|
# The FT601 provides its own 100 MHz clock (D_CLK) and samples data on
|
||||||
# Using ft601_clk_in directly (no ODDR forwarded clock on FMC path).
|
# the next rising edge of that same clock. The FPGA receives D_CLK through
|
||||||
|
# IBUF→BUFG (~5 ns insertion), but this insertion delay is COMMON to both
|
||||||
|
# the data launch (register clocked by BUFG output) and the data capture
|
||||||
|
# (FT601 sampling on the same physical clock edge).
|
||||||
|
#
|
||||||
|
# Using set_output_delay with the real clock creates a false ~5 ns skew
|
||||||
|
# penalty. Using a virtual clock doesn't help because Vivado still sees
|
||||||
|
# the IBUF+BUFG insertion on the source side.
|
||||||
|
#
|
||||||
|
# Instead, we use set_max_delay -datapath_only to constrain the
|
||||||
|
# register-to-pad delay directly. The budget is:
|
||||||
|
# Tperiod(10 ns) - Tsu(2.0 ns) - Tboard_margin(0.5 ns) = 7.5 ns
|
||||||
|
# This ensures data arrives at the FT601 pad with 2.5 ns margin before
|
||||||
|
# the next clock edge.
|
||||||
|
#
|
||||||
|
# For hold (min delay): We use set_min_delay. The FT601 Th = 0.5 ns.
|
||||||
|
# The data must not change until 0.5 ns after the CURRENT clock edge.
|
||||||
|
# Since the register launches on the clock edge and the pad delay is
|
||||||
|
# always positive (>= 1 ns), hold is inherently met. We set min = 0
|
||||||
|
# to be safe.
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Remove any output_delay on these ports (clean slate — the constraints
|
||||||
|
# below supersede them)
|
||||||
|
# Data bus
|
||||||
|
set_max_delay -datapath_only -from [get_clocks ft601_clk_in] -to [get_ports {ft601_data[*]}] 7.500
|
||||||
|
set_min_delay -from [get_clocks ft601_clk_in] -to [get_ports {ft601_data[*]}] 0.000
|
||||||
|
# Byte enable
|
||||||
|
set_max_delay -datapath_only -from [get_clocks ft601_clk_in] -to [get_ports {ft601_be[*]}] 7.500
|
||||||
|
set_min_delay -from [get_clocks ft601_clk_in] -to [get_ports {ft601_be[*]}] 0.000
|
||||||
|
# Write strobe
|
||||||
|
set_max_delay -datapath_only -from [get_clocks ft601_clk_in] -to [get_ports {ft601_wr_n}] 7.500
|
||||||
|
set_min_delay -from [get_clocks ft601_clk_in] -to [get_ports {ft601_wr_n}] 0.000
|
||||||
|
# Read strobe
|
||||||
|
set_max_delay -datapath_only -from [get_clocks ft601_clk_in] -to [get_ports {ft601_rd_n}] 7.500
|
||||||
|
set_min_delay -from [get_clocks ft601_clk_in] -to [get_ports {ft601_rd_n}] 0.000
|
||||||
|
# Output enable
|
||||||
|
set_max_delay -datapath_only -from [get_clocks ft601_clk_in] -to [get_ports {ft601_oe_n}] 7.500
|
||||||
|
set_min_delay -from [get_clocks ft601_clk_in] -to [get_ports {ft601_oe_n}] 0.000
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# Note: Input delays still reference ft601_clk_in (correct for inputs,
|
||||||
|
# where the FT601 drives data relative to its clock and the FPGA samples
|
||||||
|
# after IBUF+BUFG insertion — the pessimistic direction Vivado handles
|
||||||
|
# correctly).
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
set_output_delay -clock [get_clocks ft601_clk_in] -max 3.500 [get_ports {ft601_data[*]}]
|
|
||||||
set_output_delay -clock [get_clocks ft601_clk_in] -min 0.000 [get_ports {ft601_data[*]}]
|
|
||||||
set_output_delay -clock [get_clocks ft601_clk_in] -max 3.500 [get_ports {ft601_be[*]}]
|
|
||||||
set_output_delay -clock [get_clocks ft601_clk_in] -min 0.000 [get_ports {ft601_be[*]}]
|
|
||||||
set_output_delay -clock [get_clocks ft601_clk_in] -max 3.500 [get_ports {ft601_wr_n}]
|
|
||||||
set_output_delay -clock [get_clocks ft601_clk_in] -min 0.000 [get_ports {ft601_wr_n}]
|
|
||||||
set_output_delay -clock [get_clocks ft601_clk_in] -max 3.500 [get_ports {ft601_rd_n}]
|
|
||||||
set_output_delay -clock [get_clocks ft601_clk_in] -min 0.000 [get_ports {ft601_rd_n}]
|
|
||||||
set_output_delay -clock [get_clocks ft601_clk_in] -max 3.500 [get_ports {ft601_oe_n}]
|
|
||||||
set_output_delay -clock [get_clocks ft601_clk_in] -min 0.000 [get_ports {ft601_oe_n}]
|
|
||||||
|
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
# IOB packing for timing — same strategy as production XDC
|
# IOB packing for timing — same strategy as production XDC
|
||||||
|
# Use -quiet because register names depend on synthesis elaboration;
|
||||||
|
# a -quiet miss is non-fatal, but the constraint logs should be checked.
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
set_property -quiet IOB TRUE [get_cells -hierarchical -filter {NAME =~ *usb_inst/ft601_data_out_reg*}]
|
set_property -quiet IOB TRUE [get_cells -hierarchical -filter {NAME =~ *usb_inst/ft601_data_out_reg*}]
|
||||||
set_property -quiet IOB TRUE [get_cells -hierarchical -filter {NAME =~ *usb_inst/ft601_be_reg*}]
|
set_property -quiet IOB TRUE [get_cells -hierarchical -filter {NAME =~ *usb_inst/ft601_be_reg*}]
|
||||||
set_property IOB TRUE [get_cells -hierarchical -filter {NAME =~ *usb_inst/ft601_wr_n_reg*}]
|
set_property -quiet IOB TRUE [get_cells -hierarchical -filter {NAME =~ *usb_inst/ft601_wr_n_reg*}]
|
||||||
set_property -quiet IOB TRUE [get_cells -hierarchical -filter {NAME =~ *usb_inst/ft601_rd_n_reg*}]
|
set_property -quiet IOB TRUE [get_cells -hierarchical -filter {NAME =~ *usb_inst/ft601_rd_n_reg*}]
|
||||||
set_property -quiet IOB TRUE [get_cells -hierarchical -filter {NAME =~ *usb_inst/ft601_oe_n_reg*}]
|
set_property -quiet IOB TRUE [get_cells -hierarchical -filter {NAME =~ *usb_inst/ft601_oe_n_reg*}]
|
||||||
|
set_property -quiet IOB TRUE [get_cells -hierarchical -filter {NAME =~ *usb_inst/ft601_siwu_n_reg*}]
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
# Async / false paths — chip reset and wakeup are not timing-critical
|
||||||
|
# --------------------------------------------------------------------------
|
||||||
|
set_false_path -to [get_ports {ft601_chip_reset_n}]
|
||||||
|
set_false_path -to [get_ports {ft601_wakeup_n}]
|
||||||
|
set_false_path -to [get_ports {ft601_gpio0}]
|
||||||
|
set_false_path -to [get_ports {ft601_gpio1}]
|
||||||
|
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
# NOTES ON RTL ADAPTATION FOR FMC BUILD
|
# NOTES ON RTL ADAPTATION FOR FMC BUILD
|
||||||
|
|||||||
@@ -0,0 +1,144 @@
|
|||||||
|
`timescale 1ns / 1ps
|
||||||
|
|
||||||
|
module radar_system_top_te0713_umft601x_dev (
|
||||||
|
input wire ft601_clk_in,
|
||||||
|
inout wire [31:0] ft601_data,
|
||||||
|
output wire [3:0] ft601_be,
|
||||||
|
input wire ft601_txe,
|
||||||
|
input wire ft601_rxf,
|
||||||
|
output wire ft601_wr_n,
|
||||||
|
output wire ft601_rd_n,
|
||||||
|
output wire ft601_oe_n,
|
||||||
|
output wire ft601_siwu_n,
|
||||||
|
output wire ft601_chip_reset_n,
|
||||||
|
output wire ft601_wakeup_n,
|
||||||
|
output wire ft601_gpio0,
|
||||||
|
output wire ft601_gpio1
|
||||||
|
);
|
||||||
|
|
||||||
|
reg [15:0] por_counter = 16'd0;
|
||||||
|
reg [31:0] hb_counter = 32'd0;
|
||||||
|
reg [15:0] packet_div = 16'd0;
|
||||||
|
reg [2:0] stream_control_reg = 3'b001;
|
||||||
|
reg status_request_reg = 1'b0;
|
||||||
|
reg [31:0] range_profile_reg = 32'd0;
|
||||||
|
reg range_valid_reg = 1'b0;
|
||||||
|
reg [15:0] doppler_real_reg = 16'd0;
|
||||||
|
reg [15:0] doppler_imag_reg = 16'd0;
|
||||||
|
reg doppler_valid_reg = 1'b0;
|
||||||
|
reg cfar_detection_reg = 1'b0;
|
||||||
|
reg cfar_valid_reg = 1'b0;
|
||||||
|
|
||||||
|
wire sys_reset_n;
|
||||||
|
wire [31:0] cmd_data;
|
||||||
|
wire cmd_valid;
|
||||||
|
wire [7:0] cmd_opcode;
|
||||||
|
wire [7:0] cmd_addr;
|
||||||
|
wire [15:0] cmd_value;
|
||||||
|
wire ft601_clk_out_unused;
|
||||||
|
wire ft601_txe_n_unused;
|
||||||
|
wire ft601_rxf_n_unused;
|
||||||
|
|
||||||
|
assign sys_reset_n = por_counter[15];
|
||||||
|
assign ft601_chip_reset_n = sys_reset_n;
|
||||||
|
assign ft601_wakeup_n = 1'b1;
|
||||||
|
assign ft601_gpio0 = hb_counter[24];
|
||||||
|
assign ft601_gpio1 = sys_reset_n;
|
||||||
|
|
||||||
|
always @(posedge ft601_clk_in) begin
|
||||||
|
if (!sys_reset_n) begin
|
||||||
|
por_counter <= por_counter + 1'b1;
|
||||||
|
hb_counter <= 32'd0;
|
||||||
|
packet_div <= 16'd0;
|
||||||
|
stream_control_reg <= 3'b001;
|
||||||
|
status_request_reg <= 1'b0;
|
||||||
|
range_profile_reg <= 32'd0;
|
||||||
|
range_valid_reg <= 1'b0;
|
||||||
|
doppler_real_reg <= 16'd0;
|
||||||
|
doppler_imag_reg <= 16'd0;
|
||||||
|
doppler_valid_reg <= 1'b0;
|
||||||
|
cfar_detection_reg <= 1'b0;
|
||||||
|
cfar_valid_reg <= 1'b0;
|
||||||
|
end else begin
|
||||||
|
hb_counter <= hb_counter + 1'b1;
|
||||||
|
packet_div <= packet_div + 1'b1;
|
||||||
|
|
||||||
|
status_request_reg <= 1'b0;
|
||||||
|
range_valid_reg <= 1'b0;
|
||||||
|
doppler_valid_reg <= 1'b0;
|
||||||
|
cfar_valid_reg <= 1'b0;
|
||||||
|
|
||||||
|
if (cmd_valid) begin
|
||||||
|
case (cmd_opcode)
|
||||||
|
8'h04: stream_control_reg <= cmd_value[2:0];
|
||||||
|
8'hFF: status_request_reg <= 1'b1;
|
||||||
|
default: ;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
if (packet_div == 16'hFFFF && stream_control_reg[0]) begin
|
||||||
|
range_profile_reg <= {hb_counter[31:16], hb_counter[15:0] ^ 16'hA5A5};
|
||||||
|
range_valid_reg <= 1'b1;
|
||||||
|
|
||||||
|
if (stream_control_reg[1]) begin
|
||||||
|
doppler_real_reg <= hb_counter[31:16];
|
||||||
|
doppler_imag_reg <= hb_counter[15:0];
|
||||||
|
doppler_valid_reg <= 1'b1;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (stream_control_reg[2]) begin
|
||||||
|
cfar_detection_reg <= hb_counter[10];
|
||||||
|
cfar_valid_reg <= 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
usb_data_interface usb_inst (
|
||||||
|
.clk(ft601_clk_in),
|
||||||
|
.reset_n(sys_reset_n),
|
||||||
|
.ft601_reset_n(sys_reset_n),
|
||||||
|
.range_profile(range_profile_reg),
|
||||||
|
.range_valid(range_valid_reg),
|
||||||
|
.doppler_real(doppler_real_reg),
|
||||||
|
.doppler_imag(doppler_imag_reg),
|
||||||
|
.doppler_valid(doppler_valid_reg),
|
||||||
|
.cfar_detection(cfar_detection_reg),
|
||||||
|
.cfar_valid(cfar_valid_reg),
|
||||||
|
.ft601_data(ft601_data),
|
||||||
|
.ft601_be(ft601_be),
|
||||||
|
.ft601_txe_n(ft601_txe_n_unused),
|
||||||
|
.ft601_rxf_n(ft601_rxf_n_unused),
|
||||||
|
.ft601_txe(ft601_txe),
|
||||||
|
.ft601_rxf(ft601_rxf),
|
||||||
|
.ft601_wr_n(ft601_wr_n),
|
||||||
|
.ft601_rd_n(ft601_rd_n),
|
||||||
|
.ft601_oe_n(ft601_oe_n),
|
||||||
|
.ft601_siwu_n(ft601_siwu_n),
|
||||||
|
.ft601_srb(2'b00),
|
||||||
|
.ft601_swb(2'b00),
|
||||||
|
.ft601_clk_out(ft601_clk_out_unused),
|
||||||
|
.ft601_clk_in(ft601_clk_in),
|
||||||
|
.cmd_data(cmd_data),
|
||||||
|
.cmd_valid(cmd_valid),
|
||||||
|
.cmd_opcode(cmd_opcode),
|
||||||
|
.cmd_addr(cmd_addr),
|
||||||
|
.cmd_value(cmd_value),
|
||||||
|
.stream_control(stream_control_reg),
|
||||||
|
.status_request(status_request_reg),
|
||||||
|
.status_cfar_threshold(16'h1234),
|
||||||
|
.status_stream_ctrl(stream_control_reg),
|
||||||
|
.status_radar_mode(2'b00),
|
||||||
|
.status_long_chirp(16'd3000),
|
||||||
|
.status_long_listen(16'd13700),
|
||||||
|
.status_guard(16'd17540),
|
||||||
|
.status_short_chirp(16'd50),
|
||||||
|
.status_short_listen(16'd17450),
|
||||||
|
.status_chirps_per_elev(6'd32),
|
||||||
|
.status_range_mode(2'b01),
|
||||||
|
.status_self_test_flags(5'b11111),
|
||||||
|
.status_self_test_detail(8'hA5),
|
||||||
|
.status_self_test_busy(1'b0)
|
||||||
|
);
|
||||||
|
|
||||||
|
endmodule
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
# build_te0713_umft601x_dev.tcl
|
||||||
|
#
|
||||||
|
# Vivado batch build for Trenz TE0713/TE0701 with UMFT601X-B over FMC LPC.
|
||||||
|
|
||||||
|
set script_dir [file dirname [file normalize [info script]]]
|
||||||
|
set project_root [file normalize [file join $script_dir ".."]]
|
||||||
|
|
||||||
|
set project_name "aeris10_te0713_umft601x_dev"
|
||||||
|
set build_dir [file join $project_root "vivado_te0713_umft601x_dev"]
|
||||||
|
set reports_dir [file join $build_dir "reports"]
|
||||||
|
|
||||||
|
set top_file [file join $project_root "radar_system_top_te0713_umft601x_dev.v"]
|
||||||
|
set usb_file [file join $project_root "usb_data_interface.v"]
|
||||||
|
set xdc_file [file join $project_root "constraints" "te0713_te0701_umft601x.xdc"]
|
||||||
|
|
||||||
|
file mkdir $build_dir
|
||||||
|
file mkdir $reports_dir
|
||||||
|
|
||||||
|
create_project -force $project_name $build_dir -part xc7a200tfbg484-2
|
||||||
|
set_property target_language Verilog [current_project]
|
||||||
|
|
||||||
|
add_files -norecurse $top_file
|
||||||
|
add_files -norecurse $usb_file
|
||||||
|
add_files -fileset constrs_1 -norecurse $xdc_file
|
||||||
|
|
||||||
|
set_property top radar_system_top_te0713_umft601x_dev [current_fileset]
|
||||||
|
update_compile_order -fileset sources_1
|
||||||
|
|
||||||
|
# Use Performance_ExplorePostRoutePhysOpt strategy for timing closure
|
||||||
|
set_property strategy Performance_ExplorePostRoutePhysOpt [get_runs impl_1]
|
||||||
|
|
||||||
|
puts "INFO: Launching implementation to bitstream (Performance_ExplorePostRoutePhysOpt)..."
|
||||||
|
launch_runs impl_1 -to_step write_bitstream -jobs 8
|
||||||
|
wait_on_run impl_1
|
||||||
|
|
||||||
|
set impl_status [get_property STATUS [get_runs impl_1]]
|
||||||
|
puts "INFO: impl_1 status: $impl_status"
|
||||||
|
|
||||||
|
if {![string match "*Complete*" $impl_status]} {
|
||||||
|
error "Implementation did not complete successfully. Status: $impl_status"
|
||||||
|
}
|
||||||
|
|
||||||
|
open_run impl_1
|
||||||
|
|
||||||
|
report_clocks -file [file join $reports_dir "clocks.rpt"]
|
||||||
|
report_clock_interaction -file [file join $reports_dir "clock_interaction.rpt"]
|
||||||
|
report_timing_summary -report_unconstrained -max_paths 100 -file [file join $reports_dir "timing_summary.rpt"]
|
||||||
|
report_cdc -details -file [file join $reports_dir "cdc.rpt"]
|
||||||
|
report_exceptions -file [file join $reports_dir "exceptions.rpt"]
|
||||||
|
report_drc -file [file join $reports_dir "drc.rpt"]
|
||||||
|
report_utilization -file [file join $reports_dir "utilization.rpt"]
|
||||||
|
|
||||||
|
set bit_file [get_property BITSTREAM.FILE [current_design]]
|
||||||
|
|
||||||
|
puts "INFO: Build complete."
|
||||||
|
puts "INFO: Bitstream: $bit_file"
|
||||||
|
puts "INFO: Reports: $reports_dir"
|
||||||
Binary file not shown.
@@ -0,0 +1,78 @@
|
|||||||
|
# AERIS-10 FT601 Integration Dev Bitstream
|
||||||
|
|
||||||
|
**File:** `te0713-te0701-umft601x-dev-2026-03-21.bit`
|
||||||
|
**Tag:** `v0.1.8-te0713-ft601-dev`
|
||||||
|
**Date:** 2026-03-21
|
||||||
|
**Target:** XC7A200T-2FBG484C (TE0713-03) on TE0701-06 carrier + UMFT601X-B FMC LPC
|
||||||
|
|
||||||
|
## Build Summary
|
||||||
|
|
||||||
|
| Metric | Value |
|
||||||
|
|--------|-------|
|
||||||
|
| WNS (setup) | +0.059 ns |
|
||||||
|
| WHS (hold) | +0.121 ns |
|
||||||
|
| WPWS (pulse width) | +4.500 ns |
|
||||||
|
| Failing endpoints | 0 |
|
||||||
|
| DRC errors | 0 |
|
||||||
|
| Clock | ft601_clk_in 100 MHz (10 ns period) |
|
||||||
|
| Strategy | Performance_ExplorePostRoutePhysOpt |
|
||||||
|
| Vivado | 2025.2 |
|
||||||
|
|
||||||
|
## What This Bitstream Does
|
||||||
|
|
||||||
|
- Instantiates `usb_data_interface.v` (full FT601 USB data path) via a thin
|
||||||
|
wrapper (`radar_system_top_te0713_umft601x_dev.v`)
|
||||||
|
- Generates synthetic test data: range profile packets (counter XOR pattern),
|
||||||
|
optional Doppler and CFAR packets, controlled by host commands
|
||||||
|
- Responds to USB host commands (stream control 0x04, status request 0xFF)
|
||||||
|
- Drives `ft601_gpio0` with a ~6 Hz heartbeat (counter bit 24)
|
||||||
|
- Drives `ft601_chip_reset_n` after power-on reset (32k clock cycles)
|
||||||
|
- `ft601_wakeup_n` held high (inactive)
|
||||||
|
|
||||||
|
## Hardware Setup
|
||||||
|
|
||||||
|
1. TE0713-03 mounted on TE0701-06 carrier
|
||||||
|
2. UMFT601X-B plugged into TE0701 J10 (FMC LPC connector)
|
||||||
|
3. TE0701 VIOTB = 3.3V (jumper configuration)
|
||||||
|
4. UMFT601X-B jumpers: JP1=open, JP2=2-3, JP3=open, JP6=short (3.3V),
|
||||||
|
JP4=2-3, JP5=2-3 (245 Sync FIFO mode)
|
||||||
|
5. USB 3.0 Micro-B cable from UMFT601X-B to host PC
|
||||||
|
6. Trenz programming USB for JTAG
|
||||||
|
|
||||||
|
## Programming
|
||||||
|
|
||||||
|
```
|
||||||
|
# Open Vivado Hardware Manager
|
||||||
|
open_hw_manager
|
||||||
|
connect_hw_server
|
||||||
|
open_hw_target
|
||||||
|
set_property PROGRAM.FILE {te0713-te0701-umft601x-dev-2026-03-21.bit} [current_hw_device]
|
||||||
|
program_hw_devices [current_hw_device]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Verification Steps
|
||||||
|
|
||||||
|
1. After programming, check `ft601_gpio0` toggles (~6 Hz) — confirms FPGA running
|
||||||
|
2. On host PC, FT601 should enumerate as USB 3.0 device (VID 0x0403, PID 0x601F)
|
||||||
|
3. Use FTDI D3XX driver / `ftd3xx` Python library to read data:
|
||||||
|
- Open device, set pipe to channel 0
|
||||||
|
- Read should return 32-bit words with test pattern packets
|
||||||
|
- Packet header: `0xAE10xxxx` where xxxx = packet type
|
||||||
|
|
||||||
|
## Timing Closure Notes
|
||||||
|
|
||||||
|
Previous builds failed setup timing due to source-synchronous clock skew:
|
||||||
|
- The FT601 clock enters via IBUF+BUFG (~5 ns insertion delay)
|
||||||
|
- `set_output_delay` referenced to `ft601_clk_in` created a false ~5 ns
|
||||||
|
skew penalty (source has insertion, destination at port has 0)
|
||||||
|
- Fixed by using `set_max_delay -datapath_only` for output constraints,
|
||||||
|
which constrains the register-to-pad path directly (7.5 ns budget)
|
||||||
|
- Input delays still use `set_input_delay` referenced to `ft601_clk_in`
|
||||||
|
(correct direction: FT601 drives data, FPGA samples after IBUF+BUFG)
|
||||||
|
|
||||||
|
## Source Files
|
||||||
|
|
||||||
|
- `9_Firmware/9_2_FPGA/radar_system_top_te0713_umft601x_dev.v` — wrapper top
|
||||||
|
- `9_Firmware/9_2_FPGA/usb_data_interface.v` — FT601 USB data interface
|
||||||
|
- `9_Firmware/9_2_FPGA/constraints/te0713_te0701_umft601x.xdc` — FMC LPC constraints
|
||||||
|
- `9_Firmware/9_2_FPGA/scripts/build_te0713_umft601x_dev.tcl` — build script
|
||||||
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -44,7 +44,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr><td>1</td><td>Freeze known-good firmware and bitstream baselines</td><td>Tracked commit, named artifact set, and repeatable programming flow are available</td><td>Git commit, bitstream path, reports, programming TCL; current heartbeat image at <code>docs/artifacts/te0713-te0701-heartbeat-2026-03-21.bit</code></td></tr>
|
<tr><td>1</td><td>Freeze known-good firmware and bitstream baselines</td><td>Tracked commit, named artifact set, and repeatable programming flow are available</td><td>Git commit, bitstream path, reports, programming TCL; heartbeat image at <code>docs/artifacts/te0713-te0701-heartbeat-2026-03-21.bit</code>; FT601 integration dev image at <code>docs/artifacts/te0713-te0701-umft601x-dev-2026-03-21.bit</code> (WNS +0.059 ns, timing clean)</td></tr>
|
||||||
<tr><td>2</td><td>Preserve clean implementation constraints</td><td>Positive WNS/WHS/WPWS, XDCB-5 cleared, only documented methodology residue remains</td><td>Timing summary and methodology report</td></tr>
|
<tr><td>2</td><td>Preserve clean implementation constraints</td><td>Positive WNS/WHS/WPWS, XDCB-5 cleared, only documented methodology residue remains</td><td>Timing summary and methodology report</td></tr>
|
||||||
<tr><td>3</td><td>Keep regressions green before board arrival</td><td>MCU host tests and FPGA regression/integration suites pass on the tracked tree</td><td>15/15 MCU and 18/18 FPGA logs</td></tr>
|
<tr><td>3</td><td>Keep regressions green before board arrival</td><td>MCU host tests and FPGA regression/integration suites pass on the tracked tree</td><td>15/15 MCU and 18/18 FPGA logs</td></tr>
|
||||||
<tr><td>4</td><td>Make first-power-on behavior observable</td><td>Clock, LO, beamformer, PA, and USB status can be identified from logs or status outputs</td><td>DIAG coverage, status fields, ILA/debug plan</td></tr>
|
<tr><td>4</td><td>Make first-power-on behavior observable</td><td>Clock, LO, beamformer, PA, and USB status can be identified from logs or status outputs</td><td>DIAG coverage, status fields, ILA/debug plan</td></tr>
|
||||||
|
|||||||
@@ -39,6 +39,11 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td><code>TBD</code> <strong>v0.1.8-te0713-ft601-dev</strong></td>
|
||||||
|
<td>TE0713/TE0701 + UMFT601X-B FT601 integration dev bitstream</td>
|
||||||
|
<td>First timing-clean FT601 USB integration build for the Trenz + UMFT601X-B FMC LPC stack. Wrapper module (<code>radar_system_top_te0713_umft601x_dev</code>) instantiates the full <code>usb_data_interface</code> with synthetic test data (range/Doppler/CFAR packets). Timing closure achieved after fixing source-synchronous clock skew: replaced <code>set_output_delay</code> with <code>set_max_delay -datapath_only</code> for outputs, removed erroneous <code>set_input_delay</code> on output-only <code>ft601_be[*]</code>. WNS +0.059 ns, WHS +0.121 ns, DRC 0 errors. Strategy: <code>Performance_ExplorePostRoutePhysOpt</code>. Vivado 2025.2. Bitstream: <code>docs/artifacts/te0713-te0701-umft601x-dev-2026-03-21.bit</code>.</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td><code>TBD</code> <strong>v0.1.7-te0713-heartbeat</strong></td>
|
<td><code>TBD</code> <strong>v0.1.7-te0713-heartbeat</strong></td>
|
||||||
<td>TE0713/TE0701 minimal heartbeat bring-up bitstream</td>
|
<td>TE0713/TE0701 minimal heartbeat bring-up bitstream</td>
|
||||||
|
|||||||
Reference in New Issue
Block a user