diff --git a/fuzzers/005-tilegrid/generate_bram.tcl b/fuzzers/005-tilegrid/generate_bram.tcl index a03f5f33..ba98e649 100644 --- a/fuzzers/005-tilegrid/generate_bram.tcl +++ b/fuzzers/005-tilegrid/generate_bram.tcl @@ -14,46 +14,9 @@ proc loc_brams {} { set bram_sites [get_sites -of_objects [get_pblocks roi] -filter {SITE_TYPE =~ RAMBFIFO36E1*}] set bram_bels [get_bels -of_objects $bram_sites] - set selected_bram_sites {} - set bram_index 0 - - # LOC one BRAM (a "selected_lut") into each BRAM segment configuration column (ie 10 per CMT column) - set bram_columns "" - foreach bram $bram_bels { - regexp "RAMB36_X([0-9]+)Y([0-9]+)/" $bram match slice_x slice_y - - # 10 per column => 10, 20, ,etc - # ex: RAMB36_X0Y10/RAMBFIFO36E1 - set y_column [expr ($slice_y / 10) * 10] - dict append bram_columns "X${slice_x}Y${y_column}" "$bram " - } - - # Pick the smallest Y in each column. - dict for {column brams_in_column} $bram_columns { - set min_slice_y 9999999 - - foreach bram $brams_in_column { - regexp "RAMB36_X([0-9]+)Y([0-9]+)/" $bram match slice_x slice_y - - if { $slice_y < $min_slice_y } { - set selected_bram_bel $bram - } - } - - set selected_bram_bel [get_bels $selected_bram_bel] - - set bram_site [get_sites -of_objects $selected_bram_bel] - puts "LOCing BEL: $selected_bram_bel to $bram_site" - set cell [get_cells roi/brams[$bram_index].bram] - set_property LOC $bram_site $cell - if {"$bram_site" == ""} {error "Bad site $bram_site from bel $selected_bram_bel"} - - set bram_index [expr $bram_index + 1] - # Output site, not bel, to avoid reference issues after PnR - lappend selected_bram_sites $bram_site - } - - return $selected_bram_sites + set bram_columns [group_dut_cols $bram_bels 10] + # Output site, not bel, to avoid reference issues after PnR + return [loc_dut_col_sites $bram_columns {roi/brams[} {].bram}] } proc write_brams { selected_brams_sites } { diff --git a/fuzzers/005-tilegrid/generate_clb.tcl b/fuzzers/005-tilegrid/generate_clb.tcl index 5870f381..7ca94e33 100644 --- a/fuzzers/005-tilegrid/generate_clb.tcl +++ b/fuzzers/005-tilegrid/generate_clb.tcl @@ -1,13 +1,9 @@ source "$::env(FUZDIR)/util.tcl" -proc loc_luts {} { - set luts [get_bels -of_objects [get_sites -of_objects [get_pblocks roi]] -filter {TYPE =~ LUT*} */A6LUT] - set selected_luts {} - set lut_index 0 - +proc group_lut_cols { lut_bels } { # LOC one LUT (a "selected_lut") into each CLB segment configuration column (ie 50 per CMT column) set lut_columns "" - foreach lut $luts { + foreach lut $lut_bels { regexp "SLICE_X([0-9]+)Y([0-9]+)/" $lut match slice_x slice_y # Only even SLICEs should be used as column bases. @@ -15,34 +11,19 @@ proc loc_luts {} { continue } - # 50 per column => 50, 100, 150, etc + # 50 per column => 0, 50, 100, 150, etc # ex: SLICE_X2Y50/A6LUT # Only take one of the CLBs within a slice set y_column [expr ($slice_y / 50) * 50] dict append lut_columns "X${slice_x}Y${y_column}" "$lut " } + return $lut_columns +} - # Pick the smallest Y in each column. - dict for {column luts_in_column} $lut_columns { - set min_slice_y 9999999 - - foreach lut $luts_in_column { - regexp "SLICE_X([0-9]+)Y([0-9]+)/" $lut slice_x slice_y - - if { $slice_y < $min_slice_y } { - set selected_lut $lut - } - } - - set cell [get_cells roi/luts[$lut_index].lut] - set lut_site [get_sites -of_objects [get_bels $selected_lut]] - puts "LOCing $selected_lut to $lut_site" - set_property LOC $lut_site $cell - set lut_index [expr $lut_index + 1] - lappend selected_luts [get_bels $selected_lut] - } - - return $selected_luts +proc loc_luts {} { + set lut_bels [get_bels -of_objects [get_sites -of_objects [get_pblocks roi]] -filter {TYPE =~ LUT*} */A6LUT] + set lut_columns [group_lut_cols $lut_bels] + return [loc_dut_col_bels $lut_columns {roi/luts[} {].lut}] } proc write_clbs { selected_luts } { diff --git a/fuzzers/005-tilegrid/generate_iob.tcl b/fuzzers/005-tilegrid/generate_iob.tcl index aa68113d..0ea201e0 100644 --- a/fuzzers/005-tilegrid/generate_iob.tcl +++ b/fuzzers/005-tilegrid/generate_iob.tcl @@ -1,7 +1,7 @@ source "$::env(FUZDIR)/util.tcl" # FIXME: change to grab one IOB from each column -proc loc_iob {} { +proc loc_iob_old {} { set ports [concat [get_ports clk] [get_ports do] [get_ports stb] [get_ports di]] set selected_iobs {} foreach port $ports { @@ -17,6 +17,15 @@ proc loc_iob {} { return $selected_iobs } +proc loc_iob {} { + # Get all possible sites + set duts [make_iob_sites] + # Sort them into CMT columns + set dut_columns [group_dut_cols $duts 75] + # Assign one from each + return [loc_dut_col_bels $dut_columns {di[} {]} ] +} + proc write_iob { selected_iobs } { foreach port $selected_iobs { puts "" diff --git a/fuzzers/005-tilegrid/util.tcl b/fuzzers/005-tilegrid/util.tcl index 0ef61a14..523678e4 100644 --- a/fuzzers/005-tilegrid/util.tcl +++ b/fuzzers/005-tilegrid/util.tcl @@ -1,4 +1,75 @@ -proc make_ios {} { +proc min_ysite { duts_in_column } { + # Given a list of sites, return the one with the lowest Y coordinate + + set min_dut_y 9999999 + + foreach dut $duts_in_column { + # Ex: SLICE_X2Y50/A6LUT + # Ex: IOB_X1Y50 + regexp ".*_X([0-9]+)Y([0-9]+)" $dut match dut_x dut_y + + if { $dut_y < $min_dut_y } { + set selected_dut $dut + set min_dut_y $dut_y + } + } + return $selected_dut +} + +proc group_dut_cols { duts ypitch } { + # Group a list of sites into pitch sized buckets + # Ex: IOBs occur 75 to a CMT column + # Set pitch to 75 to get 0-74 in one bucket, 75-149 in a second, etc + # X0Y0 {IOB_X0Y49 IOB_X0Y48 IOB_X0Y47 ... } + # Anything with a different x is automatically in a different bucket + + # LOC one LUT (a "selected_lut") into each CLB segment configuration column (ie 50 per CMT column) + set dut_columns "" + foreach dut $duts { + # Ex: SLICE_X2Y50/A6LUT + # Ex: IOB_X1Y50 + regexp ".*_X([0-9]+)Y([0-9]+)" $dut match dut_x dut_y + + # 75 per column => 0, 75, 150, etc + set y_column [expr ($dut_y / $ypitch) * $ypitch] + dict append dut_columns "X${dut_x}Y${y_column}" "$dut " + } + return $dut_columns +} + +proc loc_dut_col_bels { dut_columns cellpre cellpost } { + # set cellpre di + + # Pick the smallest Y in each column and LOC a cell to it + # cells must be named like $cellpre[$dut_index] + # Return the selected sites + + set ret_bels {} + set dut_index 0 + + dict for {column duts_in_column} $dut_columns { + set selected_dut_bel_str [min_ysite $duts_in_column] + set selected_dut_bel [get_bels $selected_dut_bel_str] + set selected_dut_site [get_sites -of_objects $selected_dut_bel] + + set cell [get_cells $cellpre$dut_index$cellpost] + puts "LOCing cell $cell to site $selected_dut_site (from bel $selected_dut_bel)" + set_property LOC $selected_dut_site $cell + + set dut_index [expr $dut_index + 1] + lappend ret_bels $selected_dut_bel + } + + return $ret_bels +} + +proc loc_dut_col_sites { dut_columns cellpre cellpost } { + set bels [loc_dut_col_bels $dut_columns $cellpre $cellpost] + set sites [get_sites -of_objects $bels] + return $sites +} + +proc make_io_pad_sites {} { # get all possible IOB pins foreach pad [get_package_pins -filter "IS_GENERAL_PURPOSE == 1"] { set site [get_sites -of_objects $pad] @@ -9,14 +80,30 @@ proc make_ios {} { dict append io_pad_sites $site $pad } } + return $io_pad_sites +} + +proc make_iob_pads {} { + set io_pad_sites [make_io_pad_sites] set iopad "" dict for {key value} $io_pad_sites { + # Some sites have more than one pad? lappend iopad [lindex $value 0] } return $iopad } +proc make_iob_sites {} { + set io_pad_sites [make_io_pad_sites] + + set sites "" + dict for {key value} $io_pad_sites { + lappend sites $key + } + return $sites +} + proc assign_iobs_old {} { set_property -dict "PACKAGE_PIN $::env(XRAY_PIN_00) IOSTANDARD LVCMOS33" [get_ports clk] set_property -dict "PACKAGE_PIN $::env(XRAY_PIN_01) IOSTANDARD LVCMOS33" [get_ports di] @@ -29,7 +116,7 @@ proc assign_iobs {} { # The iob fuzzer sets these to more specific values # All possible IOs - set iopad [make_ios] + set iopad [make_iob_pads] # Basic pins set_property -dict "PACKAGE_PIN [lindex $iopad 0] IOSTANDARD LVCMOS33" [get_ports clk] set_property -dict "PACKAGE_PIN [lindex $iopad 1] IOSTANDARD LVCMOS33" [get_ports do]