{{ header }}

{% from "_helpers.j2" import board_name, board_fpga_part, safe_attr %}
puts "Adding constraint files..."

# Get script directory for reliable path resolution
set script_dir [file dirname [info script]]

# Only include constraint files provided by PCILeech discovery and generation
set already_added_files [list]

# Generated XDC path (copied by the builder)
{% if generated_xdc_path %}
set generated_xdc "{{ generated_xdc_path }}"
if {[file exists $generated_xdc]} {
    if {[lsearch -exact $already_added_files $generated_xdc] == -1} {
        add_files -fileset constrs_1 -norecurse $generated_xdc
        lappend already_added_files $generated_xdc
        puts "Added generated XDC constraints: $generated_xdc"
    }
} else {
    puts "WARNING: Generated XDC path does not exist: $generated_xdc"
}
{% endif %}

# Explicit constraint files provided by the builder
{% if constraint_files %}
set pcileech_xdc_files [list \
{% for f in constraint_files %}    "{{ f }}" \
{% endfor %}]
foreach xdc_file $pcileech_xdc_files {
    if {[file exists $xdc_file]} {
        if {[lsearch -exact $already_added_files $xdc_file] == -1} {
            add_files -fileset constrs_1 -norecurse $xdc_file
            lappend already_added_files $xdc_file
            puts "  Added PCILeech XDC: $xdc_file"
        }
    } else {
        puts "WARNING: PCILeech XDC not found: $xdc_file"
    }
}
{% endif %}

# Generate device-specific timing constraints
puts "Adding device-specific timing constraints..."
# Try to use board-specific XDC constraints if board type is specified
{%- if board is defined -%}
puts "Attempting to load board-specific XDC constraints for: {{ board_name(board) }}"

{%- if board_xdc_content is defined and board_xdc_content %}
# Load XDC constraints from PCILeech repository
# This will be populated by the constraint generation system
# with actual XDC content from the PCILeech FPGA repository
# Write board XDC content to temporary file to avoid brace/semicolon issues
set board_auto_xdc_file [file join $script_dir "{{ board_name(board) }}_auto.xdc"]
set fp [open $board_auto_xdc_file w]
puts $fp {{ "{" ~ board_xdc_content ~ "}" }}
close $fp
add_files -fileset constrs_1 -norecurse $board_auto_xdc_file
read_xdc $board_auto_xdc_file
puts "Added auto-generated board XDC: $board_auto_xdc_file"
{%- else %}
# No board-specific XDC available, using generic constraints
puts "WARNING: No board-specific XDC constraints available for {{ board_name(board) }}"
puts "Using generic timing constraints only. You may need to add board-specific pin assignments."
{%- endif %}
{%- endif %}

# Generate device-specific timing constraints file
{% set sys_clk_period = (1000.0 / (sys_clk_freq_mhz | default(100))) | round(3) %}
set timing_constraints_content {
# Clock constraints - {{ sys_clk_freq_mhz | default(100) }} MHz system clock
create_clock -period {{ sys_clk_period }} -name sys_clk [get_ports clk]

# Input delay constraints for actual input ports
set_input_delay -clock sys_clk 2.000 [get_ports reset_n]

# Device-specific constraints for {{ device.vendor_id }}:{{ device.device_id }}
# Board-specific pin assignments for {{ board_name(board) }}

# NOTE: Pin assignments MUST be loaded from board-specific XDC files from the PCILeech repository.
# We NEVER generate fallback XDC content as it contains critical pin assignments.
}

# Write timing constraints to file
set constraints_file [file join $script_dir "device_constraints.xdc"]
set fp [open $constraints_file w]
puts $fp $timing_constraints_content
close $fp
add_files -fileset constrs_1 -norecurse $constraints_file
read_xdc $constraints_file
set_property PROCESSING_ORDER LATE [get_files $constraints_file]
puts "Generated device constraints file: $constraints_file"

# Quality-of-life tweaks for USB-heavy designs
{% if board and board.features is defined and board.features %}
set_param xicom.use_bs_reader 1
puts "Enabled fast bitstream reader for FT601 board"
{% endif %}

puts "Constraints setup completed"