mirror of https://github.com/openXC7/prjxray.git
187 lines
5.9 KiB
Python
187 lines
5.9 KiB
Python
#!/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()
|