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.
|
# These PIPs all appear to be either a 2 bit solutions.
|
||||||
SEGMATCH_FLAGS=-c 2
|
SEGMATCH_FLAGS=-c 2
|
||||||
SPECIMENS_DEPS=build/cmt_regions.csv
|
SPECIMENS_DEPS=build/dump.ok
|
||||||
A_PIPLIST=clk_hrow_bot_r.txt
|
A_PIPLIST=clk_hrow_bot_r.txt
|
||||||
|
|
||||||
include ../pip_loop.mk
|
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_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
|
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
|
mkdir -p build
|
||||||
cd build/ && ${XRAY_VIVADO} -mode batch -source ${FUZDIR}/output_cmt.tcl
|
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)
|
generate: $(SPECIMENS_OK)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -246,9 +246,17 @@ proc run {} {
|
||||||
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets]
|
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets]
|
||||||
|
|
||||||
place_design
|
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_todo
|
||||||
route_design
|
write_checkpoint -force design_todo_routed.dcp
|
||||||
|
|
||||||
|
puts "Routing design #2"
|
||||||
|
route_design -directive Quick
|
||||||
|
|
||||||
write_checkpoint -force design.dcp
|
write_checkpoint -force design.dcp
|
||||||
write_bitstream -force design.bit
|
write_bitstream -force design.bit
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ set_property design_mode PinPlanning [current_fileset]
|
||||||
open_io_design -name io_1
|
open_io_design -name io_1
|
||||||
|
|
||||||
set fp [open "cmt_regions.csv" "w"]
|
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"] {
|
foreach site [get_sites -filter "SITE_TYPE == $site_type"] {
|
||||||
puts $fp "$site,[get_property CLOCK_REGION $site]"
|
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))
|
random.seed(int(os.getenv("SEED"), 16))
|
||||||
from prjxray import util
|
from prjxray import util
|
||||||
from prjxray import verilog
|
from prjxray import verilog
|
||||||
|
from prjxray.grid_types import GridLoc
|
||||||
from prjxray.db import Database
|
from prjxray.db import Database
|
||||||
from prjxray.lut_maker import LutMaker
|
from prjxray.lut_maker import LutMaker
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
|
import csv
|
||||||
|
import sys
|
||||||
|
|
||||||
CMT_XY_FUN = util.create_xy_fun(prefix='')
|
CMT_XY_FUN = util.create_xy_fun(prefix='')
|
||||||
BUFGCTRL_XY_FUN = util.create_xy_fun('BUFGCTRL_')
|
BUFGCTRL_XY_FUN = util.create_xy_fun('BUFGCTRL_')
|
||||||
BUFHCE_XY_FUN = util.create_xy_fun('BUFHCE_')
|
BUFHCE_XY_FUN = util.create_xy_fun('BUFHCE_')
|
||||||
|
|
||||||
|
def eprint(*args, **kwargs):
|
||||||
|
print(*args, file=sys.stderr, **kwargs)
|
||||||
|
|
||||||
def gen_sites(desired_site_type):
|
def gen_sites(desired_site_type):
|
||||||
db = Database(util.get_db_root())
|
db = Database(util.get_db_root())
|
||||||
|
|
@ -41,6 +46,10 @@ def gen_bufhce_sites():
|
||||||
if sites:
|
if sites:
|
||||||
yield tile_name, sorted(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():
|
def read_site_to_cmt():
|
||||||
""" Yields clock sources and which CMT they route within. """
|
""" Yields clock sources and which CMT they route within. """
|
||||||
|
|
@ -50,6 +59,11 @@ def read_site_to_cmt():
|
||||||
site, cmt = l.strip().split(',')
|
site, cmt = l.strip().split(',')
|
||||||
yield (site, 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 ClockSources(object):
|
||||||
""" Class for tracking clock sources.
|
""" Class for tracking clock sources.
|
||||||
|
|
@ -147,7 +161,7 @@ class ClockSources(object):
|
||||||
if src_loc is None:
|
if src_loc is None:
|
||||||
continue
|
continue
|
||||||
if src_loc.grid_y <= loc.grid_y:
|
if src_loc.grid_y <= loc.grid_y:
|
||||||
bufg_sources.extend(cmt_sources)
|
bufg_sources.extend(cmt_sources)
|
||||||
elif bottom:
|
elif bottom:
|
||||||
for src_loc, cmt_sources in self.sources_by_loc.items():
|
for src_loc, cmt_sources in self.sources_by_loc.items():
|
||||||
if src_loc is None:
|
if src_loc is None:
|
||||||
|
|
@ -305,18 +319,23 @@ def main():
|
||||||
PLLE2_ADV
|
PLLE2_ADV
|
||||||
BUFGCTRL
|
BUFGCTRL
|
||||||
Local INT connect
|
Local INT connect
|
||||||
|
PS7 (Zynq)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
print('''
|
print('''
|
||||||
|
// SEED={}
|
||||||
module top();
|
module top();
|
||||||
''')
|
'''.format(os.getenv('SEED')))
|
||||||
|
|
||||||
site_to_cmt = dict(read_site_to_cmt())
|
|
||||||
|
|
||||||
is_zynq = os.getenv('XRAY_DATABASE') == 'zynq7'
|
is_zynq = os.getenv('XRAY_DATABASE') == 'zynq7'
|
||||||
clock_sources = ClockSources()
|
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
|
# 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
|
# sources are allowed. The force of ODD/EVEN/BOTH further biases the
|
||||||
# clock sources to the left or right column inputs.
|
# clock sources to the left or right column inputs.
|
||||||
|
|
@ -427,6 +446,42 @@ module top();
|
||||||
.O(O_{site})
|
.O(O_{site})
|
||||||
);""".format(site=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()
|
luts = LutMaker()
|
||||||
bufhs = StringIO()
|
bufhs = StringIO()
|
||||||
bufgs = StringIO()
|
bufgs = StringIO()
|
||||||
|
|
@ -497,6 +552,12 @@ module top();
|
||||||
if random.random() > .05:
|
if random.random() > .05:
|
||||||
wire_name = clock_sources.get_random_source(site_to_cmt[site])
|
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:
|
if wire_name is None:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
@ -532,28 +593,6 @@ module top();
|
||||||
break
|
break
|
||||||
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():
|
for l in luts.create_wires_and_luts():
|
||||||
|
|
@ -569,7 +608,9 @@ module top();
|
||||||
if random.randint(0, 1):
|
if random.randint(0, 1):
|
||||||
wire_name = clock_sources.get_bufg_source(
|
wire_name = clock_sources.get_bufg_source(
|
||||||
loc, tile_type, site, todos, 1, used_only)
|
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(
|
print(
|
||||||
"""
|
"""
|
||||||
assign I1_{site} = {wire_name};""".format(
|
assign I1_{site} = {wire_name};""".format(
|
||||||
|
|
@ -580,7 +621,9 @@ module top();
|
||||||
if random.randint(0, 1):
|
if random.randint(0, 1):
|
||||||
wire_name = clock_sources.get_bufg_source(
|
wire_name = clock_sources.get_bufg_source(
|
||||||
loc, tile_type, site, todos, 0, used_only)
|
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(
|
print(
|
||||||
"""
|
"""
|
||||||
assign I0_{site} = {wire_name};""".format(
|
assign I0_{site} = {wire_name};""".format(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue