blob: be162cdbe125d23b021b47b0d1da0b1a6659e8ae [file] [log] [blame]
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (C) 2017-2020 The Project X-Ray Authors.
#
# Use of this source code is governed by a ISC-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/ISC
#
# SPDX-License-Identifier: ISC
import json
import io
import os
import random
import re
random.seed(int(os.getenv("SEED"), 16))
from prjxray import util
from prjxray import lut_maker
from prjxray import verilog
from prjxray.db import Database
def gen_sites():
db = Database(util.get_db_root(), util.get_part())
grid = db.grid()
for tile_name in sorted(grid.tiles()):
loc = grid.loc_of_tilename(tile_name)
gridinfo = grid.gridinfo_at_loc(loc)
if gridinfo.tile_type.endswith("_SING"):
continue
# Y9 tiles have frame address 1 frame higher than the rest
# Need to investigate what is so special about them
if tile_name.endswith("Y9"):
continue
sites = []
for site_name, site_type in gridinfo.sites.items():
if site_type == 'IDELAYE2_FINEDELAY':
yield tile_name, site_name
def write_params(params):
pinstr = 'tile,isone,site\n'
for vals in params:
pinstr += ','.join(map(str, vals)) + '\n'
open('params.csv', 'w').write(pinstr)
def use_idelay(p, luts, connects):
print(
'''
wire idelay_{site};
(* KEEP, DONT_TOUCH, LOC = "{site}" *)
IDELAYE2_FINEDELAY #(
.HIGH_PERFORMANCE_MODE("{param}"),
.DELAY_SRC("DATAIN")
) idelay_site_{site} (
.DATAIN({onet}),
.DATAOUT(idelay_{site})
);
assign {net} = idelay_{site};
'''.format(
onet=luts.get_next_output_net(),
net=luts.get_next_input_net(),
param="TRUE" if p['isone'] else "FALSE",
**p),
file=connects)
def run():
luts = lut_maker.LutMaker()
connects = io.StringIO()
tile_params = []
params = []
sites = sorted(list(gen_sites()))
for idx, ((tile, site), isone) in enumerate(zip(
sites, util.gen_fuzz_states(len(sites)))):
p = {}
p['tile'] = tile
p['site'] = site
p['isone'] = isone
params.append(p)
tile_params.append((tile, p['isone'], site))
write_params(tile_params)
print('''
module top();
''')
# Always output a LUT6 to make placer happy.
print('''
(* KEEP, DONT_TOUCH *)
LUT6 dummy_lut();
''')
# Need IDELAYCTRL for IDEALAYs
print('''
(* KEEP, DONT_TOUCH *)
IDELAYCTRL();
''')
for p in params:
use_idelay(p, luts, connects)
for l in luts.create_wires_and_luts():
print(l)
print(connects.getvalue())
print("endmodule")
if __name__ == '__main__':
run()