mirror of https://github.com/openXC7/prjxray.git
Modified fuzzer 041 to solve Zynq PS7 FCLK clocks.
Signed-off-by: Maciej Kurc <mkurc@antmicro.com>
This commit is contained in:
parent
7bd13efdcb
commit
6086e6d6f5
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -246,9 +246,17 @@ proc run {} {
|
|||
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets]
|
||||
|
||||
place_design
|
||||
route_design
|
||||
|
||||
puts "Routing design #1"
|
||||
route_design -directive Quick
|
||||
write_checkpoint -force design_initially_routed.dcp
|
||||
|
||||
puts "Routing TODOs"
|
||||
route_todo
|
||||
route_design
|
||||
write_checkpoint -force design_todo_routed.dcp
|
||||
|
||||
puts "Routing design #2"
|
||||
route_design -directive Quick
|
||||
|
||||
write_checkpoint -force design.dcp
|
||||
write_bitstream -force design.bit
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ set_property design_mode PinPlanning [current_fileset]
|
|||
open_io_design -name io_1
|
||||
|
||||
set fp [open "cmt_regions.csv" "w"]
|
||||
foreach site_type {MMCME2_ADV PLLE2_ADV BUFHCE BUFR} {
|
||||
foreach site_type {MMCME2_ADV PLLE2_ADV BUFHCE BUFR PS7} {
|
||||
foreach site [get_sites -filter "SITE_TYPE == $site_type"] {
|
||||
puts $fp "$site,[get_property CLOCK_REGION $site]"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
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,tile"
|
||||
|
||||
# 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.
|
||||
set pips [get_pips CLK_HROW_* -of_objects [get_nodes -of_objects $wire]]
|
||||
# Get the CLK_HROW tile.
|
||||
set tile [get_tiles -of_objects [lindex $pips 0]]
|
||||
|
||||
# Get uphill PIP, parse its name to get the PS7 wire name.
|
||||
set pip [get_pips -uphill -of_objects $wire]
|
||||
set pin [lindex [split [lindex [split $pip "."] 1] "-"] 0]
|
||||
|
||||
puts $fp "$pin,$tile"
|
||||
}
|
||||
|
||||
close $fp
|
||||
|
|
@ -5,14 +5,19 @@ 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())
|
||||
|
|
@ -41,6 +46,10 @@ def gen_bufhce_sites():
|
|||
if 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. """
|
||||
|
|
@ -50,6 +59,11 @@ def read_site_to_cmt():
|
|||
site, cmt = l.strip().split(',')
|
||||
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.
|
||||
|
|
@ -147,7 +161,7 @@ class ClockSources(object):
|
|||
if src_loc is None:
|
||||
continue
|
||||
if src_loc.grid_y <= loc.grid_y:
|
||||
bufg_sources.extend(cmt_sources)
|
||||
bufg_sources.extend(cmt_sources)
|
||||
elif bottom:
|
||||
for src_loc, cmt_sources in self.sources_by_loc.items():
|
||||
if src_loc is None:
|
||||
|
|
@ -305,18 +319,23 @@ def main():
|
|||
PLLE2_ADV
|
||||
BUFGCTRL
|
||||
Local INT connect
|
||||
|
||||
PS7 (Zynq)
|
||||
"""
|
||||
|
||||
print('''
|
||||
// SEED={}
|
||||
module top();
|
||||
''')
|
||||
'''.format(os.getenv('SEED')))
|
||||
|
||||
site_to_cmt = dict(read_site_to_cmt())
|
||||
|
||||
is_zynq = os.getenv('XRAY_DATABASE') == 'zynq7'
|
||||
clock_sources = ClockSources()
|
||||
|
||||
site_to_cmt = dict(read_site_to_cmt())
|
||||
|
||||
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
|
||||
# clock sources to the left or right column inputs.
|
||||
|
|
@ -427,6 +446,42 @@ module top();
|
|||
.O(O_{site})
|
||||
);""".format(site=site))
|
||||
|
||||
if is_zynq:
|
||||
|
||||
clocks = [
|
||||
"PSS_FCLKCLK0",
|
||||
"PSS_FCLKCLK1",
|
||||
"PSS_FCLKCLK2",
|
||||
"PSS_FCLKCLK3",
|
||||
]
|
||||
|
||||
loc, _, site = next(gen_sites('PS7'))
|
||||
|
||||
print("")
|
||||
|
||||
for wire in clocks:
|
||||
cmt = site_to_cmt[site]
|
||||
cmt_tile = [d["tile"] for d in pss_clocks if d["pin"] == wire][0]
|
||||
cmt_loc = get_cmt_loc(cmt_tile)
|
||||
|
||||
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]
|
||||
))
|
||||
|
||||
used_pss_clocks = set()
|
||||
|
||||
luts = LutMaker()
|
||||
bufhs = StringIO()
|
||||
bufgs = StringIO()
|
||||
|
|
@ -497,6 +552,12 @@ module top();
|
|||
if random.random() > .05:
|
||||
wire_name = clock_sources.get_random_source(site_to_cmt[site])
|
||||
|
||||
if wire_name is not None and wire_name.startswith("PSS"):
|
||||
if wire_name not in used_pss_clocks:
|
||||
used_pss_clocks.add(wire_name)
|
||||
else:
|
||||
wire_name = None
|
||||
|
||||
if wire_name is None:
|
||||
continue
|
||||
|
||||
|
|
@ -532,28 +593,6 @@ module top();
|
|||
break
|
||||
break
|
||||
|
||||
if is_zynq:
|
||||
for loc, _, site in gen_sites('PS7'):
|
||||
print("""
|
||||
(* KEEP, DONT_TOUCH, LOC = "{site}" *)
|
||||
PS7 ps7_{site} (
|
||||
.FCLKCLK({fclk3, fclk2, fclk1, fclk0}),
|
||||
.TESTPLLCLKOUT({testpllclkout2, testpllclkout1, testpllclkout0}),
|
||||
.TESTPLLNEWCLK({testpllnewclk2, testpllnewclk1, testpllnewclk0}),
|
||||
);
|
||||
""".format(
|
||||
site=site,
|
||||
fclk0=,
|
||||
fclk1=,
|
||||
fclk2=,
|
||||
fclk3=,
|
||||
testpllclkout2=,
|
||||
testpllclkout1=,
|
||||
testpllclkout0=,
|
||||
testpllnewclk2=,
|
||||
testpllnewclk1=,
|
||||
testpllnewclk0=,
|
||||
))
|
||||
|
||||
|
||||
for l in luts.create_wires_and_luts():
|
||||
|
|
@ -569,7 +608,9 @@ module top();
|
|||
if random.randint(0, 1):
|
||||
wire_name = clock_sources.get_bufg_source(
|
||||
loc, tile_type, site, todos, 1, used_only)
|
||||
if wire_name is not None:
|
||||
if wire_name is not None and wire_name not in used_pss_clocks:
|
||||
if wire_name.startswith("PSS"):
|
||||
used_pss_clocks.add(wire_name)
|
||||
print(
|
||||
"""
|
||||
assign I1_{site} = {wire_name};""".format(
|
||||
|
|
@ -580,7 +621,9 @@ module top();
|
|||
if random.randint(0, 1):
|
||||
wire_name = clock_sources.get_bufg_source(
|
||||
loc, tile_type, site, todos, 0, used_only)
|
||||
if wire_name is not None:
|
||||
if wire_name is not None and wire_name not in used_pss_clocks:
|
||||
if wire_name.startswith("PSS"):
|
||||
used_pss_clocks.add(wire_name)
|
||||
print(
|
||||
"""
|
||||
assign I0_{site} = {wire_name};""".format(
|
||||
|
|
|
|||
Loading…
Reference in New Issue