mirror of https://github.com/openXC7/prjxray.git
commit
cc9e00da8f
|
|
@ -39,12 +39,14 @@ DB_SIMPLE=\
|
|||
$(addsuffix _r, $(DB_SIMPLE_LR) $(DB_SIMPLE_R)) \
|
||||
segbits_cmt_top_l_upper_t \
|
||||
segbits_cmt_top_r_upper_t \
|
||||
segbits_lioi3 \
|
||||
segbits_rioi3 \
|
||||
segbits_liob33 \
|
||||
segbits_riob33 \
|
||||
segbits_hclk_ioi3 \
|
||||
|
||||
ifneq (${XRAY_DATABASE}, zynq7)
|
||||
DB_SIMPLE += segbits_lioi3 segbits_liob33
|
||||
endif
|
||||
|
||||
BLOCK_RAM_EXTRA_FOR=\
|
||||
mask_bram \
|
||||
segbits_bram
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ N = 50
|
|||
|
||||
# These PIPs all appear to be either a 2 bit solutions.
|
||||
SEGMATCH_FLAGS=-c 2
|
||||
SPECIMENS_DEPS=build/cmt_regions.csv
|
||||
SPECIMENS_DEPS=build/dump.ok
|
||||
A_PIPLIST=clk_hrow_bot_r.txt
|
||||
|
||||
include ../pip_loop.mk
|
||||
|
|
@ -37,9 +37,18 @@ database: build/segbits_clk_hrow_bot_r.rdb build/segbits_clk_hrow_top_r.rdb
|
|||
XRAY_DATABASE_DIR=${FUZDIR}/build/database ${XRAY_MERGEDB} clk_hrow_bot_r build/segbits_clk_hrow_bot_r.db
|
||||
XRAY_DATABASE_DIR=${FUZDIR}/build/database ${XRAY_MERGEDB} clk_hrow_top_r build/segbits_clk_hrow_top_r.db
|
||||
|
||||
build/cmt_regions.csv: output_cmt.tcl
|
||||
ifeq (${XRAY_DATABASE}, zynq7)
|
||||
build/dump.ok: output_cmt.tcl output_pss_clocks.tcl
|
||||
mkdir -p build
|
||||
cd build/ && ${XRAY_VIVADO} -mode batch -source ${FUZDIR}/output_cmt.tcl
|
||||
cd build/ && ${XRAY_VIVADO} -mode batch -source ${FUZDIR}/output_pss_clocks.tcl
|
||||
touch build/dump.ok
|
||||
else
|
||||
build/dump.ok: output_cmt.tcl
|
||||
mkdir -p build
|
||||
cd build/ && ${XRAY_VIVADO} -mode batch -source ${FUZDIR}/output_cmt.tcl
|
||||
touch build/dump.ok
|
||||
endif
|
||||
|
||||
generate: $(SPECIMENS_OK)
|
||||
|
||||
|
|
|
|||
|
|
@ -28,11 +28,6 @@ proc print_tile_pips {tile_type filename} {
|
|||
continue
|
||||
}
|
||||
|
||||
# TODO: Support CLK sources from PS7 hardblock
|
||||
if [string match *PSS_HCLK* $src_node] {
|
||||
continue
|
||||
}
|
||||
|
||||
if {[llength [get_nodes -uphill -of_objects [get_nodes -of_objects $dst]]] != 1} {
|
||||
set pip_string "$tile_type.[regsub {.*/} $dst ""].[regsub {.*/} $src ""]"
|
||||
if ![dict exists $pips $pip_string] {
|
||||
|
|
|
|||
|
|
@ -246,9 +246,9 @@ proc run {} {
|
|||
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets]
|
||||
|
||||
place_design
|
||||
route_design
|
||||
route_design -directive Quick
|
||||
route_todo
|
||||
route_design
|
||||
route_design -directive Quick
|
||||
|
||||
write_checkpoint -force design.dcp
|
||||
write_bitstream -force design.bit
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
create_project -force -part $::env(XRAY_PART) design design
|
||||
set_property design_mode PinPlanning [current_fileset]
|
||||
open_io_design -name io_1
|
||||
|
||||
set fp [open "pss_clocks.csv" "w"]
|
||||
puts $fp "pin,wire,tile,clock_regions"
|
||||
|
||||
# List all PSS_HCLK wires
|
||||
set pss_clk_wires [get_wires *PSS_HCLK* -of_objects [get_tiles PSS*]]
|
||||
foreach wire $pss_clk_wires {
|
||||
|
||||
# Get PIPs that mention the wire inside a CLK_HROW tile. Take the first one.
|
||||
set pips [get_pips CLK_HROW_* -of_objects [get_nodes -of_objects $wire]]
|
||||
set pip [lindex $pips 0]
|
||||
|
||||
# Get the CLK_HROW tile.
|
||||
set tile [get_tiles -of_objects $pip]
|
||||
|
||||
# Get the name of the input wire of the CLK_HROW tile. This is different
|
||||
# than the name of the PSS clock wire. Do it by parsing the PIP name
|
||||
set cmt_wire [lindex [split [lindex [split $pip "-"] 0] "."] 1]
|
||||
|
||||
# Get clock regions of the tile. CLK_HROW tiles span two regions.
|
||||
set regions [dict create]
|
||||
foreach site [get_sites -of_objects $tile] {
|
||||
set region [get_property CLOCK_REGION $site]
|
||||
dict incr regions $region
|
||||
}
|
||||
|
||||
set regions [dict keys $regions]
|
||||
|
||||
# Get uphill PIP, parse its name to get the PS7 wire name. This will be
|
||||
# actually the wire of the PSS tile but the important part of the name
|
||||
# is the same.
|
||||
set pip [get_pips -uphill -of_objects $wire]
|
||||
set pin [lindex [split [lindex [split $pip "."] 1] "-"] 0]
|
||||
|
||||
puts $fp "$pin,$cmt_wire,$tile,$regions"
|
||||
}
|
||||
|
||||
close $fp
|
||||
|
|
@ -5,15 +5,22 @@ import re
|
|||
random.seed(int(os.getenv("SEED"), 16))
|
||||
from prjxray import util
|
||||
from prjxray import verilog
|
||||
from prjxray.grid_types import GridLoc
|
||||
from prjxray.db import Database
|
||||
from prjxray.lut_maker import LutMaker
|
||||
from io import StringIO
|
||||
import csv
|
||||
import sys
|
||||
|
||||
CMT_XY_FUN = util.create_xy_fun(prefix='')
|
||||
BUFGCTRL_XY_FUN = util.create_xy_fun('BUFGCTRL_')
|
||||
BUFHCE_XY_FUN = util.create_xy_fun('BUFHCE_')
|
||||
|
||||
|
||||
def eprint(*args, **kwargs):
|
||||
print(*args, file=sys.stderr, **kwargs)
|
||||
|
||||
|
||||
def gen_sites(desired_site_type):
|
||||
db = Database(util.get_db_root())
|
||||
grid = db.grid()
|
||||
|
|
@ -42,6 +49,12 @@ def gen_bufhce_sites():
|
|||
yield tile_name, sorted(sites)
|
||||
|
||||
|
||||
def get_cmt_loc(cmt_tile_name):
|
||||
db = Database(util.get_db_root())
|
||||
grid = db.grid()
|
||||
return grid.loc_of_tilename(cmt_tile_name)
|
||||
|
||||
|
||||
def read_site_to_cmt():
|
||||
""" Yields clock sources and which CMT they route within. """
|
||||
with open(os.path.join(os.getenv('FUZDIR'), 'build',
|
||||
|
|
@ -51,6 +64,13 @@ def read_site_to_cmt():
|
|||
yield (site, cmt)
|
||||
|
||||
|
||||
def read_pss_clocks():
|
||||
with open(os.path.join(os.getenv('FUZDIR'), 'build',
|
||||
'pss_clocks.csv')) as f:
|
||||
for l in csv.DictReader(f):
|
||||
yield l
|
||||
|
||||
|
||||
class ClockSources(object):
|
||||
""" Class for tracking clock sources.
|
||||
|
||||
|
|
@ -305,16 +325,21 @@ def main():
|
|||
PLLE2_ADV
|
||||
BUFGCTRL
|
||||
Local INT connect
|
||||
|
||||
PS7 (Zynq)
|
||||
"""
|
||||
|
||||
print('''
|
||||
// SEED={}
|
||||
module top();
|
||||
''')
|
||||
'''.format(os.getenv('SEED')))
|
||||
|
||||
is_zynq = os.getenv('XRAY_DATABASE') == 'zynq7'
|
||||
clock_sources = ClockSources()
|
||||
|
||||
site_to_cmt = dict(read_site_to_cmt())
|
||||
|
||||
clock_sources = ClockSources()
|
||||
if is_zynq:
|
||||
pss_clocks = list(read_pss_clocks())
|
||||
|
||||
# To ensure that all left or right sources are used, sometimes only MMCM/PLL
|
||||
# sources are allowed. The force of ODD/EVEN/BOTH further biases the
|
||||
|
|
@ -426,6 +451,57 @@ module top();
|
|||
.O(O_{site})
|
||||
);""".format(site=site))
|
||||
|
||||
if is_zynq:
|
||||
|
||||
# FCLK clocks. Those are generated by the PS and go directly to one of
|
||||
# the CLK_HROW tile.
|
||||
clocks = [
|
||||
"PSS_FCLKCLK0",
|
||||
"PSS_FCLKCLK1",
|
||||
"PSS_FCLKCLK2",
|
||||
"PSS_FCLKCLK3",
|
||||
]
|
||||
|
||||
loc, _, site = next(gen_sites('PS7'))
|
||||
|
||||
print("")
|
||||
|
||||
# Add clock sources and generate wires
|
||||
for wire in clocks:
|
||||
clock_info = [d for d in pss_clocks if d["pin"] == wire][0]
|
||||
|
||||
# CMT tile
|
||||
cmt_tile = clock_info["tile"]
|
||||
cmt_loc = get_cmt_loc(cmt_tile)
|
||||
|
||||
# Add only if the input wire is in the todo list
|
||||
dsts = [k for k, v in todos.items() if clock_info["wire"] in v]
|
||||
if len(dsts) > 0:
|
||||
|
||||
# Wire source clock region. The PS7 is always left of the
|
||||
# CLK_HROW tile, but it does not matter here.
|
||||
regions = clock_info["clock_regions"].split()
|
||||
regions = sorted([(int(r[1]), int(r[3])) for r in regions])
|
||||
|
||||
# Add the clock source
|
||||
cmt = "X{}Y{}".format(regions[0][0], regions[0][1])
|
||||
clock_sources.add_clock_source(wire, cmt, cmt_loc)
|
||||
|
||||
print(" wire {};".format(wire))
|
||||
|
||||
print(
|
||||
"""
|
||||
(* KEEP, DONT_TOUCH, LOC = "{site}" *)
|
||||
PS7 ps7_{site} (
|
||||
.FCLKCLK({{{fclk3}, {fclk2}, {fclk1}, {fclk0}}})
|
||||
);
|
||||
""".format(
|
||||
site=site,
|
||||
fclk0=clocks[0],
|
||||
fclk1=clocks[1],
|
||||
fclk2=clocks[2],
|
||||
fclk3=clocks[3]))
|
||||
|
||||
luts = LutMaker()
|
||||
bufhs = StringIO()
|
||||
bufgs = StringIO()
|
||||
|
|
|
|||
Loading…
Reference in New Issue