mirror of https://github.com/openXC7/prjxray.git
Merge pull request #36 from mcmasterg/roi_harness_arty
roi_harness improvements
This commit is contained in:
commit
c91bd8d6b8
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue