def handle_data_rate(segmk, d): if 'DATA_WIDTH' not in d: return for opt in ['SDR', 'DDR']: segmk.add_site_tag(d['site'], 'ISERDES.DATA_RATE.{}'.format(opt), verilog.unquote(d['DATA_RATE']) == opt)
def run(): segmk = Segmaker("design.bits") clk_inverts = {} with open('design.csv', 'r') as f: for params in csv.DictReader(f): clk_inverts[params['site']] = params print("Loading tags") f = open('params.jl', 'r') f.readline() for l in f: j = json.loads(l) ps = j['params'] assert j['module'] == 'my_RAMB18E1' site = verilog.unquote(ps['LOC']) isinv_tags(segmk, ps, site, clk_inverts[site]) bus_tags(segmk, ps, site) rw_width_tags(segmk, ps, site) write_mode_tags(segmk, ps, site) write_rstreg_priority(segmk, ps, site) write_rdaddr_collision(segmk, ps, site) def bitfilter(frame, bit): # rw_width_tags() aliasing interconnect on large widths return frame not in (20, 21) segmk.compile(bitfilter=bitfilter) segmk.write()
def gen_iserdes(loc): # Site params params = { "SITE_LOC": verilog.quote(loc), "USE_IDELAY": random.randint(0, 1), "BEL_TYPE": verilog.quote("ISERDESE2"), "INIT_Q1": random.randint(0, 1), "INIT_Q2": random.randint(0, 1), "INIT_Q3": random.randint(0, 1), "INIT_Q4": random.randint(0, 1), "SRVAL_Q1": random.randint(0, 1), "SRVAL_Q2": random.randint(0, 1), "SRVAL_Q3": random.randint(0, 1), "SRVAL_Q4": random.randint(0, 1), "NUM_CE": random.randint(1, 2), # The following one shows negative correlation (0 - not inverted) "IS_D_INVERTED": random.randint(0, 1), # No bits were found for parameters below "IS_OCLKB_INVERTED": random.randint(0, 1), "IS_OCLK_INVERTED": random.randint(0, 1), "IS_CLKDIVP_INVERTED": random.randint(0, 1), "IS_CLKDIV_INVERTED": random.randint(0, 1), "IS_CLKB_INVERTED": random.randint(0, 1), "IS_CLK_INVERTED": random.randint(0, 1), "DYN_CLKDIV_INV_EN": verilog.quote(random.choice(["TRUE", "FALSE"])), "DYN_CLK_INV_EN": verilog.quote(random.choice(["TRUE", "FALSE"])), "IOBDELAY": verilog.quote(random.choice(["NONE", "IBUF", "IFD", "BOTH"])), "OFB_USED": verilog.quote( random.choice(["TRUE"] + ["FALSE"] * 9)), # Force more FALSEs } iface_type = random.choice( ["NETWORKING", "OVERSAMPLE", "MEMORY", "MEMORY_DDR3", "MEMORY_QDR"]) data_rate = random.choice(["SDR", "DDR"]) serdes_mode = random.choice(["MASTER", "SLAVE"]) params["INTERFACE_TYPE"] = verilog.quote(iface_type) params["DATA_RATE"] = verilog.quote(data_rate) params["SERDES_MODE"] = verilog.quote(serdes_mode) # Networking mode if iface_type == "NETWORKING": data_widths = { "SDR": [2, 3, 4, 5, 6, 7, 8], "DDR": [4, 6, 8, 10, 14], } params["DATA_WIDTH"] = random.choice(data_widths[data_rate]) # Others else: params["DATA_WIDTH"] = 4 if verilog.unquote(params["OFB_USED"]) == "TRUE": params["IOBDELAY"] = verilog.quote("NONE") return params
def main(): segmk = Segmaker("design.bits") print("Loading tags") with open('params.json') as f: params = json.load(f) for row in params: base_name = 'BUFHCE_X{}Y{}'.format(row['x'], row['y']) segmk.add_site_tag(row['site'], '{}.IN_USE'.format(base_name), row['IN_USE']) if not row['IN_USE']: continue segmk.add_site_tag(row['site'], '{}.INIT_OUT'.format(base_name), row['INIT_OUT']) segmk.add_site_tag(row['site'], '{}.ZINV_CE'.format(base_name), 1 ^ row['IS_CE_INVERTED']) # SYNC is a zero pattern for opt in ['ASYNC']: segmk.add_site_tag(row['site'], '{}.CE_TYPE.'.format(base_name) + opt, verilog.unquote(row['CE_TYPE']) == opt) segmk.compile() segmk.write()
def write_mode_tags(segmk, ps, site): for param in ["WRITE_MODE_A", "WRITE_MODE_B"]: set_val = verilog.unquote(ps[param]) # WRITE_FIRST: no bits set segmk.add_site_tag(site, '%s_READ_FIRST' % (param), set_val == "READ_FIRST") segmk.add_site_tag(site, '%s_NO_CHANGE' % (param), set_val == "NO_CHANGE")
def handle_data_width(segmk, d): if 'DATA_WIDTH' not in d: return site = d['ologic_loc'] data_rate = verilog.unquote(d['DATA_RATE_OQ']) segmk.add_site_tag( site, 'OSERDES.DATA_WIDTH.{}.W{}'.format(data_rate, d['DATA_WIDTH']), 1)
def main(): segmk = Segmaker("design.bits", verbose=True) # Load tags with open("params.json", "r") as fp: data = json.load(fp) idelay_types = ["FIXED", "VARIABLE", "VAR_LOAD"] delay_srcs = ["IDATAIN", "DATAIN"] # Output tags for params in data: segmk.add_site_tag(params['IDELAY_IN_USE'], 'IN_USE', True) segmk.add_site_tag(params['IDELAY_NOT_IN_USE'], 'IN_USE', False) loc = verilog.unquote(params["LOC"]) # Delay type value = verilog.unquote(params["IDELAY_TYPE"]) value = value.replace("_PIPE", "") # VAR_LOAD and VAR_LOAD_PIPE are the same add_site_group_zero(segmk, loc, "IDELAY_TYPE_", idelay_types, "FIXED", value) # Delay value value = int(params["IDELAY_VALUE"]) for i in range(5): segmk.add_site_tag(loc, "IDELAY_VALUE[%01d]" % i, ((value >> i) & 1) != 0) segmk.add_site_tag(loc, "ZIDELAY_VALUE[%01d]" % i, ((value >> i) & 1) == 0) # Delay source value = verilog.unquote(params["DELAY_SRC"]) for x in delay_srcs: segmk.add_site_tag(loc, "DELAY_SRC_%s" % x, int(value == x)) value = verilog.unquote(params["CINVCTRL_SEL"]) segmk.add_site_tag(loc, "CINVCTRL_SEL", int(value == "TRUE")) value = verilog.unquote(params["PIPE_SEL"]) segmk.add_site_tag(loc, "PIPE_SEL", int(value == "TRUE")) if "IS_C_INVERTED" in params: segmk.add_site_tag(loc, "IS_C_INVERTED", int(params["IS_C_INVERTED"])) segmk.add_site_tag(loc, "ZINV_C", 1 ^ int(params["IS_C_INVERTED"])) segmk.add_site_tag(loc, "IS_DATAIN_INVERTED", int(params["IS_DATAIN_INVERTED"])) if params['IBUF_IN_USE']: value = verilog.unquote(params["HIGH_PERFORMANCE_MODE"]) segmk.add_site_tag(loc, "HIGH_PERFORMANCE_MODE", int(value == "TRUE")) segmk.add_site_tag(loc, "IS_IDATAIN_INVERTED", int(params["IS_IDATAIN_INVERTED"])) segmk.compile(bitfilter=bitfilter) segmk.write()
def run(): segmk = Segmaker("design.bits") print("Loading tags") f = open('params.jl', 'r') design = json.load(f) for p in design: ps = p["params"] if p["site_type"] in "ICAP": param = verilog.unquote(ps["ICAP_WIDTH"]) segmaker.add_site_group_zero(segmk, p["site"], "ICAP_WIDTH_", ["X32", "X8", "X16"], "X32", param) elif p["site_type"] in "BSCAN": param = str(ps["JTAG_CHAIN"]) segmaker.add_site_group_zero(segmk, p["site"], "JTAG_CHAIN_", ["1", "2", "3", "4"], param, param) elif p["site_type"] in "CAPTURE": param = verilog.unquote(ps["ONESHOT"]) segmk.add_site_tag(p["site"], "ONESHOT", True if param in "TRUE" else False) elif p["site_type"] in "STARTUP": param = verilog.unquote(ps["PROG_USR"]) segmk.add_site_tag(p["site"], "PROG_USR", True if param in "TRUE" else False) elif p["site_type"] in "FRAME_ECC": param = verilog.unquote(ps["FARSRC"]) segmaker.add_site_group_zero(segmk, p["site"], "FARSRC_", ["FAR", "EFAR"], param, param) elif p["site_type"] in ["USR_ACCESS", "DCIRESET"]: feature = "ENABLED" segmk.add_site_tag(p["site"], feature, True if ps["ENABLED"] else False) segmk.compile(bitfilter=bitfilter) segmk.write()
def run(): segmk = Segmaker("design.bits") print("Loading tags") f = open('params.jl', 'r') f.readline() for l in f: j = json.loads(l) ps = j['params'] assert j['module'] == 'my_PLLE2_ADV' site = verilog.unquote(ps['LOC']) bus_tags(segmk, ps, site) segmk.compile() segmk.write()
def process_specimen(root): sites = create_sites_from_fasm(root) with open(os.path.join(root, 'params.jl')) as f: params = json.load(f) for p in params: tile = p['tile'] site = p['site'] site_y = int(site[site.find('Y') + 1:]) % 2 if generate.skip_broken_tiles(p): continue site_key = 'IOB_Y{}'.format(site_y) if (tile, site_key) not in sites: assert p['type'] is None, p continue site_from_fasm = sites[(tile, site_key)] assert p['type'] == site_from_fasm['type'], (tile, site_key, p, site_from_fasm) if p['type'] is None: continue assert p['PULLTYPE'] == site_from_fasm['PULLTYPE'], (tile, site_key, p, site_from_fasm) assert verilog.unquote( p['IOSTANDARD']) in site_from_fasm['IOSTANDARDS'], (tile, site_key, p, site_from_fasm) if p['type'] != 'IBUF': assert p['SLEW'] == site_from_fasm['SLEW'], (tile, site_key, p, site_from_fasm) assert 'I{}'.format( p['DRIVE']) in site_from_fasm['DRIVES'], (tile, site_key, p, site_from_fasm)
def run(): segmk = Segmaker("design.bits") clk_inverts = {} with open('design.csv', 'r') as f: for params in csv.DictReader(f): clk_inverts[params['site']] = params print("Loading tags") f = open('params.jl', 'r') f.readline() for l in f: j = json.loads(l) ps = j['params'] assert j['module'] == 'my_RAMB18E1' site = verilog.unquote(ps['LOC']) bus_tags(segmk, ps, site) if ps['RAM_MODE'] == '"TDP"': rw_width_tags(segmk, ps, site) segmk.add_site_tag( site, 'SDP_READ_WIDTH_36', ps['RAM_MODE'] == '"SDP"' and int(ps['READ_WIDTH_A']) == 36) segmk.add_site_tag( site, 'SDP_WRITE_WIDTH_36', ps['RAM_MODE'] == '"SDP"' and int(ps['WRITE_WIDTH_B']) == 36) if ps['READ_WIDTH_A'] < 36 and ps['WRITE_WIDTH_B'] < 36: isinv_tags(segmk, ps, site, clk_inverts[site]) write_mode_tags(segmk, ps, site) write_rstreg_priority(segmk, ps, site) write_rdaddr_collision(segmk, ps, site) def bitfilter(frame, bit): # rw_width_tags() aliasing interconnect on large widths return frame not in (0, 20, 21) segmk.compile(bitfilter=bitfilter) segmk.write()
def handle_data_width(segmk, d): if 'DATA_WIDTH' not in d: return site = d['ologic_loc'] for opt in [2, 3, 4, 5, 6, 7, 8]: segmk.add_site_tag(site, 'OSERDES.DATA_WIDTH.W{}'.format(opt), d['DATA_WIDTH'] == opt) if verilog.unquote(d['DATA_RATE_OQ']) == 'DDR': # DDR + WIDTH 6/8 have some overlapping bits, create a feature. OVERLAPPING_WIDTHS = [6, 8] segmk.add_site_tag( site, 'OSERDES.DATA_WIDTH.DDR.W{}'.format('_'.join( map(str, OVERLAPPING_WIDTHS))), d['DATA_WIDTH'] in OVERLAPPING_WIDTHS) else: # SDR + WIDTH 2/4/5/6 have some overlapping bits, create a feature. OVERLAPPING_WIDTHS = [2, 4, 5, 6] segmk.add_site_tag( site, 'OSERDES.DATA_WIDTH.SDR.W{}'.format('_'.join( map(str, OVERLAPPING_WIDTHS))), d['DATA_WIDTH'] in OVERLAPPING_WIDTHS)
def main(): print("Loading tags") segmk = Segmaker("design.bits") ''' port,site,tile,pin,slew,drive,pulltype di[0],IOB_X0Y107,LIOB33_X0Y107,A21,PULLDOWN di[10],IOB_X0Y147,LIOB33_X0Y147,F14,PULLUP ''' with open('params.jl', 'r') as f: design = json.load(f) for d in design: site = d['site'] if skip_broken_tiles(d): continue iostandard = verilog.unquote(d['IOSTANDARD']) stepdown = iostandard in STEPDOWN_IOSTANDARDS segmk.add_site_tag(site, '_'.join(STEPDOWN_IOSTANDARDS), stepdown) if d['type'] is None: segmk.add_site_tag(site, 'INOUT', 0) segmk.add_site_tag(site, '{}.IN_USE'.format(iostandard), 0) segmk.add_site_tag(site, '{}.IN'.format(iostandard), 0) segmk.add_site_tag(site, '{}.OUT'.format(iostandard), 0) for drive in drives_for_iostandard(iostandard): segmk.add_site_tag( site, '{}.DRIVE.I{}.IN_OUT_COMMON'.format(iostandard, drive), 0) elif d['type'] == 'IBUF': segmk.add_site_tag(site, 'INOUT', 0) segmk.add_site_tag(site, '{}.IN_USE'.format(iostandard), 1) segmk.add_site_tag(site, '{}.IN'.format(iostandard), 1) segmk.add_site_tag(site, '{}.OUT'.format(iostandard), 0) for drive in drives_for_iostandard(iostandard): segmk.add_site_tag( site, '{}.DRIVE.I{}.IN_OUT_COMMON'.format(iostandard, drive), 1) elif d['type'] == 'OBUF': segmk.add_site_tag(site, 'INOUT', 0) segmk.add_site_tag(site, '{}.IN_USE'.format(iostandard), 1) segmk.add_site_tag(site, '{}.IN'.format(iostandard), 0) segmk.add_site_tag(site, '{}.OUT'.format(iostandard), 1) for drive in drives_for_iostandard(iostandard): if drive == d['DRIVE']: segmk.add_site_tag( site, '{}.DRIVE.I{}.IN_OUT_COMMON'.format( iostandard, drive), 1) else: segmk.add_site_tag( site, '{}.DRIVE.I{}.IN_OUT_COMMON'.format( iostandard, drive), 0) elif d['type'] == 'IOBUF_INTERMDISABLE': segmk.add_site_tag(site, 'INOUT', 1) segmk.add_site_tag(site, '{}.IN_USE'.format(iostandard), 1) segmk.add_site_tag(site, '{}.OUT'.format(iostandard), 1) if d['type'] is not None: segmaker.add_site_group_zero( segmk, site, "PULLTYPE.", ("NONE", "KEEPER", "PULLDOWN", "PULLUP"), "PULLDOWN", verilog.unquote(d['PULLTYPE'])) if d['type'] == 'IBUF' or d['type'] is None: continue drive_opts = set() for opt in ("LVCMOS25", "LVCMOS33", "LVCMOS18", "LVCMOS15", "LVCMOS12", 'LVTTL'): for drive_opt in ("4", "8", "12", "16", "24"): if drive_opt == "16" and opt == "LVCMOS12": continue if drive_opt == "24" and opt not in ["LVCMOS18", 'LVTTL']: continue drive_opts.add(mk_drive_opt(opt, drive_opt)) segmaker.add_site_group_zero(segmk, site, '', drive_opts, mk_drive_opt('LVCMOS25', '12'), mk_drive_opt(iostandard, d['DRIVE'])) segmaker.add_site_group_zero(segmk, site, "SLEW.", ("SLOW", "FAST"), "FAST", verilog.unquote(d['SLEW'])) if 'ibufdisable_wire' in d: segmk.add_site_tag(site, 'IBUFDISABLE.I', d['ibufdisable_wire'] != '0') if 'intermdisable_wire' in d: segmk.add_site_tag(site, 'INTERMDISABLE.I', d['intermdisable_wire'] != '0') segmk.compile(bitfilter=bitfilter) segmk.write(allow_empty=True)
def main(): f = open('params.jl', 'w') f.write('module,loc,params\n') print("""module top(input clk); (* KEEP, DONT_TOUCH *) LUT1 dummy(); """) for site in sorted(gen_sites()): params = { "site": site, 'active': random.random() > .2, "clkin1_conn": random.choice(( "clkfbout_mult_BUFG_" + site, "clk", )), "clkin2_conn": random.choice(( "clkfbout_mult_BUFG_" + site, "clk", )), "dclk_conn": random.choice(( "0", "clk", )), "dwe_conn": random.choice(( "", "1", "0", "dwe_" + site, "den_" + site, )), "den_conn": random.choice(( "", "1", "0", "den_" + site, )), "daddr4_conn": random.choice(( "0", "dwe_" + site, )), "IS_RST_INVERTED": random.randint(0, 1), "IS_PWRDWN_INVERTED": random.randint(0, 1), "IS_CLKINSEL_INVERTED": random.randint(0, 1), "CLKFBOUT_MULT": random.randint(2, 4), "CLKOUT0_DIVIDE": random.randint(1, 128), "CLKOUT1_DIVIDE": random.randint(1, 128), "CLKOUT2_DIVIDE": random.randint(1, 128), "CLKOUT3_DIVIDE": random.randint(1, 128), "CLKOUT4_DIVIDE": random.randint(1, 128), "CLKOUT5_DIVIDE": random.randint(1, 128), "DIVCLK_DIVIDE": random.randint(1, 5), "CLKOUT0_DUTY_CYCLE": "0.500", "STARTUP_WAIT": verilog.quote('TRUE' if random.randint(0, 1) else 'FALSE'), "COMPENSATION": verilog.quote( random.choice(( 'ZHOLD', 'BUF_IN', 'EXTERNAL', 'INTERNAL', ))), "BANDWIDTH": verilog.quote(random.choice(( 'OPTIMIZED', 'HIGH', 'LOW', ))), } if verilog.unquote(params['COMPENSATION']) == 'ZHOLD': params['clkfbin_conn'] = random.choice(( "", "clkfbout_mult_BUFG_" + site, )) elif verilog.unquote(params['COMPENSATION']) == 'INTERNAL': params['clkfbin_conn'] = random.choice(( "", "clkfbout_mult_" + site, )) else: params['clkfbin_conn'] = random.choice( ("", "clk", "clkfbout_mult_BUFG_" + site)) f.write('%s\n' % (json.dumps(params))) if not params['active']: continue print(""" wire den_{site}; wire dwe_{site}; LUT1 den_lut_{site} ( .O(den_{site}) ); LUT1 dwe_lut_{site} ( .O(dwe_{site}) ); wire clkfbout_mult_{site}; wire clkfbout_mult_BUFG_{site}; wire clkout0_{site}; wire clkout1_{site}; wire clkout2_{site}; wire clkout3_{site}; wire clkout4_{site}; wire clkout5_{site}; (* KEEP, DONT_TOUCH, LOC = "{site}" *) PLLE2_ADV #( .IS_RST_INVERTED({IS_RST_INVERTED}), .IS_PWRDWN_INVERTED({IS_PWRDWN_INVERTED}), .IS_CLKINSEL_INVERTED({IS_CLKINSEL_INVERTED}), .CLKOUT0_DIVIDE({CLKOUT0_DIVIDE}), .CLKOUT1_DIVIDE({CLKOUT1_DIVIDE}), .CLKOUT2_DIVIDE({CLKOUT2_DIVIDE}), .CLKOUT3_DIVIDE({CLKOUT3_DIVIDE}), .CLKOUT4_DIVIDE({CLKOUT4_DIVIDE}), .CLKOUT5_DIVIDE({CLKOUT5_DIVIDE}), .CLKFBOUT_MULT({CLKFBOUT_MULT}), .DIVCLK_DIVIDE({DIVCLK_DIVIDE}), .STARTUP_WAIT({STARTUP_WAIT}), .CLKOUT0_DUTY_CYCLE({CLKOUT0_DUTY_CYCLE}), .COMPENSATION({COMPENSATION}), .BANDWIDTH({BANDWIDTH}), .CLKIN1_PERIOD(10.0), .CLKIN2_PERIOD(10.0) ) pll_{site} ( .CLKFBOUT(clkfbout_mult_{site}), .CLKOUT0(clkout0_{site}), .CLKOUT1(clkout1_{site}), .CLKOUT2(clkout2_{site}), .CLKOUT3(clkout3_{site}), .CLKOUT4(clkout4_{site}), .CLKOUT5(clkout5_{site}), .DRDY(), .LOCKED(), .DO(), .CLKFBIN({clkfbin_conn}), .CLKIN1({clkin1_conn}), .CLKIN2({clkin2_conn}), .CLKINSEL(), .DCLK({dclk_conn}), .DEN({den_conn}), .DWE({dwe_conn}), .PWRDWN(), .RST(), .DI(), .DADDR({{7{{ {daddr4_conn} }} }})); (* KEEP, DONT_TOUCH *) BUFG bufg_{site} ( .I(clkfbout_mult_{site}), .O(clkfbout_mult_BUFG_{site}) ); (* KEEP, DONT_TOUCH *) FDRE reg_clkfbout_mult_{site} ( .C(clkfbout_mult_{site}) ); (* KEEP, DONT_TOUCH *) FDRE reg_clkout0_{site} ( .C(clkout0_{site}) ); (* KEEP, DONT_TOUCH *) FDRE reg_clkout1_{site} ( .C(clkout1_{site}) ); (* KEEP, DONT_TOUCH *) FDRE reg_clkout2_{site} ( .C(clkout2_{site}) ); (* KEEP, DONT_TOUCH *) FDRE reg_clkout3_{site} ( .C(clkout3_{site}) ); (* KEEP, DONT_TOUCH *) FDRE reg_clkout4_{site} ( .C(clkout4_{site}) ); (* KEEP, DONT_TOUCH *) FDRE reg_clkout5_{site} ( .C(clkout5_{site}) ); """.format(**params)) print('endmodule') f.close()
def main(): print("Loading tags") segmk = Segmaker("design.bits") with open('params.jl', 'r') as f: design = json.load(f) for d in design: site = d['ilogic_loc'] handle_data_width(segmk, d) handle_data_rate(segmk, d) segmk.add_site_tag(site, 'ISERDES.IN_USE', d['use_iserdese2']) if 'NUM_CE' in d: segmk.add_site_tag(site, 'ISERDES.NUM_CE.N2', d['NUM_CE'] == 2) segmk.add_site_tag( site, 'IDDR_OR_ISERDES.IN_USE', d['use_iserdese2'] or d['iddr_mux_config'] != 'none') if 'INTERFACE_TYPE' in d: for opt in ( 'MEMORY', 'MEMORY_DDR3', 'MEMORY_QDR', 'NETWORKING', 'OVERSAMPLE', ): segmk.add_site_tag( site, 'ISERDES.INTERFACE_TYPE.{}'.format(opt), opt == verilog.unquote(d['INTERFACE_TYPE'])) segmk.add_site_tag( site, 'ISERDES.INTERFACE_TYPE.Z_{}'.format(opt), opt != verilog.unquote(d['INTERFACE_TYPE'])) segmk.add_site_tag( site, 'ISERDES.INTERFACE_TYPE.NOT_MEMORY', 'MEMORY' not in verilog.unquote(d['INTERFACE_TYPE'])) if d['iddr_mux_config'] != 'none': segmk.add_site_tag(site, 'IFF.ZINIT_Q1', not d['INIT_Q1']) segmk.add_site_tag(site, 'IFF.ZINIT_Q2', not d['INIT_Q2']) if 'DYN_CLKDIV_INV_EN' in d: segmk.add_site_tag( site, 'DYN_CLKDIV_INV_EN', verilog.unquote(d['DYN_CLKDIV_INV_EN']) == 'TRUE') if 'DYN_CLK_INV_EN' in d: segmk.add_site_tag( site, 'DYN_CLK_INV_EN', verilog.unquote(d['DYN_CLK_INV_EN']) == 'TRUE') if 'INIT_Q3' in d: segmk.add_site_tag(site, 'IFF.ZINIT_Q3', not d['INIT_Q3']) segmk.add_site_tag(site, 'IFF.ZINIT_Q4', not d['INIT_Q4']) segmk.add_site_tag(site, 'IFF.ZSRVAL_Q1', not d['SRVAL_Q1']) segmk.add_site_tag(site, 'IFF.ZSRVAL_Q2', not d['SRVAL_Q2']) segmk.add_site_tag(site, 'IFF.ZSRVAL_Q3', not d['SRVAL_Q3']) segmk.add_site_tag(site, 'IFF.ZSRVAL_Q4', not d['SRVAL_Q4']) if 'IS_CLK_INVERTED' in d and not d['DISABLE_CLOCKS']: if verilog.unquote(d['INTERFACE_TYPE']) == 'MEMORY_DDR3': segmk.add_site_tag(site, 'IFF.INV_CLK', d['IS_CLK_INVERTED']) segmk.add_site_tag(site, 'IFF.INV_CLKB', d['IS_CLKB_INVERTED']) segmk.add_site_tag(site, 'IFF.ZINV_CLK', not d['IS_CLK_INVERTED']) segmk.add_site_tag(site, 'IFF.ZINV_CLKB', not d['IS_CLKB_INVERTED']) segmk.add_site_tag( site, 'IFF.ZINV_CLK_XOR', d['IS_CLK_INVERTED'] ^ d['IS_CLKB_INVERTED']) segmk.add_site_tag( site, 'IFF.ZINV_CLK_NXOR', not (d['IS_CLK_INVERTED'] ^ d['IS_CLKB_INVERTED'])) segmk.add_site_tag( site, 'IFF.ZINV_CLK_OR', d['IS_CLK_INVERTED'] or d['IS_CLKB_INVERTED']) segmk.add_site_tag( site, 'IFF.ZINV_CLK_NOR', not (d['IS_CLK_INVERTED'] or d['IS_CLKB_INVERTED'])) segmk.add_site_tag( site, 'IFF.ZINV_CLK_AND', d['IS_CLK_INVERTED'] and d['IS_CLKB_INVERTED']) segmk.add_site_tag( site, 'IFF.ZINV_CLK_NAND', not (d['IS_CLK_INVERTED'] and d['IS_CLKB_INVERTED'])) if 'IS_OCLK_INVERTED' in d and not d['DISABLE_CLOCKS']: segmk.add_site_tag(site, 'IFF.INV_OCLK', d['IS_OCLK_INVERTED']) segmk.add_site_tag(site, 'IFF.ZINV_OCLK', not d['IS_OCLK_INVERTED']) segmk.add_site_tag(site, 'IFF.INV_OCLKB', d['IS_OCLKB_INVERTED']) segmk.add_site_tag(site, 'IFF.ZINV_OCLKB', not d['IS_OCLKB_INVERTED']) if 'IS_CLKDIV_INVERTED' in d and not d['DISABLE_CLOCKS'] and \ verilog.unquote(d['INTERFACE_TYPE']) == 'MEMORY': segmk.add_site_tag(site, 'IFF.INV_CLKDIV', d['IS_CLKDIV_INVERTED']) segmk.add_site_tag(site, 'IFF.ZINV_CLKDIV', not d['IS_CLKDIV_INVERTED']) if 'IS_C_INVERTED' in d: segmk.add_site_tag(site, 'IFF.ZINV_C', not d['IS_C_INVERTED']) segmk.add_site_tag(site, 'ZINV_D', not d['IS_D_INVERTED']) if 'SRTYPE' in d: for opt in ['ASYNC', 'SYNC']: segmk.add_site_tag(site, 'IFF.SRTYPE.{}'.format(opt), verilog.unquote(d['SRTYPE']) == opt) if 'DDR_CLK_EDGE' in d: for opt in [ 'OPPOSITE_EDGE', 'SAME_EDGE', 'SAME_EDGE_PIPELINED' ]: segmk.add_site_tag( site, 'IFF.DDR_CLK_EDGE.{}'.format(opt), verilog.unquote(d['DDR_CLK_EDGE']) == opt) if d['iddr_mux_config'] == 'direct': segmk.add_site_tag(site, 'IFFDELMUXE3.P0', 0) segmk.add_site_tag(site, 'IFFDELMUXE3.P1', 1) segmk.add_site_tag(site, 'IFFDELMUXE3.P2', 0) elif d['iddr_mux_config'] == 'idelay': segmk.add_site_tag(site, 'IFFDELMUXE3.P0', 1) segmk.add_site_tag(site, 'IFFDELMUXE3.P1', 0) segmk.add_site_tag(site, 'IFFDELMUXE3.P2', 0) elif d['iddr_mux_config'] == 'none': segmk.add_site_tag(site, 'IFFDELMUXE3.P0', 0) segmk.add_site_tag(site, 'IFFDELMUXE3.P1', 0) segmk.add_site_tag(site, 'IFFDELMUXE3.P2', 0) else: assert False, d['mux_config'] if d['mux_config'] == 'direct': segmk.add_site_tag(site, 'IDELMUXE3.P0', 0) segmk.add_site_tag(site, 'IDELMUXE3.P1', 1) segmk.add_site_tag(site, 'IDELMUXE3.P2', 0) elif d['mux_config'] == 'idelay': segmk.add_site_tag(site, 'IDELMUXE3.P0', 1) segmk.add_site_tag(site, 'IDELMUXE3.P1', 0) segmk.add_site_tag(site, 'IDELMUXE3.P2', 0) elif d['mux_config'] == 'none': segmk.add_site_tag(site, 'IDELMUXE3.P0', 0) segmk.add_site_tag(site, 'IDELMUXE3.P1', 0) segmk.add_site_tag(site, 'IDELMUXE3.P2', 0) else: assert False, d['mux_config'] if DEBUG_FUZZER: for k in d: segmk.add_site_tag( site, 'param_' + k + '_' + str(d[k]).replace(' ', '').replace('\n', ''), 1) segmk.compile(bitfilter=bitfilter) segmk.write(allow_empty=True)
def write_rstreg_priority(segmk, ps, site): for param in ["RSTREG_PRIORITY_A", "RSTREG_PRIORITY_B"]: set_val = verilog.unquote(ps[param]) for opt in ["RSTREG", "REGCE"]: segmk.add_site_tag(site, "{}_{}".format(param, opt), set_val == opt)
def write_rdaddr_collision(segmk, ps, site): for opt in ["DELAYED_WRITE", "PERFORMANCE"]: set_val = verilog.unquote(ps['RDADDR_COLLISION_HWCONFIG']) segmk.add_site_tag(site, "RDADDR_COLLISION_HWCONFIG_{}".format(opt), set_val == opt)
def main(): # Create map of iobank -> sites iobanks = {} site_to_iobank = {} iobank_iostandards = {} with open(os.path.join(os.getenv('FUZDIR'), 'build', 'iobanks.txt')) as f: for l in f: iob_site, iobank = l.strip().split(',') iobank = int(iobank) if iobank not in iobanks: iobanks[iobank] = set() iobanks[iobank].add(iob_site) assert iob_site not in site_to_iobank site_to_iobank[iob_site] = iobank for iobank in iobanks: iobank_iostandards[iobank] = set() # Load a list of PUDC_B pin function tiles. They are configured differently # by the vendor tools so need to be skipped pudc_tiles = set() with open(os.path.join(os.getenv('FUZDIR'), 'build', 'pudc_sites.csv')) as f: for l in csv.DictReader(f): pudc_tiles.add(l["tile"]) print("Loading tags") segmk = Segmaker("design.bits") ''' port,site,tile,pin,slew,drive,pulltype di[0],IOB_X0Y107,LIOB33_X0Y107,A21,PULLDOWN di[10],IOB_X0Y147,LIOB33_X0Y147,F14,PULLUP ''' with open('params.json', 'r') as f: design = json.load(f) diff_pairs = set() for d in design['tiles']: iostandard = verilog.unquote(d['IOSTANDARD']) if iostandard.startswith('DIFF_'): diff_pairs.add(d['pair_site']) for d in design['tiles']: site = d['site'] if d['tile'] in pudc_tiles: continue if site in diff_pairs: continue iostandard = verilog.unquote(d['IOSTANDARD']) if iostandard.startswith('DIFF_'): iostandard = iostandard[5:] iobank_iostandards[site_to_iobank[site]].add(iostandard) segmk.add_site_tag(site, '_'.join(STEPDOWN_IOSTANDARDS) + '.STEPDOWN', iostandard in STEPDOWN_IOSTANDARDS) if 'IN_TERM' in d: segmaker.add_site_group_zero(segmk, site, 'IN_TERM.', [ 'NONE', 'UNTUNED_SPLIT_40', 'UNTUNED_SPLIT_50', 'UNTUNED_SPLIT_60' ], 'NONE', d['IN_TERM']) if d['type'] is None: segmk.add_site_tag(site, 'INOUT', 0) segmk.add_site_tag(site, '{}.IN_USE'.format(iostandard), 0) segmk.add_site_tag(site, '{}.IN'.format(iostandard), 0) segmk.add_site_tag(site, '{}.OUT'.format(iostandard), 0) segmk.add_site_tag(site, '{}.IN_ONLY'.format(iostandard), 0) elif d['type'] == 'IBUF': segmk.add_site_tag(site, 'INOUT', 0) segmk.add_site_tag(site, '{}.IN_USE'.format(iostandard), 1) segmk.add_site_tag(site, '{}.IN'.format(iostandard), 1) segmk.add_site_tag(site, '{}.IN_DIFF'.format(iostandard), 0) segmk.add_site_tag(site, '{}.OUT'.format(iostandard), 0) segmk.add_site_tag(site, '{}.IN_ONLY'.format(iostandard), 1) segmk.add_tile_tag(d['tile'], 'IN_DIFF', 0) if iostandard in IBUF_LOW_PWR_SUPPORTED: segmk.add_site_tag(site, 'IBUF_LOW_PWR', d['IBUF_LOW_PWR']) segmk.add_site_tag(site, 'ZIBUF_LOW_PWR', 1 ^ d['IBUF_LOW_PWR']) elif d['type'] == 'IBUFDS': segmk.add_site_tag(site, 'INOUT', 0) segmk.add_site_tag(site, '{}.IN_USE'.format(iostandard), 1) segmk.add_site_tag(site, '{}.IN'.format(iostandard), 1) segmk.add_site_tag(site, '{}.IN_DIFF'.format(iostandard), 1) segmk.add_site_tag(d['pair_site'], '{}.IN_DIFF'.format(iostandard), 1) segmk.add_site_tag(site, '{}.OUT'.format(iostandard), 0) segmk.add_site_tag(site, '{}.IN_ONLY'.format(iostandard), 1) segmk.add_tile_tag(d['tile'], 'IN_DIFF', 1) elif d['type'] == 'OBUF': segmk.add_site_tag(site, 'INOUT', 0) segmk.add_site_tag(site, '{}.IN_USE'.format(iostandard), 1) segmk.add_site_tag(site, '{}.IN'.format(iostandard), 0) segmk.add_site_tag(site, '{}.OUT'.format(iostandard), 1) segmk.add_tile_tag(d['tile'], 'OUT_DIFF', 0) elif d['type'] == 'OBUFDS': segmk.add_site_tag(site, 'INOUT', 0) segmk.add_site_tag(site, '{}.IN_USE'.format(iostandard), 1) segmk.add_site_tag(site, '{}.IN'.format(iostandard), 0) segmk.add_site_tag(site, '{}.OUT'.format(iostandard), 1) segmk.add_tile_tag(d['tile'], 'OUT_DIFF', 1) segmk.add_tile_tag(d['tile'], 'OUT_TDIFF', 0) elif d['type'] == 'OBUFTDS': segmk.add_site_tag(site, 'INOUT', 0) segmk.add_site_tag(site, '{}.IN_USE'.format(iostandard), 1) segmk.add_site_tag(site, '{}.IN'.format(iostandard), 0) segmk.add_site_tag(site, '{}.OUT'.format(iostandard), 1) segmk.add_tile_tag(d['tile'], 'OUT_DIFF', 1) segmk.add_tile_tag(d['tile'], 'OUT_TDIFF', 1) elif d['type'] == 'IOBUF_INTERMDISABLE': segmk.add_site_tag(site, 'INOUT', 1) segmk.add_site_tag(site, '{}.IN_USE'.format(iostandard), 1) segmk.add_site_tag(site, '{}.IN'.format(iostandard), 1) segmk.add_site_tag(site, '{}.OUT'.format(iostandard), 1) if d['type'] is not None: segmaker.add_site_group_zero( segmk, site, "PULLTYPE.", ("NONE", "KEEPER", "PULLDOWN", "PULLUP"), "PULLDOWN", verilog.unquote(d['PULLTYPE'])) if d['type'] in [None, 'IBUF', 'IBUFDS']: continue drive_opts = set() for opt in ("LVCMOS25", "LVCMOS33", "LVCMOS18", "LVCMOS15", "LVCMOS12", 'LVTTL'): for drive_opt in ("4", "8", "12", "16", "24"): if drive_opt == "16" and opt == "LVCMOS12": continue if drive_opt == "24" and opt not in ["LVCMOS18", 'LVTTL']: continue drive_opts.add(mk_drive_opt(opt, drive_opt)) drive_opts.add(mk_drive_opt("SSTL135", None)) segmaker.add_site_group_zero(segmk, site, '', drive_opts, mk_drive_opt('LVCMOS25', '12'), mk_drive_opt(iostandard, d['DRIVE'])) for opt in ["SLOW", "FAST"]: segmk.add_site_tag(site, iostandard + ".SLEW." + opt, opt == verilog.unquote(d['SLEW'])) if 'ibufdisable_wire' in d: segmk.add_site_tag(site, 'IBUFDISABLE.I', d['ibufdisable_wire'] != '0') if 'intermdisable_wire' in d: segmk.add_site_tag(site, 'INTERMDISABLE.I', d['intermdisable_wire'] != '0') site_to_cmt = {} site_to_tile = {} tile_to_cmt = {} cmt_to_idelay = {} with open(os.path.join(os.getenv('FUZDIR'), 'build', 'cmt_regions.csv')) as f: for l in f: site, tile, cmt = l.strip().split(',') site_to_tile[site] = tile site_to_cmt[site] = cmt tile_to_cmt[tile] = cmt # Given IDELAYCTRL's are only located in HCLK_IOI3 tiles, and # there is only on HCLK_IOI3 tile per CMT, update # CMT -> IDELAYCTRL / tile map. if 'IDELAYCTRL' in site: assert cmt not in cmt_to_idelay cmt_to_idelay[cmt] = site, tile # For each IOBANK with an active VREF set the feature cmt_vref_active = set() with open('iobank_vref.csv') as f: for l in f: iobank, vref = l.strip().split(',') iobank = int(iobank) cmt = None for cmt_site in iobanks[iobank]: if cmt_site in site_to_cmt: cmt = site_to_cmt[cmt_site] break if cmt is None: continue cmt_vref_active.add(cmt) _, hclk_cmt_tile = cmt_to_idelay[cmt] opt = 'VREF.V_{:d}_MV'.format(int(float(vref) * 1000)) segmk.add_tile_tag(hclk_cmt_tile, opt, 1) for iobank in iobank_iostandards: if len(iobank_iostandards[iobank]) == 0: continue for cmt_site in iobanks[iobank]: if cmt_site in site_to_cmt: cmt = site_to_cmt[cmt_site] break if cmt is None: continue _, hclk_cmt_tile = cmt_to_idelay[cmt] assert len(iobank_iostandards[iobank]) == 1, iobank_iostandards[iobank] iostandard = list(iobank_iostandards[iobank])[0] segmk.add_tile_tag(hclk_cmt_tile, 'STEPDOWN', iostandard in STEPDOWN_IOSTANDARDS) # For IOBANK's with no active VREF, clear all VREF options. for cmt, (_, hclk_cmt_tile) in cmt_to_idelay.items(): if cmt in cmt_vref_active: continue for vref in ( .600, .675, .75, .90, ): opt = 'VREF.V_{:d}_MV'.format(int(vref * 1000)) segmk.add_tile_tag(hclk_cmt_tile, opt, 0) segmk.compile(bitfilter=bitfilter) segmk.write(allow_empty=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(): tile_types = [ 'IBUF', 'OBUF', 'IOBUF_INTERMDISABLE', None, None, None, None, None ] i_idx = 0 o_idx = 0 io_idx = 0 iostandards = [ 'LVCMOS12', 'LVCMOS15', 'LVCMOS18', 'LVCMOS25', 'LVCMOS33', 'LVTTL', 'SSTL135', ] diff_map = { "SSTL135": ["DIFF_SSTL135"], } IN_TERM_ALLOWED = [ 'SSTL15', 'SSTL15_R', 'SSTL18', 'SSTL18_R', 'SSTL135', 'SSTL135_R', 'HSTL_I' 'HSTL_I_18' 'HSTL_II', 'HSTL_II_18', ] iostandard = random.choice(iostandards) if iostandard in ['LVTTL', 'LVCMOS18']: drives = [4, 8, 12, 16, 24] elif iostandard in ['LVCMOS12']: drives = [4, 8, 12] elif iostandard == 'SSTL135': drives = None else: drives = [4, 8, 12, 16] slews = ['FAST', 'SLOW'] pulls = ["NONE", "KEEPER", "PULLDOWN", "PULLUP"] luts = lut_maker.LutMaker() connects = io.StringIO() tile_params = [] params = { "tiles": [], 'INTERNAL_VREF': {}, } with open(os.path.join(os.getenv('FUZDIR'), 'build', 'iobanks.txt')) as f: iobanks = [int(l.strip().split(',')[1]) for l in f] params['iobanks'] = iobanks if iostandard in ['SSTL135']: for iobank in iobanks: params['INTERNAL_VREF'][iobank] = random.choice(( .600, .675, .75, .90, )) any_idelay = False for tile, sites in gen_sites(): site_bels = {} for site_type in sites: if site_type.endswith('M'): if iostandard in diff_map: site_bels[site_type] = random.choice( tile_types + ['IBUFDS', 'OBUFDS', 'OBUFTDS']) else: site_bels[site_type] = random.choice(tile_types) is_m_diff = site_bels[site_type] is not None and site_bels[ site_type].endswith('DS') else: site_bels[site_type] = random.choice(tile_types) if is_m_diff: site_bels['IOB33S'] = None for site_type, site in sites.items(): p = {} p['tile'] = tile p['site'] = site p['type'] = site_bels[site_type] if p['type'] is not None and p['type'].endswith('DS'): iostandard_site = random.choice(diff_map[iostandard]) p['pair_site'] = sites['IOB33S'] else: iostandard_site = iostandard p['IOSTANDARD'] = verilog.quote(iostandard_site) p['PULLTYPE'] = verilog.quote(random.choice(pulls)) if p['type'] is None: p['pad_wire'] = None elif p['type'] == 'IBUF': p['pad_wire'] = 'di[{}]'.format(i_idx) p['IDELAY_ONLY'] = random.randint(0, 1) if not p['IDELAY_ONLY']: p['owire'] = luts.get_next_input_net() else: any_idelay = True p['owire'] = 'idelay_{site}'.format(**p) p['DRIVE'] = None p['SLEW'] = None p['IBUF_LOW_PWR'] = random.randint(0, 1) if iostandard in IN_TERM_ALLOWED: p['IN_TERM'] = random.choice(( 'NONE', 'UNTUNED_SPLIT_40', 'UNTUNED_SPLIT_50', 'UNTUNED_SPLIT_60', )) i_idx += 1 elif p['type'] == 'IBUFDS': p['pad_wire'] = 'di[{}]'.format(i_idx) i_idx += 1 p['bpad_wire'] = 'di[{}]'.format(i_idx) i_idx += 1 p['IDELAY_ONLY'] = random.randint(0, 1) p['DIFF_TERM'] = random.randint(0, 1) if not p['IDELAY_ONLY']: p['owire'] = luts.get_next_input_net() else: any_idelay = True p['owire'] = 'idelay_{site}'.format(**p) p['DRIVE'] = None p['SLEW'] = None p['IBUF_LOW_PWR'] = random.randint(0, 1) elif p['type'] == 'OBUF': p['pad_wire'] = 'do[{}]'.format(o_idx) p['iwire'] = luts.get_next_output_net() if drives is not None: p['DRIVE'] = random.choice(drives) else: p['DRIVE'] = None p['SLEW'] = verilog.quote(random.choice(slews)) o_idx += 1 elif p['type'] == 'OBUFDS': p['pad_wire'] = 'do[{}]'.format(o_idx) o_idx += 1 p['bpad_wire'] = 'do[{}]'.format(o_idx) o_idx += 1 p['iwire'] = luts.get_next_output_net() if drives is not None: p['DRIVE'] = random.choice(drives) else: p['DRIVE'] = None p['SLEW'] = verilog.quote(random.choice(slews)) elif p['type'] == 'OBUFTDS': p['pad_wire'] = 'do[{}]'.format(o_idx) o_idx += 1 p['bpad_wire'] = 'do[{}]'.format(o_idx) o_idx += 1 p['tristate_wire'] = random.choice( ('0', luts.get_next_output_net())) p['iwire'] = luts.get_next_output_net() if drives is not None: p['DRIVE'] = random.choice(drives) else: p['DRIVE'] = None p['SLEW'] = verilog.quote(random.choice(slews)) elif p['type'] == 'IOBUF_INTERMDISABLE': p['pad_wire'] = 'dio[{}]'.format(io_idx) p['iwire'] = luts.get_next_output_net() p['owire'] = luts.get_next_input_net() if drives is not None: p['DRIVE'] = random.choice(drives) else: p['DRIVE'] = None p['SLEW'] = verilog.quote(random.choice(slews)) p['tristate_wire'] = random.choice( ('0', luts.get_next_output_net())) p['ibufdisable_wire'] = random.choice( ('0', luts.get_next_output_net())) p['intermdisable_wire'] = random.choice( ('0', luts.get_next_output_net())) io_idx += 1 if 'DRIVE' in p: if p['DRIVE'] is not None: p['DRIVE_STR'] = '.DRIVE({}),'.format(p['DRIVE']) else: p['DRIVE_STR'] = '' if p['type'] is not None: tile_params.append(( tile, site, p['pad_wire'], iostandard_site, p['DRIVE'], verilog.unquote(p['SLEW']) if p['SLEW'] else None, verilog.unquote(p['PULLTYPE']), p['IN_TERM'] if 'IN_TERM' in p else None, )) params['tiles'].append(p) write_params(tile_params) with open('iobank_vref.csv', 'w') as f: for iobank, vref in params['INTERNAL_VREF'].items(): f.write('{},{}\n'.format(iobank, vref)) print(''' `define N_DI {n_di} `define N_DO {n_do} `define N_DIO {n_dio} module top(input wire [`N_DI-1:0] di, output wire [`N_DO-1:0] do, inout wire [`N_DIO-1:0] dio); '''.format(n_di=i_idx, n_do=o_idx, n_dio=io_idx)) if any_idelay: print(''' (* KEEP, DONT_TOUCH *) IDELAYCTRL();''') # Always output a LUT6 to make placer happy. print(''' (* KEEP, DONT_TOUCH *) LUT6 dummy_lut();''') for p in params['tiles']: if p['type'] is None: continue elif p['type'] == 'IBUF': print(''' wire idelay_{site}; (* KEEP, DONT_TOUCH *) IBUF #( .IBUF_LOW_PWR({IBUF_LOW_PWR}), .IOSTANDARD({IOSTANDARD}) ) ibuf_{site} ( .I({pad_wire}), .O({owire}) );'''.format(**p), file=connects) if p['IDELAY_ONLY']: print(""" (* KEEP, DONT_TOUCH *) IDELAYE2 idelay_site_{site} ( .IDATAIN(idelay_{site}) );""".format(**p), file=connects) elif p['type'] == 'IBUFDS': print(''' wire idelay_{site}; (* KEEP, DONT_TOUCH *) IBUFDS #( .IBUF_LOW_PWR({IBUF_LOW_PWR}), .DIFF_TERM({DIFF_TERM}), .IOSTANDARD({IOSTANDARD}) ) ibuf_{site} ( .I({pad_wire}), .IB({bpad_wire}), .O({owire}) );'''.format(**p), file=connects) if p['IDELAY_ONLY']: print(""" (* KEEP, DONT_TOUCH *) IDELAYE2 idelay_site_{site} ( .IDATAIN(idelay_{site}) );""".format(**p), file=connects) elif p['type'] == 'OBUF': print(''' (* KEEP, DONT_TOUCH *) OBUF #( .IOSTANDARD({IOSTANDARD}), {DRIVE_STR} .SLEW({SLEW}) ) obuf_{site} ( .O({pad_wire}), .I({iwire}) );'''.format(**p), file=connects) elif p['type'] == 'OBUFDS': print(''' (* KEEP, DONT_TOUCH *) OBUFDS #( .IOSTANDARD({IOSTANDARD}), {DRIVE_STR} .SLEW({SLEW}) ) obufds_{site} ( .O({pad_wire}), .OB({bpad_wire}), .I({iwire}) );'''.format(**p), file=connects) elif p['type'] == 'OBUFTDS': print(''' (* KEEP, DONT_TOUCH *) OBUFTDS #( .IOSTANDARD({IOSTANDARD}), {DRIVE_STR} .SLEW({SLEW}) ) obufds_{site} ( .O({pad_wire}), .OB({bpad_wire}), .T({tristate_wire}), .I({iwire}) );'''.format(**p), file=connects) elif p['type'] == 'IOBUF_INTERMDISABLE': print(''' (* KEEP, DONT_TOUCH *) IOBUF_INTERMDISABLE #( .IOSTANDARD({IOSTANDARD}), {DRIVE_STR} .SLEW({SLEW}) ) ibuf_{site} ( .IO({pad_wire}), .I({iwire}), .O({owire}), .T({tristate_wire}), .IBUFDISABLE({ibufdisable_wire}), .INTERMDISABLE({intermdisable_wire}) );'''.format(**p), file=connects) for l in luts.create_wires_and_luts(): print(l) print(connects.getvalue()) print("endmodule") with open('params.json', 'w') as f: json.dump(params, f, indent=2)
def main(): print("Loading tags") segmk = Segmaker("design.bits") with open('params.jl', 'r') as f: design = json.load(f) for d in design: site = d['site'] handle_data_width(segmk, d) handle_data_rate(segmk, d) if 'INTERFACE_TYPE' in d: for opt in ( 'MEMORY', 'MEMORY_DDR3', 'MEMORY_QDR', 'NETWORKING', 'OVERSAMPLE', ): segmk.add_site_tag( site, 'ISERDES.INTERFACE_TYPE.{}'.format(opt), opt == verilog.unquote(d['INTERFACE_TYPE'])) if d['iddr_mux_config'] != 'none': segmk.add_site_tag(site, 'IFF.ZINIT_Q1', not d['INIT_Q1']) segmk.add_site_tag(site, 'IFF.ZINIT_Q2', not d['INIT_Q2']) if 'INIT_Q3' in d: segmk.add_site_tag(site, 'IFF.ZINIT_Q3', not d['INIT_Q3']) segmk.add_site_tag(site, 'IFF.ZINIT_Q4', not d['INIT_Q4']) segmk.add_site_tag(site, 'IFF.ZSRVAL_Q1', not d['SRVAL_Q1']) segmk.add_site_tag(site, 'IFF.ZSRVAL_Q2', not d['SRVAL_Q2']) segmk.add_site_tag(site, 'IFF.ZSRVAL_Q3', not d['SRVAL_Q3']) segmk.add_site_tag(site, 'IFF.ZSRVAL_Q4', not d['SRVAL_Q4']) if 'IS_CLK_INVERTED' in d: if verilog.unquote(d['INTERFACE_TYPE']) == 'MEMORY_DDR3': segmk.add_site_tag(site, 'IFF.ZINV_CLK', not d['IS_CLK_INVERTED']) segmk.add_site_tag(site, 'IFF.ZINV_CLKB', not d['IS_CLKB_INVERTED']) segmk.add_site_tag( site, 'IFF.ZINV_CLK_XOR', d['IS_CLK_INVERTED'] ^ d['IS_CLKB_INVERTED']) segmk.add_site_tag( site, 'IFF.ZINV_CLK_NXOR', not (d['IS_CLK_INVERTED'] ^ d['IS_CLKB_INVERTED'])) segmk.add_site_tag( site, 'IFF.ZINV_CLK_OR', d['IS_CLK_INVERTED'] or d['IS_CLKB_INVERTED']) segmk.add_site_tag( site, 'IFF.ZINV_CLK_NOR', not (d['IS_CLK_INVERTED'] or d['IS_CLKB_INVERTED'])) segmk.add_site_tag( site, 'IFF.ZINV_CLK_AND', d['IS_CLK_INVERTED'] and d['IS_CLKB_INVERTED']) segmk.add_site_tag( site, 'IFF.ZINV_CLK_NAND', not (d['IS_CLK_INVERTED'] and d['IS_CLKB_INVERTED'])) if 'IS_OCLK_INVERTED' in d: segmk.add_site_tag(site, 'IFF.ZINV_OCLK', not d['IS_OCLK_INVERTED']) if 'IS_C_INVERTED' in d: segmk.add_site_tag(site, 'IFF.ZINV_C', not d['IS_C_INVERTED']) segmk.add_site_tag(site, 'ZINV_D', not d['IS_D_INVERTED']) if 'SRTYPE' in d: for opt in ['ASYNC', 'SYNC']: segmk.add_site_tag(site, 'IFF.SRTYPE.{}'.format(opt), verilog.unquote(d['SRTYPE']) == opt) if 'DDR_CLK_EDGE' in d: for opt in [ 'OPPOSITE_EDGE', 'SAME_EDGE', 'SAME_EDGE_PIPELINED' ]: segmk.add_site_tag( site, 'IFF.DDR_CLK_EDGE.{}'.format(opt), verilog.unquote(d['DDR_CLK_EDGE']) == opt) ofb_used = False if 'OFB_USED' in d and d['OFB_USED']: ofb_used = True if d['iddr_mux_config'] == 'direct': segmk.add_site_tag(site, 'IFFDELMUXE3.0', 0) segmk.add_site_tag(site, 'IFFDELMUXE3.1', 1) segmk.add_site_tag(site, 'IFFDELMUXE3.2', 0) if ofb_used: segmk.add_site_tag(site, 'IFFMUX.1', 1) segmk.add_site_tag(site, 'IFFMUX.0', 0) else: segmk.add_site_tag(site, 'IFFMUX.1', 0) segmk.add_site_tag(site, 'IFFMUX.0', 1) elif d['iddr_mux_config'] == 'idelay': segmk.add_site_tag(site, 'IFFDELMUXE3.0', 1) segmk.add_site_tag(site, 'IFFDELMUXE3.1', 0) segmk.add_site_tag(site, 'IFFDELMUXE3.2', 0) if ofb_used: segmk.add_site_tag(site, 'IFFMUX.1', 1) segmk.add_site_tag(site, 'IFFMUX.0', 0) else: segmk.add_site_tag(site, 'IFFMUX.1', 0) segmk.add_site_tag(site, 'IFFMUX.0', 1) elif d['iddr_mux_config'] == 'none': segmk.add_site_tag(site, 'IFFDELMUXE3.0', 0) segmk.add_site_tag(site, 'IFFDELMUXE3.1', 0) segmk.add_site_tag(site, 'IFFDELMUXE3.2', 0) else: assert False, d['mux_config'] if d['mux_config'] == 'direct': segmk.add_site_tag(site, 'IDELMUXE3.0', 0) segmk.add_site_tag(site, 'IDELMUXE3.1', 1) segmk.add_site_tag(site, 'IDELMUXE3.2', 0) if ofb_used: segmk.add_site_tag(site, 'IMUX.1', 1) segmk.add_site_tag(site, 'IMUX.0', 0) else: segmk.add_site_tag(site, 'IMUX.1', 0) segmk.add_site_tag(site, 'IMUX.0', 1) elif d['mux_config'] == 'idelay': segmk.add_site_tag(site, 'IDELMUXE3.0', 1) segmk.add_site_tag(site, 'IDELMUXE3.1', 0) segmk.add_site_tag(site, 'IDELMUXE3.2', 0) if ofb_used: segmk.add_site_tag(site, 'IMUX.1', 1) segmk.add_site_tag(site, 'IMUX.0', 0) else: segmk.add_site_tag(site, 'IMUX.1', 0) segmk.add_site_tag(site, 'IMUX.0', 1) elif d['mux_config'] == 'none': segmk.add_site_tag(site, 'IDELMUXE3.0', 0) segmk.add_site_tag(site, 'IDELMUXE3.1', 0) segmk.add_site_tag(site, 'IDELMUXE3.2', 0) else: assert False, d['mux_config'] segmk.compile() segmk.write(allow_empty=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) match = verilog.unquote(ps['COMPENSATION']) in ['BUF_IN', 'EXTERNAL'] bufg_on_clkin = \ 'BUFG' in ps['clkin1_conn'] or \ 'BUFG' in ps['clkin2_conn'] 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_X0Y2" ) segmk.add_site_tag( site, 'COMP.ZHOLD_NO_CLKIN_BUF_TOP', match and \ not bufg_on_clkin and \ site == "PLLE2_ADV_X0Y2" ) for opt in ['ZHOLD', 'BUF_IN', 'EXTERNAL', 'INTERNAL']: 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) 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 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), ('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) 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']) 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") # Load tags with open("params.json", "r") as fp: data = json.load(fp) loc_to_tile_site_map = {} # Output tags for param_list in data: for params in param_list: loc = verilog.unquote(params["SITE_LOC"]) get_xy = util.create_xy_fun('IOB_') x, y = get_xy(loc.replace("ILOGIC", "IOB")) loc_to_tile_site_map[loc] = params["TILE_NAME"] + ".IOB_Y%d" % ( y % 2) # Site not used at all if not params["IS_USED"]: segmk.add_site_tag(loc, "ISERDES.SHIFTOUT_USED", 0) segmk.add_site_tag(loc, "IDDR_OR_ISERDES.IN_USE", 0) segmk.add_site_tag(loc, "ISERDES.IN_USE", 0) segmk.add_site_tag(loc, "IDDR.IN_USE", 0) segmk.add_site_tag(loc, "ISERDES.MODE.MASTER", 0) segmk.add_site_tag(loc, "ISERDES.MODE.SLAVE", 0) for i in iface_types: if i == "NETWORKING": for j in data_rates: for k in data_widths[j]: tag = "ISERDES.%s.%s.W%s" % (i, j, k) segmk.add_site_tag(loc, tag, 0) else: segmk.add_site_tag(loc, "ISERDES.%s.DDR.W4" % i, 0) segmk.add_site_tag(loc, "ISERDES.NUM_CE.N1", 0) segmk.add_site_tag(loc, "ISERDES.NUM_CE.N2", 0) for i in range(1, 4 + 1): segmk.add_site_tag(loc, "IFF.ZINIT_Q%d" % i, 0) for i in range(1, 4 + 1): segmk.add_site_tag(loc, "IFF.ZSRVAL_Q%d" % i, 0) # segmk.add_site_tag(loc, "ISERDES.IS_CLKB_INVERTED", 0) # segmk.add_site_tag(loc, "ISERDES.IS_CLK_INVERTED", 1) segmk.add_site_tag(loc, "ISERDES.DYN_CLKDIV_INV_EN", 0) segmk.add_site_tag(loc, "ISERDES.DYN_CLK_INV_EN", 0) segmk.add_site_tag(loc, "IFFDELMUXE3.P0", 0) segmk.add_site_tag(loc, "IFFDELMUXE3.P1", 1) segmk.add_site_tag(loc, "IDELMUXE3.P0", 0) segmk.add_site_tag(loc, "IDELMUXE3.P1", 1) segmk.add_site_tag(loc, "ISERDES.OFB_USED", 0) # Site used as ISERDESE2 elif verilog.unquote(params["BEL_TYPE"]) == "ISERDESE2": segmk.add_site_tag(loc, "IDDR_OR_ISERDES.IN_USE", 1) segmk.add_site_tag(loc, "ISERDES.IN_USE", 1) if "SHIFTOUT_USED" in params: if params["CHAINED"]: value = params["SHIFTOUT_USED"] segmk.add_site_tag(loc, "ISERDES.SHIFTOUT_USED", value) if "SERDES_MODE" in params: value = verilog.unquote(params["SERDES_MODE"]) if value == "MASTER": segmk.add_site_tag(loc, "ISERDES.MODE.MASTER", 1) segmk.add_site_tag(loc, "ISERDES.MODE.SLAVE", 0) if value == "SLAVE": segmk.add_site_tag(loc, "ISERDES.MODE.MASTER", 0) segmk.add_site_tag(loc, "ISERDES.MODE.SLAVE", 1) iface_type = verilog.unquote(params["INTERFACE_TYPE"]) data_rate = verilog.unquote(params["DATA_RATE"]) data_width = int(params["DATA_WIDTH"]) for i in iface_types: if i == "NETWORKING": for j in data_rates: for k in data_widths[j]: tag = "ISERDES.%s.%s.W%s" % (i, j, k) if i == iface_type: if j == data_rate: if k == data_width: segmk.add_site_tag(loc, tag, 1) else: if i == iface_type: segmk.add_site_tag(loc, "ISERDES.%s.DDR.W4" % i, 1) if "NUM_CE" in params: value = params["NUM_CE"] if value == 1: segmk.add_site_tag(loc, "ISERDES.NUM_CE.N1", 1) segmk.add_site_tag(loc, "ISERDES.NUM_CE.N2", 0) if value == 2: segmk.add_site_tag(loc, "ISERDES.NUM_CE.N1", 0) segmk.add_site_tag(loc, "ISERDES.NUM_CE.N2", 1) for i in range(1, 4 + 1): if ("INIT_Q%d" % i) in params: segmk.add_site_tag( loc, "IFF.ZINIT_Q%d" % i, not params["INIT_Q%d" % i]) for i in range(1, 4 + 1): if ("SRVAL_Q%d" % i) in params: segmk.add_site_tag( loc, "IFF.ZSRVAL_Q%d" % i, not params["SRVAL_Q%d" % i]) for inv in ["CLK", "CLKB", "OCLK", "OCLKB", "CLKDIV", "CLKDIVP"]: if "IS_{}_INVERTED".format(inv) in params: segmk.add_site_tag( loc, "ISERDES.INV_{}".format(inv), params["IS_{}_INVERTED".format(inv)]) segmk.add_site_tag( loc, "ISERDES.ZINV_{}".format(inv), not params["IS_{}_INVERTED".format(inv)]) if "DYN_CLKDIV_INV_EN" in params: value = verilog.unquote(params["DYN_CLKDIV_INV_EN"]) segmk.add_site_tag( loc, "ISERDES.DYN_CLKDIV_INV_EN", int(value == "TRUE")) if "DYN_CLK_INV_EN" in params: value = verilog.unquote(params["DYN_CLK_INV_EN"]) segmk.add_site_tag( loc, "ISERDES.DYN_CLK_INV_EN", int(value == "TRUE")) # This parameter actually controls muxes used both in ILOGIC and # ISERDES mode. if "IOBDELAY" in params: value = verilog.unquote(params["IOBDELAY"]) if value == "NONE": segmk.add_site_tag(loc, "IFFDELMUXE3.P0", 0) segmk.add_site_tag(loc, "IFFDELMUXE3.P1", 1) segmk.add_site_tag(loc, "IDELMUXE3.P0", 0) segmk.add_site_tag(loc, "IDELMUXE3.P1", 1) if value == "IBUF": segmk.add_site_tag(loc, "IFFDELMUXE3.P0", 0) segmk.add_site_tag(loc, "IFFDELMUXE3.P1", 1) segmk.add_site_tag(loc, "IDELMUXE3.P0", 1) segmk.add_site_tag(loc, "IDELMUXE3.P1", 0) if value == "IFD": segmk.add_site_tag(loc, "IFFDELMUXE3.P0", 1) segmk.add_site_tag(loc, "IFFDELMUXE3.P1", 0) segmk.add_site_tag(loc, "IDELMUXE3.P0", 0) segmk.add_site_tag(loc, "IDELMUXE3.P1", 1) if value == "BOTH": segmk.add_site_tag(loc, "IFFDELMUXE3.P0", 1) segmk.add_site_tag(loc, "IFFDELMUXE3.P1", 0) segmk.add_site_tag(loc, "IDELMUXE3.P0", 1) segmk.add_site_tag(loc, "IDELMUXE3.P1", 0) if "OFB_USED" in params: value = verilog.unquote(params["OFB_USED"]) segmk.add_site_tag( loc, "ISERDES.OFB_USED", int(value == "TRUE")) # Site used as IDDR elif verilog.unquote(params["BEL_TYPE"]) in ["IDDR", "IDDR_NO_CLK"]: segmk.add_site_tag(loc, "IDDR_OR_ISERDES.IN_USE", 1) segmk.add_site_tag(loc, "IDDR.IN_USE", 1) segmk.add_site_tag(loc, "ISERDES.IN_USE", 0) if "DDR_CLK_EDGE" in params: value = verilog.unquote(params["DDR_CLK_EDGE"]) segmk.add_site_tag( loc, "IFF.DDR_CLK_EDGE.OPPOSITE_EDGE", int(value == "OPPOSITE_EDGE")) segmk.add_site_tag( loc, "IFF.DDR_CLK_EDGE.SAME_EDGE", int(value == "SAME_EDGE")) segmk.add_site_tag( loc, "IFF.DDR_CLK_EDGE.SAME_EDGE_PIPELINED", int(value == "SAME_EDGE_PIPELINED")) if "SRTYPE" in params: value = verilog.unquote(params["SRTYPE"]) if value == "ASYNC": segmk.add_site_tag(loc, "IFF.SRTYPE.ASYNC", 1) segmk.add_site_tag(loc, "IFF.SRTYPE.SYNC", 0) if value == "SYNC": segmk.add_site_tag(loc, "IFF.SRTYPE.ASYNC", 0) segmk.add_site_tag(loc, "IFF.SRTYPE.SYNC", 1) if "IDELMUX" in params: if params["IDELMUX"] == 1: segmk.add_site_tag(loc, "IDELMUXE3.P0", 1) segmk.add_site_tag(loc, "IDELMUXE3.P1", 0) else: segmk.add_site_tag(loc, "IDELMUXE3.P0", 0) segmk.add_site_tag(loc, "IDELMUXE3.P1", 1) if "IFFDELMUX" in params: if params["IFFDELMUX"] == 1: segmk.add_site_tag(loc, "IFFDELMUXE3.P0", 1) segmk.add_site_tag(loc, "IFFDELMUXE3.P1", 0) else: segmk.add_site_tag(loc, "IFFDELMUXE3.P0", 0) segmk.add_site_tag(loc, "IFFDELMUXE3.P1", 1) for inv in ["C", "D"]: if "IS_{}_INVERTED".format(inv) in params: segmk.add_site_tag( loc, "INV_{}".format(inv), params["IS_{}_INVERTED".format(inv)]) segmk.add_site_tag( loc, "ZINV_{}".format(inv), not params["IS_{}_INVERTED".format(inv)]) segmk.add_site_tag(loc, "ISERDES.NUM_CE.N1", 1) segmk.add_site_tag(loc, "ISERDES.NUM_CE.N2", 0) # Should not happen else: print("Unknown BEL_TYPE '{}'".format(params["BEL_TYPE"])) exit(-1) # Write segments and tags for later check def_tags = {t: 0 for d in segmk.site_tags.values() for t in d.keys()} with open("tags.json", "w") as fp: tags = {} for l, d in segmk.site_tags.items(): d1 = dict(def_tags) d1.update({k: int(v) for k, v in d.items()}) tags[loc_to_tile_site_map[l]] = d1 json.dump(tags, fp, sort_keys=True, indent=1) def bitfilter(frame_idx, bit_idx): if frame_idx < 26 or frame_idx > 29: return False return True segmk.compile(bitfilter=bitfilter) segmk.write()
def run(): iostandards = [ 'LVCMOS12', 'LVCMOS15', 'LVCMOS18', 'LVCMOS25', 'LVCMOS33', 'LVTTL' ] iostandard = random.choice(iostandards) if iostandard in ['LVTTL', 'LVCMOS18']: drives = [4, 8, 12, 16, 24] elif iostandard == 'LVCMOS12': drives = [4, 8, 12] else: drives = [4, 8, 12, 16] slews = ['FAST', 'SLOW'] pulls = ["NONE", "KEEPER", "PULLDOWN", "PULLUP"] luts = lut_maker.LutMaker() connects = io.StringIO() tile_params = [] params = [] for idx, (tile, site) in enumerate(gen_sites()): if idx == 0: continue p = {} p['tile'] = tile p['site'] = site p['ilogic_loc'] = site.replace('IOB', 'ILOGIC') p['ologic_loc'] = site.replace('IOB', 'OLOGIC') p['idelay_loc'] = site.replace('IOB', 'IDELAY') p['IOSTANDARD'] = verilog.quote(iostandard) p['PULLTYPE'] = verilog.quote(random.choice(pulls)) p['DRIVE'] = random.choice(drives) p['SLEW'] = verilog.quote(random.choice(slews)) p['pad_wire'] = 'dio[{}]'.format(idx - 1) p['owire'] = 'do_buf[{}]'.format(idx - 1) p['iwire'] = 'di_buf[{}]'.format(idx - 1) p['twire'] = 't[{}]'.format(idx - 1) params.append(p) tile_params.append((tile, site, p['pad_wire'], iostandard, p['DRIVE'], verilog.unquote(p['SLEW']) if p['SLEW'] else None, verilog.unquote(p['PULLTYPE']))) write_params(tile_params) print(''' `define N_DI {n_di} module top(input clk, inout wire [`N_DI-1:0] dio); wire [`N_DI-1:0] di_buf; wire [`N_DI-1:0] do_buf; wire [`N_DI-1:0] t; '''.format(n_di=idx)) # Always output a LUT6 to make placer happy. print(''' (* KEEP, DONT_TOUCH *) LUT6 dummy_lut(); ''') any_idelay = False for p in params: print(''' wire iddr_d_{site}; (* KEEP, DONT_TOUCH, LOC = "{site}" *) IOBUF #( .IOSTANDARD({IOSTANDARD}) ) ibuf_{site} ( .IO({pad_wire}), .I({owire}), .O({iwire}), .T({twire}) ); '''.format(**p), file=connects) p['use_iserdese2'] = random.randint(0, 1) if p['use_iserdese2']: use_iserdese2(p, luts, connects) else: use_direct_and_iddr(p, luts, connects) if p['iddr_mux_config'] == 'idelay' or p['mux_config'] == 'idelay': any_idelay = True if any_idelay: print(""" (* KEEP, DONT_TOUCH *) IDELAYCTRL();""") for l in luts.create_wires_and_luts(): print(l) print(connects.getvalue()) print("endmodule") with open('params.jl', 'w') as f: json.dump(params, f, indent=2)
def main(): print(''' module top(); ''') params_list = [] for tile_name, sites in gen_sites(): params = {} params['tile'] = tile_name params['site'] = sites['RAMBFIFO36E1'] params['DATA_WIDTH'] = random.choice([4, 9, 18, 36, 72]) params['EN_SYN'] = random.randint(0, 1) params['DO_REG'] = 1 if params['EN_SYN']: params['FIRST_WORD_FALL_THROUGH'] = 0 else: params['FIRST_WORD_FALL_THROUGH'] = random.randint(0, 1) if params['EN_SYN']: MIN_ALMOST_FULL_OFFSET = 1 if params['DATA_WIDTH'] == 4: MAX_ALMOST_FULL_OFFSET = 8190 elif params['DATA_WIDTH'] == 9: MAX_ALMOST_FULL_OFFSET = 4094 elif params['DATA_WIDTH'] == 18: MAX_ALMOST_FULL_OFFSET = 2046 elif params['DATA_WIDTH'] == 36: MAX_ALMOST_FULL_OFFSET = 1022 elif params['DATA_WIDTH'] == 72: MAX_ALMOST_FULL_OFFSET = 510 else: assert False MIN_ALMOST_EMPTY_OFFSET = MIN_ALMOST_FULL_OFFSET MAX_ALMOST_EMPTY_OFFSET = MAX_ALMOST_FULL_OFFSET else: MIN_ALMOST_FULL_OFFSET = 4 if params['DATA_WIDTH'] == 4: MAX_ALMOST_FULL_OFFSET = 8185 elif params['DATA_WIDTH'] == 9: MAX_ALMOST_FULL_OFFSET = 4089 elif params['DATA_WIDTH'] == 18: MAX_ALMOST_FULL_OFFSET = 2041 elif params['DATA_WIDTH'] == 36: MAX_ALMOST_FULL_OFFSET = 1017 elif params['DATA_WIDTH'] == 72: MAX_ALMOST_FULL_OFFSET = 505 else: assert False if params['FIRST_WORD_FALL_THROUGH']: MIN_ALMOST_EMPTY_OFFSET = MIN_ALMOST_FULL_OFFSET + 2 MAX_ALMOST_EMPTY_OFFSET = MAX_ALMOST_FULL_OFFSET + 2 else: MIN_ALMOST_EMPTY_OFFSET = MIN_ALMOST_FULL_OFFSET + 1 MAX_ALMOST_EMPTY_OFFSET = MAX_ALMOST_FULL_OFFSET + 1 ALMOST_EMPTY_OFFSET = rand_int( MIN_ALMOST_EMPTY_OFFSET, MAX_ALMOST_EMPTY_OFFSET) ALMOST_FULL_OFFSET = rand_int( MIN_ALMOST_FULL_OFFSET, MAX_ALMOST_FULL_OFFSET) params['ALMOST_EMPTY_OFFSET'] = "13'b{:013b}".format( ALMOST_EMPTY_OFFSET) params['ALMOST_FULL_OFFSET'] = "13'b{:013b}".format(ALMOST_FULL_OFFSET) if params['DATA_WIDTH'] == 36: params['FIFO_MODE'] = verilog.quote('FIFO36_72') else: params['FIFO_MODE'] = verilog.quote( 'FIFO36_72' ) #verilog.quote('FIFO18') #verilog.quote(random.choice(('FIFO18', 'FIFO18_36'))) params['INIT'] = '0' #vrandbits(36) params['SRVAL'] = '0' #vrandbits(36) print( ''' (* KEEP, DONT_TOUCH, LOC = "{site}" *) FIFO36E1 #( .ALMOST_EMPTY_OFFSET({ALMOST_EMPTY_OFFSET}), .ALMOST_FULL_OFFSET({ALMOST_FULL_OFFSET}), .DATA_WIDTH({DATA_WIDTH}), .DO_REG({DO_REG}), .EN_SYN({EN_SYN}), .FIFO_MODE({FIFO_MODE}), .FIRST_WORD_FALL_THROUGH({FIRST_WORD_FALL_THROUGH}), .INIT({INIT}), .SRVAL({SRVAL}) ) fifo_{site} ( ); '''.format(**params, )) params['FIFO_MODE'] = verilog.unquote(params['FIFO_MODE']) params_list.append(params) print("endmodule") with open('params.json', 'w') as f: json.dump(params_list, f, indent=2)
def use_iserdese2(p, luts, connects): iobdelay = random.choice(( 'NONE', 'BOTH', 'IBUF', 'IFD', )) p['IOBDELAY'] = verilog.quote(iobdelay) p['INIT_Q1'] = random.randint(0, 1) p['INIT_Q2'] = random.randint(0, 1) p['INIT_Q3'] = random.randint(0, 1) p['INIT_Q4'] = random.randint(0, 1) p['SRVAL_Q1'] = random.randint(0, 1) p['SRVAL_Q2'] = random.randint(0, 1) p['SRVAL_Q3'] = random.randint(0, 1) p['SRVAL_Q4'] = random.randint(0, 1) p['NUM_CE'] = random.randint(1, 2) p['IS_CLK_INVERTED'] = random.randint(0, 1) p['IS_CLKB_INVERTED'] = random.randint(0, 1) p['IS_OCLK_INVERTED'] = random.randint(0, 1) p['IS_D_INVERTED'] = random.randint(0, 1) p['INTERFACE_TYPE'] = verilog.quote( random.choice(( 'MEMORY', 'MEMORY_DDR3', 'MEMORY_QDR', 'NETWORKING', 'OVERSAMPLE', ))) p['DATA_RATE'] = verilog.quote(random.choice(( 'SDR', 'DDR', ))) if verilog.unquote(p['DATA_RATE']) == 'SDR': data_widths = [2, 3, 4, 5, 6, 7, 8] else: data_widths = [4, 6, 8] p['DATA_WIDTH'] = random.choice(data_widths) p['SERDES_MODE'] = verilog.quote(random.choice(('MASTER', 'SLAVE'))) use_delay = iobdelay != 'NONE' if iobdelay == 'NONE': p['mux_config'] = 'direct' p['iddr_mux_config'] = 'direct' elif iobdelay == 'BOTH': p['mux_config'] = 'idelay' p['iddr_mux_config'] = 'idelay' elif iobdelay == 'IBUF': p['mux_config'] = 'idelay' p['iddr_mux_config'] = 'direct' elif iobdelay == 'IFD': p['mux_config'] = 'direct' p['iddr_mux_config'] = 'idelay' p['OFB_USED'] = verilog.quote(random.choice(('TRUE', 'FALSE'))) p['DYN_CLKDIV_INV_EN'] = verilog.quote(random.choice(('TRUE', 'FALSE'))) p['DYN_CLK_INV_EN'] = verilog.quote(random.choice(('TRUE', 'FALSE'))) if use_delay: print(""" wire idelay_{site}; (* KEEP, DONT_TOUCH, LOC = "{idelay_loc}" *) IDELAYE2 #( ) idelay_site_{site} ( .IDATAIN({iwire}), .DATAOUT(idelay_{site}) );""".format(**p), file=connects) p['ddly_connection'] = '.DDLY(idelay_{site}),'.format(**p) else: p['ddly_connection'] = '' if verilog.unquote(p['OFB_USED']) == 'TRUE': p['ODATA_RATE'] = verilog.quote(random.choice(( 'SDR', 'DDR', ))) if verilog.unquote(p['ODATA_RATE']) == 'SDR': data_widths = [2, 3, 4, 5, 6, 7, 8] else: data_widths = [4, 6, 8] p['ODATA_WIDTH'] = random.choice(data_widths) p['OSERDES_MODE'] = verilog.quote(random.choice(('MASTER', 'SLAVE'))) if p['ODATA_WIDTH'] == 4 and verilog.unquote(p['ODATA_RATE']) == 'DDR': p['TRISTATE_WIDTH'] = 4 else: p['TRISTATE_WIDTH'] = 1 print(""" wire tfb_{site}; wire ofb_{site}; (* KEEP, DONT_TOUCH, LOC = "{ologic_loc}" *) OSERDESE2 #( .SERDES_MODE({OSERDES_MODE}), .DATA_RATE_TQ({ODATA_RATE}), .DATA_RATE_OQ({ODATA_RATE}), .DATA_WIDTH({ODATA_WIDTH}), .TRISTATE_WIDTH({TRISTATE_WIDTH}) ) oserdese2_{site} ( .CLK(0), .CLKDIV(0), .D1(0), .TFB(tfb_{site}), .OQ({owire}), .TQ({twire}), .OFB(ofb_{site}) );""".format(**p), file=connects) p['ofb_connections'] = """ .OFB(ofb_{site}), """.format(**p) else: p['ofb_connections'] = '' print(''' (* KEEP, DONT_TOUCH, LOC = "{ilogic_loc}" *) ISERDESE2 #( .SERDES_MODE({SERDES_MODE}), .INIT_Q1({INIT_Q1}), .INIT_Q2({INIT_Q2}), .INIT_Q3({INIT_Q3}), .INIT_Q4({INIT_Q4}), .SRVAL_Q1({SRVAL_Q1}), .SRVAL_Q2({SRVAL_Q2}), .SRVAL_Q3({SRVAL_Q3}), .SRVAL_Q4({SRVAL_Q4}), .DYN_CLKDIV_INV_EN({DYN_CLKDIV_INV_EN}), .DYN_CLK_INV_EN({DYN_CLK_INV_EN}), .INTERFACE_TYPE({INTERFACE_TYPE}), .IS_CLK_INVERTED({IS_CLK_INVERTED}), .IS_CLKB_INVERTED({IS_CLKB_INVERTED}), .IS_OCLK_INVERTED({IS_OCLK_INVERTED}), .IS_D_INVERTED({IS_D_INVERTED}), .OFB_USED({OFB_USED}), .NUM_CE({NUM_CE}), .DATA_RATE({DATA_RATE}), .IOBDELAY({IOBDELAY}) ) iserdese2_{site} ( {ddly_connection} {ofb_connections} .D({iwire}), .CLK({clknet}), .CLKB({clkbnet}), .OCLK({oclknet}), .O({onet}), .Q1({q1net}), .CLKDIV(0) );'''.format(clknet=luts.get_next_output_net(), clkbnet=luts.get_next_output_net(), oclknet=luts.get_next_output_net(), onet=luts.get_next_input_net(), q1net=luts.get_next_input_net(), shiftout1net=luts.get_next_input_net(), shiftout2net=luts.get_next_input_net(), **p), file=connects)
def process_specimen(fasm_file, params_json): sites, diff_tiles = create_sites_from_fasm(fasm_file) with open(params_json) as f: params = json.load(f) count = 0 for p in params['tiles']: tile = p['tile'] for site in p['site'].split(' '): site_y = int(site[site.find('Y') + 1:]) % 2 if generate.skip_broken_tiles(p): continue site_key = 'IOB_Y{}'.format(site_y) if (tile, site_key) not in sites: assert p['type'] is None, p continue site_from_fasm = sites[(tile, site_key)] if site_y == 0 or tile not in diff_tiles: assert p['type'] in site_from_fasm['type'], ( tile, site_key, p['type'], site_from_fasm['type']) else: # Y1 on DIFF tiles is always none. assert p['type'] is None, p if p['type'] is None: continue assert 'PULLTYPE' in p, p assert 'PULLTYPE' in site_from_fasm, site_from_fasm if verilog.unquote(p['PULLTYPE']) == '': # Default is None. pulltype = verilog.quote('NONE') else: pulltype = p['PULLTYPE'] assert pulltype == site_from_fasm['PULLTYPE'], (tile, site_key, p, site_from_fasm) assert 'IOSTANDARDS' in site_from_fasm, (tile, site) iostandard = verilog.unquote(p['IOSTANDARD']) if iostandard.startswith('DIFF_'): iostandard = iostandard[5:] assert iostandard in site_from_fasm['IOSTANDARDS'], ( p['IOSTANDARD'], site_from_fasm['IOSTANDARDS'], ) if p['type'] not in ['IBUF', 'IBUFDS']: if verilog.unquote(p['SLEW']) == '': # Default is None. slew = verilog.quote('SLOW') else: slew = p['SLEW'] assert slew == site_from_fasm['SLEW'], (tile, site_key, p, site_from_fasm) assert 'DRIVES' not in p, p assert 'DRIVES' in site_from_fasm, (tile, site, p['type'], site_from_fasm) if p['DRIVE'] is None: assert None in site_from_fasm['DRIVES'], ( tile, site_key, p['DRIVE'], site_from_fasm['DRIVES']) elif p['DRIVE'] is '': if None in site_from_fasm['DRIVES']: # IOSTANDARD has not DRIVE setting, ignore pass else: # Check that drive is at default assert 'I12' in site_from_fasm['DRIVES'], ( tile, site_key, p['DRIVE'], site_from_fasm['DRIVES']) else: assert 'I{}'.format( p['DRIVE']) in site_from_fasm['DRIVES'], ( tile, site_key, p['DRIVE'], site_from_fasm['DRIVES']) count += 1 return count
def main(): sites = sorted(list(gen_sites())) max_sites = len(sites) f = open('params.jl', 'w') f.write('module,loc,params\n') routes_file = open('routes.txt', 'w') print( """ module top( input [{N}:0] clkin1, input [{N}:0] clkin2, input [{N}:0] clkfb, input [{N}:0] dclk ); (* KEEP, DONT_TOUCH *) LUT1 dummy(); """.format(N=max_sites - 1)) for i, (tile_name, tile_type, site, hclk_wires) in enumerate(sorted(gen_sites())): params = { "site": site, 'active': random.random() > .2, "clkin1_conn": random.choice( ("clkfbout_mult_BUFG_" + site, "clkin1[{}]".format(i), "")), "clkin2_conn": random.choice( ("clkfbout_mult_BUFG_" + site, "clkin2[{}]".format(i), "")), "dclk_conn": random.choice(( "0", "dclk[{}]".format(i), )), "dwe_conn": random.choice(( "", "1", "0", "dwe_" + site, "den_" + site, )), "den_conn": random.choice(( "", "1", "0", "den_" + site, )), "daddr4_conn": random.choice(( "0", "dwe_" + site, )), "IS_RST_INVERTED": random.randint(0, 1), "IS_PWRDWN_INVERTED": random.randint(0, 1), "IS_CLKINSEL_INVERTED": random.randint(0, 1), "IS_PSEN_INVERTED": random.randint(0, 1), "IS_PSINCDEC_INVERTED": random.randint(0, 1), "CLKFBOUT_MULT_F": random.randint(2, 4), "CLKOUT0_DIVIDE_F": random.randint(1, 128), "CLKOUT1_DIVIDE": random.randint(1, 128), "CLKOUT2_DIVIDE": random.randint(1, 128), "CLKOUT3_DIVIDE": random.randint(1, 128), "CLKOUT4_DIVIDE": random.randint(1, 128), "CLKOUT5_DIVIDE": random.randint(1, 128), "CLKOUT6_DIVIDE": random.randint(1, 128), "DIVCLK_DIVIDE": random.randint(1, 5), "CLKOUT0_DUTY_CYCLE": "0.500", "STARTUP_WAIT": verilog.quote('TRUE' if random.randint(0, 1) else 'FALSE'), "COMPENSATION": verilog.quote( random.choice(( 'ZHOLD', 'BUF_IN', 'EXTERNAL', 'INTERNAL', ))), "BANDWIDTH": verilog.quote(random.choice(( 'OPTIMIZED', 'HIGH', 'LOW', ))), "SS_EN": gen_true_false(0.15), } # SS_EN requires BANDWIDTH to be LOW if verilog.unquote(params["SS_EN"]) == "TRUE": params["BANDWIDTH"] = verilog.quote("LOW") if verilog.unquote(params['COMPENSATION']) == 'ZHOLD': params['clkfbin_conn'] = random.choice( ( "", "clkfbout_mult_BUFG_" + site, )) elif verilog.unquote(params['COMPENSATION']) == 'INTERNAL': params['clkfbin_conn'] = random.choice( ( "", "clkfbout_mult_" + site, )) else: params['clkfbin_conn'] = random.choice( ("", "clkfb[{}]".format(i), "clkfbout_mult_BUFG_" + site)) def get_clkin_wires(idx): wires = [ "{tile}_CLKIN{idx}", "{tile}_FREQ_BB0", "{tile}_FREQ_BB1", "{tile}_FREQ_BB2", "{tile}_FREQ_BB3", "{tile}_CLK_IN{idx}_INT" "{tile}_CLK_IN{idx}_HCLK" ] return [ tile_name + "/" + w.format(tile=tile_type, idx=idx) for w in wires ] params['clkin1_route'] = random.choice(get_clkin_wires(1) + hclk_wires) params['clkin2_route'] = random.choice(get_clkin_wires(2) + hclk_wires) params['clkfbin_route'] = random.choice( ( "{}_CLKFBOUT2IN", "{}_FREQ_BB0", "{}_FREQ_BB1", "{}_FREQ_BB2", "{}_FREQ_BB3", "{}_CLK_IN3_INT", "{}_CLK_IN3_HCLK", )).format(tile_type) f.write('%s\n' % (json.dumps(params))) def make_ibuf_net(net): p = net.find('[') return net[:p] + '_IBUF' + net[p:] if params['clkin1_conn'] != "": net = params['clkin1_conn'] if "[" in net and "]" in net: net = make_ibuf_net(net) wire = params['clkin1_route'] routes_file.write('{} {}\n'.format(net, wire)) if params['clkin2_conn'] != "": net = params['clkin2_conn'] if "[" in net and "]" in net: net = make_ibuf_net(net) wire = params['clkin2_route'] routes_file.write('{} {}\n'.format(net, wire)) if params['clkfbin_conn'] != "" and\ params['clkfbin_conn'] != ("clkfbout_mult_BUFG_" + site): net = params['clkfbin_conn'] if "[" in net and "]" in net: net = make_ibuf_net(net) wire = '{}/{}'.format(tile_name, params['clkfbin_route']) routes_file.write('{} {}\n'.format(net, wire)) if not params['active']: continue print( """ wire den_{site}; wire dwe_{site}; LUT1 den_lut_{site} ( .O(den_{site}) ); LUT1 dwe_lut_{site} ( .O(dwe_{site}) ); wire clkfbout_mult_{site}; wire clkfbout_mult_BUFG_{site}; wire clkout0_{site}; wire clkout1_{site}; wire clkout2_{site}; wire clkout3_{site}; wire clkout4_{site}; wire clkout5_{site}; wire clkout6_{site}; (* KEEP, DONT_TOUCH, LOC = "{site}" *) MMCME2_ADV #( .IS_RST_INVERTED({IS_RST_INVERTED}), .IS_PWRDWN_INVERTED({IS_PWRDWN_INVERTED}), .IS_CLKINSEL_INVERTED({IS_CLKINSEL_INVERTED}), .IS_PSEN_INVERTED({IS_PSEN_INVERTED}), .IS_PSINCDEC_INVERTED({IS_PSINCDEC_INVERTED}), .CLKOUT0_DIVIDE_F({CLKOUT0_DIVIDE_F}), .CLKOUT1_DIVIDE({CLKOUT1_DIVIDE}), .CLKOUT2_DIVIDE({CLKOUT2_DIVIDE}), .CLKOUT3_DIVIDE({CLKOUT3_DIVIDE}), .CLKOUT4_DIVIDE({CLKOUT4_DIVIDE}), .CLKOUT5_DIVIDE({CLKOUT5_DIVIDE}), .CLKOUT6_DIVIDE({CLKOUT6_DIVIDE}), .CLKFBOUT_MULT_F({CLKFBOUT_MULT_F}), .DIVCLK_DIVIDE({DIVCLK_DIVIDE}), .STARTUP_WAIT({STARTUP_WAIT}), .CLKOUT0_DUTY_CYCLE({CLKOUT0_DUTY_CYCLE}), .COMPENSATION({COMPENSATION}), .BANDWIDTH({BANDWIDTH}), .SS_EN({SS_EN}), .CLKIN1_PERIOD(10.0), .CLKIN2_PERIOD(10.0) ) pll_{site} ( .CLKFBOUT(clkfbout_mult_{site}), .CLKOUT0(clkout0_{site}), .CLKOUT1(clkout1_{site}), .CLKOUT2(clkout2_{site}), .CLKOUT3(clkout3_{site}), .CLKOUT4(clkout4_{site}), .CLKOUT5(clkout5_{site}), .CLKOUT6(clkout6_{site}), .DRDY(), .LOCKED(), .DO(), .CLKFBIN({clkfbin_conn}), .CLKIN1({clkin1_conn}), .CLKIN2({clkin2_conn}), .CLKINSEL(), .DCLK({dclk_conn}), .DEN({den_conn}), .DWE({dwe_conn}), .PWRDWN(), .RST(), .DI(), .DADDR({{7{{ {daddr4_conn} }} }})); (* KEEP, DONT_TOUCH *) BUFG bufg_{site} ( .I(clkfbout_mult_{site}), .O(clkfbout_mult_BUFG_{site}) ); (* KEEP, DONT_TOUCH *) FDRE reg_clkfbout_mult_{site} ( .C(clkfbout_mult_{site}) ); """.format(**params)) disabled_clkout = random.randint(0, 7) for clk in range(0, 7): if clk == disabled_clkout: continue print( """ (* KEEP, DONT_TOUCH *) FDRE reg_clkout{clk}_{site} ( .C(clkout{clk}_{site}) ); """.format(clk=clk, site=params['site'])) print('endmodule') f.close()
def main(): print("Loading tags") segmk = Segmaker("design.bits") with open('params.jl', 'r') as f: design = json.load(f) for d in design: site = d['ologic_loc'] handle_data_width(segmk, d) segmk.add_site_tag(site, 'OSERDES.IN_USE', d['use_oserdese2']) if d['use_oserdese2']: segmk.add_site_tag(site, 'OQUSED', 1) for opt in ['SDR', 'DDR']: segmk.add_site_tag( site, 'OSERDES.DATA_RATE_OQ.{}'.format(opt), verilog.unquote(d['DATA_RATE_OQ']) == opt) for opt in ['BUF', 'SDR', 'DDR']: segmk.add_site_tag( site, 'OSERDES.DATA_RATE_TQ.{}'.format(opt), verilog.unquote(d['DATA_RATE_TQ']) == opt) for opt in ['SRVAL_OQ', 'SRVAL_TQ', 'INIT_OQ', 'INIT_TQ']: segmk.add_site_tag(site, opt, d[opt]) segmk.add_site_tag(site, 'Z' + opt, 1 ^ d[opt]) for opt in ['CLK', 'CLKDIV']: if d['{}_USED'.format(opt)]: k = 'IS_{}_INVERTED'.format(opt) segmk.add_site_tag(site, k, d[k]) segmk.add_site_tag(site, 'ZINV_{}'.format(opt), 1 ^ d[k]) if d['io']: for idx in range(4): k = 'IS_T{}_INVERTED'.format(idx + 1) segmk.add_site_tag(site, k, d[k]) segmk.add_site_tag(site, 'ZINV_T{}'.format(idx + 1), 1 ^ d[k]) for idx in range(8): k = 'IS_D{}_INVERTED'.format(idx + 1) segmk.add_site_tag(site, k, d[k]) segmk.add_site_tag(site, 'ZINV_D{}'.format(idx + 1), 1 ^ d[k]) for tristate_width in [1, 4]: segmk.add_site_tag( site, 'OSERDES.TRISTATE_WIDTH.W{}'.format(tristate_width), d['TRISTATE_WIDTH'] == tristate_width) for opt in ['MASTER', 'SLAVE']: segmk.add_site_tag( site, 'OSERDES.SERDES_MODE.{}'.format(opt), opt == verilog.unquote(d['OSERDES_MODE'])) if d['oddr_mux_config'] == 'direct' and d[ 'tddr_mux_config'] == 'direct': for opt in ['OPPOSITE_EDGE', 'SAME_EDGE']: segmk.add_site_tag( site, 'ODDR.DDR_CLK_EDGE.{}'.format(opt), verilog.unquote(d['ODDR_CLK_EDGE']) == opt) segmk.add_site_tag(site, 'TDDR.DDR_CLK_EDGE.INV', d['ODDR_CLK_EDGE'] != d['TDDR_CLK_EDGE']) segmk.add_site_tag(site, 'TDDR.DDR_CLK_EDGE.ZINV', d['ODDR_CLK_EDGE'] == d['TDDR_CLK_EDGE']) if 'SRTYPE' in d: for opt in ['ASYNC', 'SYNC']: segmk.add_site_tag(site, 'OSERDES.SRTYPE.{}'.format(opt), verilog.unquote(d['SRTYPE']) == opt) for opt in ['ASYNC', 'SYNC']: segmk.add_site_tag(site, 'OSERDES.TSRTYPE.{}'.format(opt), verilog.unquote(d['TSRTYPE']) == opt) if not d['use_oserdese2']: if d['oddr_mux_config'] == 'lut': segmk.add_site_tag(site, 'OMUX.D1', 1) segmk.add_site_tag(site, 'OQUSED', 1) elif d['oddr_mux_config'] == 'direct': segmk.add_site_tag(site, 'OMUX.D1', 0) elif d['oddr_mux_config'] == 'none' and not d['io']: segmk.add_site_tag(site, 'OQUSED', 0) segmk.add_site_tag(site, 'TQUSED', d['io']) if DEBUG_FUZZER: for k in d: segmk.add_site_tag( site, 'param_' + k + '_' + str(d[k]).replace(' ', '').replace('\n', ''), 1) segmk.compile(bitfilter=bitfilter) segmk.write(allow_empty=True)