| #!/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, all_params, site): | 
 |     segmk.add_site_tag(site, 'IN_USE', ps['active']) | 
 |  | 
 |     if not ps['active']: | 
 |         return | 
 |  | 
 |     params = all_params[site]["params"] | 
 |  | 
 |     #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), | 
 |         ('PSEN', 1), | 
 |         ('PSINCDEC', 1), | 
 |     ]: | 
 |         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) | 
 |  | 
 |     # "INTERNAL" compensation conflicts with the CLKFBOUT2IN->CLKFBIN PIP. | 
 |     # There is no telling which of these two is actually controlled by those | 
 |     # bits. It is better to leave them for the PIP. | 
 |     COMPENSATION_OPTS = ['ZHOLD', 'BUF_IN', 'EXTERNAL'] | 
 |  | 
 |     for opt in COMPENSATION_OPTS: | 
 |         val = params["COMPENSATION"] == opt | 
 |         segmk.add_site_tag(site, "COMP.{}".format(opt), val) | 
 |         segmk.add_site_tag(site, "COMP.Z_{}".format(opt), not val) | 
 |  | 
 |     opt = (verilog.unquote(ps["SS_EN"]) == "TRUE") | 
 |     segmk.add_site_tag(site, "SS_EN", opt) | 
 |  | 
 |     for param in ['CLKFBOUT_MULT_F']: | 
 |         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_F', 7), | 
 |         ('CLKOUT1_DIVIDE', 7), | 
 |         ('CLKOUT2_DIVIDE', 7), | 
 |         ('CLKOUT3_DIVIDE', 7), | 
 |         ('CLKOUT4_DIVIDE', 7), | 
 |         ('CLKOUT5_DIVIDE', 7), | 
 |         ('CLKOUT6_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 params") | 
 |     f = open("params.json") | 
 |     params = json.load(f) | 
 |     params = {p["site"]: p for p in params} | 
 |  | 
 |     print("Loading tags") | 
 |     f = open('params.jl', 'r') | 
 |     f.readline() | 
 |     for l in f: | 
 |         j = json.loads(l) | 
 |         bus_tags(segmk, j, params, j['site']) | 
 |  | 
 |     segmk.compile(bitfilter=bitfilter) | 
 |     segmk.write() | 
 |  | 
 |  | 
 | run() |