def __init__(self): self.site_to_cmt = dict(read_site_to_cmt()) self.leaf_gclks = {} self.ioclks = {} self.rclks = {} self.selected_leaf_gclks = {} self.lut_maker = lut_maker.LutMaker() for cmt in set(self.site_to_cmt.values()): self.leaf_gclks[cmt] = [] self.ioclks[cmt] = [] self.rclks[cmt] = []
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")
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 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 generate_netlist(params): DUTN = len(params) DIN_N = DUTN * 32 DOUT_N = DUTN * 32 string_output = io.StringIO() any_bscan = False any_icap = False usr_access_on = False capture_on = False startup_on = False frame_ecc_on = False dcireset_on = False luts = lut_maker.LutMaker() verilog.top_harness(DIN_N, DOUT_N) print(''' module roi(input clk, input [%d:0] din, output [%d:0] dout);''' % (DIN_N - 1, DOUT_N - 1)) for loci, param in enumerate(params): ports = { 'din': 'din[{} +: 8]'.format(8 * loci), 'dout': 'dout[{} +: 8]'.format(8 * loci), 'clk': 'clk' } if param["site_type"] in "BSCAN": ports = { 'din': '{{din[{} +: 7],{}}}'.format(8 * loci + 1, luts.get_next_output_net()), 'dout': '{{dout[{} +: 7],{}}}'.format(8 * loci + 1, luts.get_next_input_net()), 'clk': 'clk' } any_bscan = True elif param["site_type"] in ["ICAP"]: any_icap = True elif param["site_type"] in ["CAPTURE"]: capture_on = True elif param["site_type"] in ["STARTUP"]: startup_on = True elif param["site_type"] in ["FRAME_ECC"]: frame_ecc_on = True elif param["site_type"] in ["USR_ACCESS", "DCIRESET"]: if not param["params"]["ENABLED"]: continue if param["site_type"] in ["DCIRESET"]: dcireset_on = True else: usr_access_on = True else: continue verilog.instance(param["module"], "inst_{}".format(param["site"]), ports, param["params"], string_buffer=string_output) #Generate LUTs for l in luts.create_wires_and_luts(): print(l) print(string_output.getvalue()) print(''' endmodule // ---------------------------------------------------------------------''') if any_icap: print(''' module mod_ICAP (input [7:0] din, output [7:0] dout, input clk); parameter ICAP_WIDTH = "X32"; parameter LOC = "ICAP_X0Y0"; wire [23:0] icap_out; (* KEEP, DONT_TOUCH, LOC=LOC *) ICAPE2 #( .ICAP_WIDTH(ICAP_WIDTH), .SIM_CFG_FILE_NAME("NONE") ) ICAPE2_inst ( .O({icap_out, dout}), .CLK(clk), .CSIB(), .I({24'd0, din}), .RDWRB() ); endmodule ''') if capture_on: print(''' module mod_CAPTURE (input [7:0] din, output [7:0] dout, input clk); parameter ONESHOT ="TRUE"; parameter LOC = "ICAP_X0Y0"; (* KEEP, DONT_TOUCH, LOC=LOC *) CAPTUREE2 #( .ONESHOT(ONESHOT) // Specifies the procedure for performing single readback per CAP trigger. ) CAPTUREE2_inst ( .CAP(1'b0), .CLK(clk) ); endmodule ''') if usr_access_on: print(''' module mod_USR_ACCESS (input [7:0] din, output [7:0] dout, input clk); parameter ENABLED = 1; parameter LOC = "USR_ACCESS_X0Y0"; wire [23:0] usr_access_wire; (* KEEP, DONT_TOUCH, LOC=LOC *) USR_ACCESSE2 USR_ACCESSE2_inst ( .CFGCLK(), .DATA({usr_access_wire, dout}), .DATAVALID() ); endmodule ''') if any_bscan: print(''' module mod_BSCAN (input [7:0] din, output [7:0] dout, input clk); parameter JTAG_CHAIN = 1; parameter LOC = "BSCAN_X0Y0"; (* KEEP, DONT_TOUCH, LOC=LOC *) BSCANE2 #( .JTAG_CHAIN(JTAG_CHAIN) ) dut ( .CAPTURE(), .DRCK(), .RESET(), .RUNTEST(), .SEL(), .SHIFT(), .TCK(), .TDI(dout[0]), .TMS(), .UPDATE(), .TDO(din[0]) ); endmodule ''') if startup_on: print(''' module mod_STARTUP (input [7:0] din, output [7:0] dout, input clk); parameter LOC = "STARTUP_X0Y0"; parameter PROG_USR = "******"; (* KEEP, DONT_TOUCH, LOC=LOC *) STARTUPE2 #( .PROG_USR(PROG_USR), // Activate program event security feature. Requires encrypted bitstreams. .SIM_CCLK_FREQ(0.0) // Set the Configuration Clock Frequency(ns) for simulation. ) STARTUPE2_inst ( .CFGCLK(), .CFGMCLK(), .EOS(), .PREQ(dout[0]), .CLK(clk), .GSR(), .GTS(), .KEYCLEARB(), .PACK(), .USRCCLKO(), .USRCCLKTS(), .USRDONEO(), .USRDONETS() ); endmodule ''') if frame_ecc_on: print(''' module mod_FRAME_ECC (input [7:0] din, output [7:0] dout, input clk); parameter LOC = "FRAME_ECC_X0Y0"; parameter FARSRC = "EFAR"; wire [25:0] far_wire; assign dout[7:0] = far_wire[7:0]; (* KEEP, DONT_TOUCH, LOC=LOC *) FRAME_ECCE2 #( .FARSRC(FARSRC), .FRAME_RBT_IN_FILENAME("NONE") ) FRAME_ECCE2_inst ( .CRCERROR(), .ECCERROR(), .ECCERRORSINGLE(), .FAR(far_wire), .SYNBIT(), .SYNDROME(), .SYNDROMEVALID(), .SYNWORD() ); endmodule ''') if dcireset_on: print(''' module mod_DCIRESET (input [7:0] din, output [7:0] dout, input clk); parameter LOC = "FRAME_ECC_X0Y0"; parameter ENABLED = 1; (* KEEP, DONT_TOUCH, LOC=LOC *) DCIRESET DCIRESET_inst ( .LOCKED(dout[0]), .RST(dout[1]) ); endmodule ''')
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' ] 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 = [] any_idelay = False for tile, site in gen_sites(): p = {} p['tile'] = tile p['site'] = site p['type'] = random.choice(tile_types) p['IOSTANDARD'] = verilog.quote(iostandard) 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) i_idx += 1 elif p['type'] == 'OBUF': p['pad_wire'] = 'do[{}]'.format(o_idx) p['iwire'] = luts.get_next_output_net() p['DRIVE'] = random.choice(drives) p['SLEW'] = verilog.quote(random.choice(slews)) o_idx += 1 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() p['DRIVE'] = random.choice(drives) 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 params.append(p) if p['type'] is not None: 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} `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: 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'] == 'OBUF': print(''' (* KEEP, DONT_TOUCH *) OBUF #( .IOSTANDARD({IOSTANDARD}), .DRIVE({DRIVE}), .SLEW({SLEW}) ) ibuf_{site} ( .O({pad_wire}), .I({iwire}) );'''.format(**p), file=connects) elif p['type'] == 'IOBUF_INTERMDISABLE': print(''' (* KEEP, DONT_TOUCH *) IOBUF_INTERMDISABLE #( .IOSTANDARD({IOSTANDARD}), .DRIVE({DRIVE}), .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.jl', 'w') as f: json.dump(params, f, indent=2)