mirror of https://github.com/openXC7/prjxray.git
Automatic inference of CLK_HROW with PS7 clocks, use of todo list for PS7 clock sources.
Signed-off-by: Maciej Kurc <mkurc@antmicro.com>
This commit is contained in:
parent
fb65464c42
commit
24ccfb3bb5
|
|
@ -246,16 +246,8 @@ proc run {} {
|
|||
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets]
|
||||
|
||||
place_design
|
||||
|
||||
puts "Routing design #1"
|
||||
route_design -directive Quick
|
||||
write_checkpoint -force design_initially_routed.dcp
|
||||
|
||||
puts "Routing TODOs"
|
||||
route_todo
|
||||
write_checkpoint -force design_todo_routed.dcp
|
||||
|
||||
puts "Routing design #2"
|
||||
route_design -directive Quick
|
||||
|
||||
write_checkpoint -force design.dcp
|
||||
|
|
|
|||
|
|
@ -3,21 +3,39 @@ set_property design_mode PinPlanning [current_fileset]
|
|||
open_io_design -name io_1
|
||||
|
||||
set fp [open "pss_clocks.csv" "w"]
|
||||
puts $fp "pin,tile"
|
||||
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.
|
||||
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.
|
||||
# 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,$tile"
|
||||
puts $fp "$pin,$cmt_wire,$tile,$regions"
|
||||
}
|
||||
|
||||
close $fp
|
||||
|
|
|
|||
|
|
@ -16,9 +16,11 @@ 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()
|
||||
|
|
@ -46,11 +48,13 @@ 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. """
|
||||
with open(os.path.join(os.getenv('FUZDIR'), 'build',
|
||||
|
|
@ -59,12 +63,14 @@ 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:
|
||||
'pss_clocks.csv')) as f:
|
||||
for l in csv.DictReader(f):
|
||||
yield l
|
||||
|
||||
|
||||
class ClockSources(object):
|
||||
""" Class for tracking clock sources.
|
||||
|
||||
|
|
@ -161,7 +167,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:
|
||||
|
|
@ -327,7 +333,6 @@ def main():
|
|||
module top();
|
||||
'''.format(os.getenv('SEED')))
|
||||
|
||||
|
||||
is_zynq = os.getenv('XRAY_DATABASE') == 'zynq7'
|
||||
clock_sources = ClockSources()
|
||||
|
||||
|
|
@ -448,37 +453,54 @@ module top();
|
|||
|
||||
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",
|
||||
"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:
|
||||
cmt_tile = [d["tile"] for d in pss_clocks if d["pin"] == wire][0]
|
||||
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)
|
||||
|
||||
# FIXME: HACK
|
||||
clock_sources.add_clock_source(wire, "X0Y0", cmt_loc)
|
||||
# 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("""
|
||||
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]
|
||||
))
|
||||
site=site,
|
||||
fclk0=clocks[0],
|
||||
fclk1=clocks[1],
|
||||
fclk2=clocks[2],
|
||||
fclk3=clocks[3]))
|
||||
|
||||
luts = LutMaker()
|
||||
bufhs = StringIO()
|
||||
|
|
@ -550,11 +572,6 @@ module top();
|
|||
if random.random() > .05:
|
||||
wire_name = clock_sources.get_random_source(site_to_cmt[site])
|
||||
|
||||
# FIXME: HACK
|
||||
if wire_name is not None and wire_name.startswith("PSS"):
|
||||
if "BOT" not in tile_name:
|
||||
continue
|
||||
|
||||
if wire_name is None:
|
||||
continue
|
||||
|
||||
|
|
@ -590,8 +607,6 @@ module top();
|
|||
break
|
||||
break
|
||||
|
||||
|
||||
|
||||
for l in luts.create_wires_and_luts():
|
||||
print(l)
|
||||
|
||||
|
|
@ -605,7 +620,6 @@ 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:
|
||||
print(
|
||||
"""
|
||||
|
|
@ -617,7 +631,6 @@ 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:
|
||||
print(
|
||||
"""
|
||||
|
|
@ -628,6 +641,5 @@ module top();
|
|||
|
||||
print("endmodule")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
|||
Loading…
Reference in New Issue