blob: eb5bec791d29b57307096994525afd5fbe9452c6 [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
from prjxray.segmaker import Segmaker
from prjxray import verilog
def bitfilter(frame, word):
if frame < 28:
return False
return True
def bus_tags(segmk, ps, site):
segmk.add_site_tag(site, 'IN_USE', ps['active'])
if not ps['active']:
return
for k in ps:
segmk.add_site_tag(site, 'param_' + k + '_' + str(ps[k]), 1)
for reg, invert in [
('RST', 1),
('PWRDWN', 1),
('CLKINSEL', 0),
]:
opt = 'IS_{}_INVERTED'.format(reg)
if invert:
segmk.add_site_tag(site, 'ZINV_' + reg, 1 ^ ps[opt])
else:
segmk.add_site_tag(site, 'INV_' + reg, ps[opt])
for opt in ['OPTIMIZED', 'HIGH', 'LOW']:
if verilog.unquote(ps['BANDWIDTH']) == opt:
segmk.add_site_tag(site, 'BANDWIDTH.' + opt, 1)
elif verilog.unquote(ps['BANDWIDTH']) == 'LOW':
segmk.add_site_tag(site, 'BANDWIDTH.' + opt, 0)
for opt in ['ZHOLD', 'BUF_IN', 'EXTERNAL', 'INTERNAL']:
continue
opt_match = verilog.unquote(ps['COMPENSATION']) == opt
if ps['clkfbin_conn'] == '':
segmk.add_site_tag(site, 'COMP.NOFB_' + opt, opt_match)
segmk.add_site_tag(site, 'COMP.ZNOFB_' + opt, opt_match)
continue
for conn in ['clk', 'clkfbout_mult_BUFG_' + ps['site'],
'clkfbout_mult_' + ps['site']]:
conn_match = ps['clkfbin_conn'] == conn
segmk.add_site_tag(
site, 'COMP.' + opt + '_' + conn + '_' + ps['site'], opt_match
and conn_match)
segmk.add_site_tag(
site, 'COMP.Z' + opt + '_' + conn + '_' + ps['site'],
not opt_match and conn_match)
segmk.add_site_tag(
site, 'COMP.Z' + opt + '_Z' + conn + '_' + ps['site'],
not opt_match and not conn_match)
segmk.add_site_tag(
site, 'COMP.' + opt + '_Z' + conn + '_' + ps['site'], opt_match
and not conn_match)
bufg_on_clkin = \
'BUFG' in ps['clkin1_conn'] or \
'BUFG' in ps['clkin2_conn']
# This one is in conflict with some clock routing bits.
# match = verilog.unquote(ps['COMPENSATION']) in ['BUF_IN', 'EXTERNAL']
# if not match:
# if verilog.unquote(ps['COMPENSATION']) == 'ZHOLD' and bufg_on_clkin:
# match = True
# segmk.add_site_tag(
# site, 'COMPENSATION.BUF_IN_OR_EXTERNAL_OR_ZHOLD_CLKIN_BUF', match)
match = verilog.unquote(ps['COMPENSATION']) in ['ZHOLD']
segmk.add_site_tag(
site, 'COMPENSATION.Z_ZHOLD_OR_CLKIN_BUF', not match
or (match and bufg_on_clkin))
segmk.add_site_tag(
site, 'COMPENSATION.ZHOLD_NO_CLKIN_BUF', match and \
not bufg_on_clkin
)
segmk.add_site_tag(
site, 'COMPENSATION.ZHOLD_NO_CLKIN_BUF_NO_TOP', match and \
not bufg_on_clkin and \
site != "PLLE2_ADV_X0Y3" and site != "PLLE2_ADV_X0Y0"
)
segmk.add_site_tag(
site, 'COMP.ZHOLD_NO_CLKIN_BUF_TOP', match and \
not bufg_on_clkin and \
(site == "PLLE2_ADV_X0Y3" or site == "PLLE2_ADV_X0Y0")
)
# No INTERNAL as it has conflicting bits
for opt in ['ZHOLD', 'BUF_IN', 'EXTERNAL']:
if opt in ['BUF_IN', 'EXTERNAL']:
if ps['clkfbin_conn'] not in ['', 'clk']:
continue
if site == "PLLE2_ADV_X0Y2" and opt == 'ZHOLD':
segmk.add_site_tag(
site, 'TOP.COMPENSATION.' + opt,
verilog.unquote(ps['COMPENSATION']) == opt)
else:
segmk.add_site_tag(
site, 'COMPENSATION.' + opt,
verilog.unquote(ps['COMPENSATION']) == opt)
segmk.add_site_tag(
site, 'COMPENSATION.Z_' + opt,
verilog.unquote(ps['COMPENSATION']) != opt)
# This one has bits that are in conflict with clock routing
# segmk.add_site_tag(
# site, 'COMPENSATION.INTERNAL',
# verilog.unquote(ps['COMPENSATION']) in ['INTERNAL'])
for param in ['CLKFBOUT_MULT']:
paramadj = int(ps[param])
bitstr = [int(x) for x in "{0:09b}".format(paramadj)[::-1]]
for i in range(7):
segmk.add_site_tag(site, '%s[%u]' % (param, i), bitstr[i])
for param in ['CLKOUT0_DUTY_CYCLE']:
assert ps[param][:2] == '0.', ps[param]
assert len(ps[param]) == 5
paramadj = int(ps[param][2:])
bitstr = [int(x) for x in "{0:011b}".format(paramadj)[::-1]]
for i in range(10):
segmk.add_site_tag(site, '%s[%u]' % (param, i), bitstr[i])
for param, bits in [
('CLKOUT0_DIVIDE', 7),
('CLKOUT1_DIVIDE', 7),
('CLKOUT2_DIVIDE', 7),
('CLKOUT3_DIVIDE', 7),
('CLKOUT4_DIVIDE', 7),
('CLKOUT5_DIVIDE', 7),
('DIVCLK_DIVIDE', 6),
]:
# 1-128 => 0-127 for actual 7 bit value
paramadj = int(ps[param])
if paramadj < 4:
continue
bitstr = [int(x) for x in "{0:09b}".format(paramadj)[::-1]]
for i in range(bits):
segmk.add_site_tag(site, '%s[%u]' % (param, i), bitstr[i])
segmk.add_site_tag(
site, 'STARTUP_WAIT',
verilog.unquote(ps['STARTUP_WAIT']) == 'TRUE')
def run():
segmk = Segmaker("design.bits")
print("Loading tags")
f = open('params.jl', 'r')
f.readline()
for l in f:
j = json.loads(l)
bus_tags(segmk, j, j['site'])
segmk.compile(bitfilter=bitfilter)
segmk.write()
run()