Merge pull request #36 from mcmasterg/roi_harness_arty

roi_harness improvements
This commit is contained in:
John McMaster 2018-01-05 15:35:39 -08:00 committed by GitHub
commit c91bd8d6b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 135 additions and 46 deletions

View File

@ -1,20 +1,36 @@
# WARNING: this is somewhat paramaterized, but is only tested on A50T/A35T with the traditional ROI
# Your ROI should at least have a SLICEL on the left
# Number of package inputs going to ROI
set DIN_N 8
# Number of ROI outputs going to package
set DOUT_N 8
# How many rows between pins
# Reduces routing pressure
set PITCH 3
# X12 in the ROI, X10 just to the left
# Start at bottom left of ROI and work up
# (IOs are to left)
# SLICE_X12Y100:SLICE_X27Y149
# set X_BASE 12
set X_BASE [lindex [split [lindex [split "$::env(XRAY_ROI)" Y] 0] X] 1]
set Y_BASE [lindex [split [lindex [split "$::env(XRAY_ROI)" Y] 1] :] 0]
set XRAY_ROI_X0 [lindex [split [lindex [split "$::env(XRAY_ROI)" Y] 0] X] 1]
set XRAY_ROI_X1 [lindex [split [lindex [split "$::env(XRAY_ROI)" X] 2] Y] 0]
set XRAY_ROI_Y0 [lindex [split [lindex [split "$::env(XRAY_ROI)" Y] 1] :] 0]
set XRAY_ROI_Y1 [lindex [split "$::env(XRAY_ROI)" Y] 2]
set X_BASE $XRAY_ROI_X0
set Y_BASE $XRAY_ROI_Y0
# set Y_DIN_BASE 100
set Y_CLK_BASE $Y_BASE
# Clock lut in middle
set Y_DIN_BASE [expr "$Y_CLK_BASE + 1"]
set Y_DOUT_BASE [expr "$Y_DIN_BASE + $DIN_N"]
# Sequential
# set Y_DOUT_BASE [expr "$Y_DIN_BASE + $DIN_N"]
# At top. This relieves routing pressure by spreading things out
# Note: can actually go up one more if we want
set Y_DOUT_BASE [expr "$XRAY_ROI_Y1 - $DIN_N * $PITCH"]
puts "Environment"
puts " XRAY_ROI: $::env(XRAY_ROI)"
@ -32,9 +48,12 @@ read_verilog top.v
# synth_design -top top -flatten_hierarchy none -no_lc -keep_equivalent_registers -resource_sharing off
synth_design -top top -flatten_hierarchy none -verilog_define DIN_N=$DIN_N -verilog_define DOUT_N=$DOUT_N
# TODO: find a way to more automatically assign these?
# Sequential I/O Bank 16 layout
# Map of top level net names to IOB pin names
array set net2pin [list]
# Create pin assignments based on what we are targetting
set part "$::env(XRAY_PART)"
# A50T I/O Bank 16 sequential layout
if {$part eq "xc7a50tfgg484-1"} {
# Partial list, expand as needed
set bank_16 "F21 G22 G21 D21 E21 D22 E22 A21 B21 B22 C22 C20 D20 F20 F19 A19 A18"
@ -43,22 +62,46 @@ if {$part eq "xc7a50tfgg484-1"} {
# CLK
set pin [lindex $bank_16 $banki]
incr banki
set_property -dict "PACKAGE_PIN $pin IOSTANDARD LVCMOS33" [get_ports "clk"]
set net2pin(clk) $pin
# DIN
for {set j 0} {$j < $DIN_N} {incr j} {
for {set i 0} {$i < $DIN_N} {incr i} {
set pin [lindex $bank_16 $banki]
incr banki
set_property -dict "PACKAGE_PIN $pin IOSTANDARD LVCMOS33" [get_ports "din[$j]"]
set net2pin(din[$i]) $pin
}
# DOUT
for {set j 0} {$j < $DOUT_N} {incr j} {
for {set i 0} {$i < $DOUT_N} {incr i} {
set pin [lindex $bank_16 $banki]
incr banki
set_property -dict "PACKAGE_PIN $pin IOSTANDARD LVCMOS33" [get_ports "dout[$j]"]
set net2pin(dout[$i]) $pin
}
# Arty A7 optimized I/O layout
# Arty A7 switch, button, and LED
} elseif {$part eq "xc7a35tcsg324-1"} {
# https://reference.digilentinc.com/reference/programmable-logic/arty/reference-manual?redirect=1
# 4 switches then 4 buttons
set sw_but "A8 C11 C10 A10 D9 C9 B9 B8"
# 4 LEDs then 4 RGB LEDs (green only)
set leds "H5 J5 T9 T10 F6 J4 J2 H6"
# 100 MHz CLK onboard
set pin "E3"
set net2pin(clk) $pin
# DIN
for {set i 0} {$i < $DIN_N} {incr i} {
set pin [lindex $sw_but $i]
set net2pin(din[$i]) $pin
}
# DOUT
for {set i 0} {$i < $DOUT_N} {incr i} {
set pin [lindex $leds $i]
set net2pin(dout[$i]) $pin
}
# Arty A7 pmod
# Disabled per above
} elseif {$part eq "xc7a35tcsg324-1"} {
# https://reference.digilentinc.com/reference/programmable-logic/arty/reference-manual?redirect=1
set pmod_ja "G13 B11 A11 D12 D13 B18 A18 K16"
@ -67,23 +110,30 @@ if {$part eq "xc7a50tfgg484-1"} {
# CLK on Pmod JA
set pin [lindex $pmod_ja 0]
set_property -dict "PACKAGE_PIN G13 IOSTANDARD LVCMOS33" [get_ports "clk"]
set net2pin(clk) $pin
# DIN on Pmod JB
for {set i 0} {$i < $DIN_N} {incr i} {
set pin [lindex $pmod_jb $i]
set_property -dict "PACKAGE_PIN $pin IOSTANDARD LVCMOS33" [get_ports "din[$i]"]
set net2pin(din[$i]) $pin
}
# DOUT on Pmod JC
for {set i 0} {$i < $DOUT_N} {incr i} {
set pin [lindex $pmod_jc $i]
set_property -dict "PACKAGE_PIN $pin IOSTANDARD LVCMOS33" [get_ports "dout[$i]"]
set net2pin(dout[$i]) $pin
}
} else {
error "Unsupported part $part"
}
# Now actually apply the pin definitions
puts "Applying pin definitions"
foreach {net pin} [array get net2pin] {
puts " Net $net to pin $pin"
set_property -dict "PACKAGE_PIN $pin IOSTANDARD LVCMOS33" [get_ports $net]
}
create_pblock roi
set_property EXCLUDE_PLACEMENT 1 [get_pblocks roi]
add_cells_to_pblock [get_pblocks roi] [get_cells roi]
@ -113,13 +163,13 @@ proc loc_roi_clk_left {ff_x ff_y} {
set_property BEL AFF $cell
}
proc loc_roi_in_left {index lut_x y} {
# Place an ROI input on the left edge of the ROI
proc loc_lut_in {index lut_x lut_y} {
# Place a lut at specified coordinates in BEL A
# index: input bus index
# lut_x: ROI SLICE X position. FF position is implicit to left
# y: row primitives will be placed at
# lut_x: SLICE X position
# lut_y: SLICE Y position
set slice_lut "SLICE_X${lut_x}Y${y}"
set slice_lut "SLICE_X${lut_x}Y${lut_y}"
# Fix LUTs near the edge
set cell [get_cells "roi/ins[$index].lut"]
@ -127,13 +177,13 @@ proc loc_roi_in_left {index lut_x y} {
set_property BEL A6LUT $cell
}
proc loc_roi_out_left {index lut_x y} {
# Place an ROI output on the left edge of the ROI
proc loc_lut_out {index lut_x lut_y} {
# Place a lut at specified coordinates in BEL A
# index: input bus index
# lut_x: ROI SLICE X position. FF position is implicit to left
# y: row primitives will be placed at
# lut_x: SLICE X position
# lut_y: SLICE Y position
set slice_lut "SLICE_X${lut_x}Y${y}"
set slice_lut "SLICE_X${lut_x}Y${lut_y}"
# Fix LUTs near the edge
set cell [get_cells "roi/outs[$index].lut"]
@ -141,7 +191,26 @@ proc loc_roi_out_left {index lut_x y} {
set_property BEL A6LUT $cell
}
proc net_bank_left {net} {
# return 1 if net goes to a leftmost die IO bank
# return 0 if net goes to a rightmost die IO bank
set bank [get_property IOBANK [get_ports $net]]
set left_banks "14 15 16"
set right_banks "34 35"
# left
if {[lsearch -exact $left_banks $bank] >= 0} {
return 1
# right
} elseif {[lsearch -exact $right_banks $bank] >= 0} {
return 0
} else {
error "Bad bank $bank"
}
}
# Manual placement
if {1} {
set x $X_BASE
@ -153,16 +222,20 @@ if {1} {
puts "Placing ROI inputs"
set y $Y_DIN_BASE
for {set i 0} {$i < $DIN_N} {incr i} {
loc_roi_in_left $i $x $y
set y [expr {$y + 1}]
loc_lut_in $i $x $y
set y [expr {$y + $PITCH}]
}
# Place ROI outputs
set y $Y_DOUT_BASE
puts "Placing ROI outputs"
for {set i 0} {$i < $DOUT_N} {incr i} {
loc_roi_out_left $i $x $y
set y [expr {$y + 1}]
if {[net_bank_left "dout[$i]"]} {
loc_lut_out $i $XRAY_ROI_X0 $y
} else {
loc_lut_out $i $XRAY_ROI_X1 $y
}
set y [expr {$y + $PITCH}]
}
}
@ -220,47 +293,63 @@ proc route_via2 {net nodes} {
# XXX: maybe add IOB?
set fp [open "design.txt" w]
puts $fp "name node"
puts $fp "name node pin"
# Manual routing
if {1} {
set x $X_BASE
# Nothing needed for clk
# No routing strictly needed for clk
# It will go to high level interconnect that goes everywhere
# But we still need to record something, so lets force a route
# FIXME: very ROI specific
set node "CLK_HROW_TOP_R_X60Y130/CLK_HROW_CK_BUFHCLK_L0"
route_via2 "clk_IBUF_BUFG" "$node"
set net "clk"
set pin "$net2pin($net)"
puts $fp "$net $node $pin"
puts "Routing ROI inputs"
# Arbitrary offset as observed
set y [expr {$Y_DIN_BASE - 1}]
for {set i 0} {$i < $DIN_N} {incr i} {
#route_via2 "din_IBUF[$i]" "INT_R_X9Y${y}/NE2BEG3"
# needed to force routes away to avoid looping into ROI
#set x_EE2BEG3 [expr {$x - 2}]
set x_EE2BEG3 7
set x_NE2BEG3 9
set node "INT_R_X${x_NE2BEG3}Y${y}/NE2BEG3"
route_via2 "din_IBUF[$i]" "INT_R_X${x_EE2BEG3}Y${y}/EE2BEG3 $node"
puts $fp "din[$i] $node"
set y [expr {$y + 1}]
set net "din[$i]"
set pin "$net2pin($net)"
puts $fp "$net $node $pin"
set y [expr {$y + $PITCH}]
}
puts "Routing ROI outputs"
# Arbitrary offset as observed
set y [expr {$Y_DOUT_BASE + 0}]
for {set i 0} {$i < $DOUT_N} {incr i} {
# XXX: find a better solution if we need harness long term
# works on 50t but not 35t
if {$part eq "xc7a50tfgg484-1"} {
set node "INT_L_X10Y${y}/WW2BEG0"
route_via2 "roi/dout[$i]" "$node"
# works on 35t but not 50t
} elseif {$part eq "xc7a35tcsg324-1"} {
set node "INT_L_X10Y${y}/SW6BEG0"
route_via2 "roi/dout[$i]" "$node"
if {[net_bank_left "dout[$i]"]} {
# XXX: find a better solution if we need harness long term
# works on 50t but not 35t
if {$part eq "xc7a50tfgg484-1"} {
set node "INT_L_X10Y${y}/WW2BEG0"
route_via2 "roi/dout[$i]" "$node"
# works on 35t but not 50t
} elseif {$part eq "xc7a35tcsg324-1"} {
set node "INT_L_X10Y${y}/SW6BEG0"
route_via2 "roi/dout[$i]" "$node"
} else {
error "Unsupported part $part"
}
# XXX: only care about right ports on Arty
} else {
error "Unsupported part $part"
set node "INT_R_X17Y${y}/SE6BEG0"
route_via2 "roi/dout[$i]" "$node"
}
puts $fp "dout[$i] $node"
set y [expr {$y + 1}]
set net "dout[$i]"
set pin "$net2pin($net)"
puts $fp "$net $node $pin"
set y [expr {$y + $PITCH}]
}
}
close $fp