def generate_params(): bscan_already_on = False icap_already_on = False tile_params = [] for loci, (site, site_type) in enumerate(sorted(gen_sites())): p = {} if site_type in "ICAP" and not icap_already_on: p["ICAP_WIDTH"] = verilog.quote(random.choice(["X32", "X8", "X16"])) elif site_type in "BSCAN" and not bscan_already_on: p["JTAG_CHAIN"] = random.randint(1, 4) bscan_already_on = True elif site_type in "CAPTURE": p["ONESHOT"] = verilog.quote(random.choice(["TRUE", "FALSE"])) elif site_type in "STARTUP": p["PROG_USR"] = verilog.quote(random.choice(["TRUE", "FALSE"])) elif site_type in "FRAME_ECC": p["FARSRC"] = verilog.quote(random.choice(["FAR", "EFAR"])) elif site_type in [ "DCIRESET", "USR_ACCESS" ]: #The primitives from these sites have no parameters p["ENABLED"] = random.randint(0, 1) else: continue p["LOC"] = verilog.quote(site) tile_params.append({ "site": site, "site_type": site_type, "module": "mod_{}".format(site_type), "params": p }) return tile_params
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 process_parts(parts): if len(parts) == 0: return if parts[-1] == 'IN_ONLY': yield 'type', ['IBUF', 'IBUFDS'] if len(parts) > 2 and parts[-2] == 'SLEW': yield 'SLEW', verilog.quote(parts[-1]) if parts[0] == 'PULLTYPE': yield 'PULLTYPE', verilog.quote(parts[1]) if len(parts) > 1 and parts[1] == 'IN': yield 'IOSTANDARDS', parts[0].split('_') yield 'IN', True if len(parts) > 1 and parts[1] == 'IN_DIFF': yield 'IOSTANDARDS', parts[0].split('_') yield 'IN_DIFF', True if len(parts) > 1 and parts[1] == 'DRIVE': yield 'IOSTANDARDS', parts[0].split('_') if parts[2] == 'I_FIXED': yield 'DRIVES', [None] else: yield 'DRIVES', parts[2].split('_')
def process_parts(parts): if parts[0] == 'INOUT': yield 'type', 'IOBUF_INTERMDISABLE' if parts[0] == 'IN_ONLY': yield 'type', 'IBUF' if parts[0] == 'SLEW': yield 'SLEW', verilog.quote(parts[1]) if parts[0] == 'PULLTYPE': yield 'PULLTYPE', verilog.quote(parts[1]) if len(parts) > 1 and parts[1] == 'IN': yield 'IOSTANDARDS', parts[0].split('_') if len(parts) > 1 and parts[1] == 'DRIVE': yield 'IOSTANDARDS', parts[0].split('_') yield 'DRIVES', parts[2].split('_')
def main(): print(''' module top(); ''') lines = [] site_name, site_type = gen_sites() params = dict() params['site'] = site_name verilog_attr = "" verilog_attr = "#(" # Add boolean parameters for param, _ in boolean_params: value = random.randint(0, 1) value_string = "TRUE" if value else "FALSE" params[param] = value verilog_attr += """ .{}({}),""".format(param, verilog.quote(value_string)) # Add hexadecimal parameters for param, digits in hex_params: value = random.randint(0, 2**digits) params[param] = value verilog_attr += """ .{}({}),""".format( param, "{digits}'h{value:08x}".format(value=value, digits=digits)) # Add integer parameters for param, digits in int_params: value = random.randint(0, 2**digits) params[param] = value verilog_attr += """ .{}({}),""".format( param, "{digits}'d{value:04d}".format(value=value, digits=digits)) verilog_attr = verilog_attr.rstrip(",") verilog_attr += "\n)" print("PCIE_2_1 {} pcie ();".format(verilog_attr)) print("endmodule") with open('params.json', 'w') as f: json.dump(params, f, indent=2)
def main(): print(''' module top(); ''') lines = [] site_name, site_type = gen_sites() params = dict() params['site'] = site_name verilog_attr = "" verilog_attr = "#(" fuz_dir = os.getenv("FUZDIR", None) assert fuz_dir with open(os.path.join(fuz_dir, "attrs.json"), "r") as attrs_file: attrs = json.load(attrs_file) for param, param_info in attrs.items(): param_type = param_info["type"] param_values = param_info["values"] param_digits = param_info["digits"] if param_type == BOOL: value = random.choice(param_values) value_str = verilog.quote(value) elif param_type == BIN: if type(param_values) is int: value = param_values elif type(param_values) is list: if len(param_values) > 1: value = random.choice(param_values) else: value = random.randint(0, param_values[0]) value_str = "{digits}'b{value:0{digits}b}".format( value=value, digits=param_digits) params[param] = value verilog_attr += """ .{}({}),""".format(param, value_str) verilog_attr = verilog_attr.rstrip(",") verilog_attr += "\n)" print("PCIE_2_1 {} pcie ();".format(verilog_attr)) print("endmodule") with open('params.json', 'w') as f: json.dump(params, f, indent=2)
def place_bram18(): ports = { 'clk': 'clk', 'din': 'din[ %d +: 8]' % (8 * loci, ), 'dout': 'dout[ %d +: 8]' % (8 * loci, ), } write_modes = ["WRITE_FIRST", "READ_FIRST", "NO_CHANGE"] # Datasheet says 72 is legal in some cases, but think its a copy paste error from BRAM36 # also 0 and 36 aren't real sizes # Bias choice to 18 as its needed to solve certain bits quickly widths = [1, 2, 4, 9, 18, 18, 18, 18] params = { 'LOC': verilog.quote(site), 'IS_CLKARDCLK_INVERTED': vrandbit(), 'IS_CLKBWRCLK_INVERTED': vrandbit(), 'IS_ENARDEN_INVERTED': vrandbit(), 'IS_ENBWREN_INVERTED': vrandbit(), 'IS_RSTRAMARSTRAM_INVERTED': vrandbit(), 'IS_RSTRAMB_INVERTED': vrandbit(), 'IS_RSTREGARSTREG_INVERTED': vrandbit(), 'IS_RSTREGB_INVERTED': vrandbit(), 'RAM_MODE': '"TDP"', 'WRITE_MODE_A': verilog.quote(random.choice(write_modes)), 'WRITE_MODE_B': verilog.quote(random.choice(write_modes)), "DOA_REG": vrandbit(), "DOB_REG": vrandbit(), "SRVAL_A": vrandbits(18), "SRVAL_B": vrandbits(18), "INIT_A": vrandbits(18), "INIT_B": vrandbits(18), "READ_WIDTH_A": random.choice(widths), "READ_WIDTH_B": random.choice(widths), "WRITE_WIDTH_A": random.choice(widths), "WRITE_WIDTH_B": random.choice(widths), } return ('my_RAMB18E1', ports, params)
def gen_iddr(loc): # Site params params = { "SITE_LOC": verilog.quote(loc), "USE_IDELAY": random.randint(0, 1), "BEL_TYPE": verilog.quote(random.choice(["IDDR", "IDDR_NO_CLK"])), "INIT_Q1": random.randint(0, 1), "INIT_Q2": random.randint(0, 1), "SRTYPE": verilog.quote(random.choice(["ASYNC", "SYNC"])), "DDR_CLK_EDGE": verilog.quote( random.choice( ["OPPOSITE_EDGE", "SAME_EDGE", "SAME_EDGE_PIPELINED"])), "CE1USED": random.randint(0, 1), "SR_MODE": verilog.quote(random.choice(["NONE", "SET", "RST"])), "IS_C_INVERTED": random.randint(0, 1), "IS_D_INVERTED": random.randint(0, 1), } if params["USE_IDELAY"]: params["IDELMUX"] = random.randint(0, 1) params["IFFDELMUX"] = random.randint(0, 1) else: params["IDELMUX"] = 0 params["IFFDELMUX"] = 0 return params
def run(): print(''' module top(); ''') params = {} # FIXME: can't LOC? # only one for now, worry about later sites = list(gen_sites()) for (tile_name, site_name), isone in zip(sites, util.gen_fuzz_states(len(sites))): params[tile_name] = (site_name, isone) print(''' (* KEEP, DONT_TOUCH, LOC = "{site_name}" *) PLLE2_ADV #( .STARTUP_WAIT({isone}) ) dut_{site_name} (); '''.format( site_name=site_name, isone=verilog.quote('TRUE' if isone else 'FALSE'), )) print("endmodule") write_params(params)
def main(): print(''' module top(); ''') params_list = [] for tile_name, x_min, y_min, sites in gen_sites(): for site, x, y in sites: params = {} params['tile'] = tile_name params['site'] = site params['x'] = x - x_min params['y'] = y - y_min params['IN_USE'] = random.randint(0, 1) if params['IN_USE']: params['INIT_OUT'] = random.randint(0, 1) params['CE_TYPE'] = verilog.quote( random.choice(('SYNC', 'ASYNC'))) params['IS_CE_INVERTED'] = random.randint(0, 1) print(''' (* KEEP, DONT_TOUCH, LOC = "{site}" *) BUFHCE #( .INIT_OUT({INIT_OUT}), .CE_TYPE({CE_TYPE}), .IS_CE_INVERTED({IS_CE_INVERTED}) ) buf_{site} (); '''.format(**params)) params_list.append(params) print("endmodule") with open('params.json', 'w') as f: json.dump(params_list, f, indent=2)
"CLKOUT4_CASCADE": random.choice(["\"TRUE\"", "\"FALSE\""]), "STARTUP_WAIT": random.choice(["\"TRUE\"", "\"FALSE\""]), "CLKFBOUT_USE_FINE_PS": random.choice(["\"TRUE\"", "\"FALSE\""]), "CLKOUT0_USE_FINE_PS": random.choice(["\"TRUE\"", "\"FALSE\""]), "CLKOUT1_USE_FINE_PS": random.choice(["\"TRUE\"", "\"FALSE\""]), "CLKOUT2_USE_FINE_PS": random.choice(["\"TRUE\"", "\"FALSE\""]), "CLKOUT3_USE_FINE_PS": random.choice(["\"TRUE\"", "\"FALSE\""]), "CLKOUT4_USE_FINE_PS": random.choice(["\"TRUE\"", "\"FALSE\""]), "CLKOUT5_USE_FINE_PS": random.choice(["\"TRUE\"", "\"FALSE\""]), "CLKOUT6_USE_FINE_PS": random.choice(["\"TRUE\"", "\"FALSE\""]), } modname = "my_MMCME2_ADV" verilog.instance(modname, "inst_%u" % loci, ports, params=params) # LOC isn't supported params["LOC"] = verilog.quote(site) j = {'module': modname, 'i': loci, 'params': params} f.write('%s\n' % (json.dumps(j))) print('') f.close() print('''endmodule // --------------------------------------------------------------------- ''') print(''' module my_MMCME2_ADV (input clk, input [7:0] din, output [7:0] dout); parameter CLKOUT1_DIVIDE = 1;
def run(): print(''' module top(input clk, stb, di, output do); localparam integer DIN_N = 8; localparam integer DOUT_N = 8; reg [DIN_N-1:0] din; wire [DOUT_N-1:0] dout; reg [DIN_N-1:0] din_shr; reg [DOUT_N-1:0] dout_shr; always @(posedge clk) begin din_shr <= {din_shr, di}; dout_shr <= {dout_shr, din_shr[DIN_N-1]}; if (stb) begin din <= din_shr; dout_shr <= dout; end end assign do = dout_shr[DOUT_N-1]; ''') params = {} # FIXME: can't LOC? # only one for now, worry about later sites = list(gen_sites()) for (tile_name, site_name), isone in zip(sites, util.gen_fuzz_states(len(sites))): # 0 is invalid # shift one bit, keeping LSB constant CLKOUT1_DIVIDE = {0: 2, 1: 3}[isone] params[tile_name] = (site_name, CLKOUT1_DIVIDE) print(''' (* KEEP, DONT_TOUCH, LOC=%s *) MMCME2_ADV #(/*.LOC("%s"),*/ .CLKOUT1_DIVIDE(%u)) dut_%s( .CLKFBOUT(), .CLKFBOUTB(), .CLKFBSTOPPED(), .CLKINSTOPPED(), .CLKOUT0(), .CLKOUT0B(), .CLKOUT1(), .CLKOUT1B(), .CLKOUT2(), .CLKOUT2B(), .CLKOUT3(), .CLKOUT3B(), .CLKOUT4(), .CLKOUT5(), .CLKOUT6(), .DO(), .DRDY(), .LOCKED(), .PSDONE(), .CLKFBIN(clk), .CLKIN1(clk), .CLKIN2(clk), .CLKINSEL(clk), .DADDR(), .DCLK(clk), .DEN(), .DI(), .DWE(), .PSCLK(clk), .PSEN(), .PSINCDEC(), .PWRDWN(), .RST()); ''' % (verilog.quote(site_name), site_name, CLKOUT1_DIVIDE, site_name)) print("endmodule") write_params(params)
def run(): # Get all [LR]IOI3 tiles tiles = list(gen_sites()) # Header print("// Tile count: %d" % len(tiles)) print("// Seed: '%s'" % os.getenv("SEED")) print(''' module top ( (* CLOCK_BUFFER_TYPE = "NONE" *) input wire clk1, (* CLOCK_BUFFER_TYPE = "NONE" *) input wire clk2, input wire ce, input wire rst, input wire [{N}:0] di, output wire [{N}:0] do ); wire [{N}:0] di_buf; wire [{N}:0] do_buf; // IDELAYCTRL (* KEEP, DONT_TOUCH *) IDELAYCTRL idelayctrl(); '''.format(**{"N": len(tiles) - 1})) # LOCes IOBs data = [] for i, sites in enumerate(tiles): tile_name = sites[0] # Use site if random.randint(0, 19) > 0: # Use more often # Top sites if random.randint(0, 1): this_sites = sites[1] other_sites = sites[2] # Bottom sites else: this_sites = sites[2] other_sites = sites[1] # Generate cell bel_types = ["IDDR", "ISERDESE2"] bel_type = bel_types[int( random.randint(0, 2) > 0)] # ISERDES more often if bel_type == "ISERDESE2": params = gen_iserdes(this_sites["ILOGIC"]) if bel_type == "IDDR": params = gen_iddr(this_sites["ILOGIC"]) params["IDELAY_LOC"] = verilog.quote(this_sites["IDELAY"]) params["IS_USED"] = 1 # Instantiate the cell print('') print('// This : ' + " ".join(this_sites.values())) print('// Other: ' + " ".join(other_sites.values())) print('(* LOC="%s", KEEP, DONT_TOUCH *)' % this_sites["IOB"]) print('IBUF ibuf_%03d (.I(di[%3d]), .O(di_buf[%3d]));' % (i, i, i)) print('(* LOC="%s", KEEP, DONT_TOUCH *)' % other_sites["IOB"]) print('OBUF obuf_%03d (.I(do_buf[%3d]), .O(do[%3d]));' % (i, i, i)) clk1_conn = random.choice(["clk1", ""]) param_str = ",".join(".%s(%s)" % (k, v) for k, v in params.items()) print( 'ilogic_single #(%s) ilogic_%03d (.clk1(%s), .clk2(clk2), .ce(ce), .rst(rst), .I(di_buf[%3d]), .O(do_buf[%3d]));' % (param_str, i, clk1_conn, i, i)) params["CHAINED"] = 0 params["TILE_NAME"] = tile_name # Params for the second site other_params = { "TILE_NAME": tile_name, "SITE_LOC": verilog.quote(other_sites["ILOGIC"]), "IDELAY_LOC": verilog.quote(other_sites["IDELAY"]), "IS_USED": 0, } # Append to data list data.append([params, other_params]) # Don't use sites else: params_list = [{ "TILE_NAME": tile_name, "SITE_LOC": verilog.quote(sites[1]["ILOGIC"]), "IDELAY_LOC": verilog.quote(sites[1]["IDELAY"]), "IS_USED": 0, }, { "TILE_NAME": tile_name, "SITE_LOC": verilog.quote(sites[2]["ILOGIC"]), "IDELAY_LOC": verilog.quote(sites[2]["IDELAY"]), "IS_USED": 0, }] data.append(params_list) # Store params with open("params.json", "w") as fp: json.dump(data, fp, sort_keys=True, indent=1) print(''' endmodule (* KEEP, DONT_TOUCH *) module ilogic_single( input wire clk1, input wire clk2, input wire ce, input wire rst, input wire I, output wire O, input wire [1:0] shiftin, output wire [1:0] shiftout ); parameter SITE_LOC = ""; parameter IS_USED = 1; parameter BEL_TYPE = "ISERDESE2"; parameter IDELAY_LOC = ""; parameter USE_IDELAY = 0; parameter IDELMUX = 0; parameter IFFDELMUX = 0; parameter INTERFACE_TYPE = "NETWORKING"; parameter DATA_RATE = "DDR"; parameter DATA_WIDTH = 4; parameter SERDES_MODE = "MASTER"; parameter NUM_CE = 2; parameter INIT_Q1 = 0; parameter INIT_Q2 = 0; parameter INIT_Q3 = 0; parameter INIT_Q4 = 0; parameter SRVAL_Q1 = 0; parameter SRVAL_Q2 = 0; parameter SRVAL_Q3 = 0; parameter SRVAL_Q4 = 0; parameter IS_D_INVERTED = 0; parameter IS_OCLK_INVERTED = 0; parameter IS_OCLKB_INVERTED = 0; parameter IS_CLK_INVERTED = 0; parameter IS_CLKB_INVERTED = 0; parameter IS_CLKDIV_INVERTED = 0; parameter IS_CLKDIVP_INVERTED = 0; parameter DYN_CLKDIV_INV_EN = "FALSE"; parameter DYN_CLK_INV_EN = "FALSE"; parameter IOBDELAY = "NONE"; parameter OFB_USED = "FALSE"; parameter DDR_CLK_EDGE = "OPPOSITE_EDGE"; parameter SRTYPE = "ASYNC"; parameter CE1USED = 0; parameter SR_MODE = "NONE"; parameter IS_C_INVERTED = 0; wire [8:0] x; wire ddly; (* KEEP, DONT_TOUCH *) generate if (IS_USED && USE_IDELAY) begin // IDELAY (* LOC=IDELAY_LOC, KEEP, DONT_TOUCH *) IDELAYE2 idelay ( .C(clk), .REGRST(), .LD(), .CE(), .INC(), .CINVCTRL(), .CNTVALUEIN(), .IDATAIN(I), .DATAIN(), .LDPIPEEN(), .DATAOUT(ddly), .CNTVALUEOUT() ); end else begin assign ddly = 0; end endgenerate (* KEEP, DONT_TOUCH *) generate if (IS_USED && BEL_TYPE == "ISERDESE2") begin // ISERDES (* LOC=SITE_LOC, KEEP, DONT_TOUCH *) ISERDESE2 # ( .INTERFACE_TYPE(INTERFACE_TYPE), .DATA_RATE(DATA_RATE), .DATA_WIDTH(DATA_WIDTH), .SERDES_MODE(SERDES_MODE), .NUM_CE(NUM_CE), .IS_D_INVERTED(IS_D_INVERTED), .IS_OCLK_INVERTED(IS_OCLK_INVERTED), .IS_OCLKB_INVERTED(IS_OCLKB_INVERTED), .IS_CLK_INVERTED(IS_CLK_INVERTED), .IS_CLKB_INVERTED(IS_CLKB_INVERTED), .IS_CLKDIV_INVERTED(IS_CLKDIV_INVERTED), .IS_CLKDIVP_INVERTED(IS_CLKDIVP_INVERTED), .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), .IOBDELAY(IOBDELAY), .OFB_USED(OFB_USED) ) isedres ( .D(I), .DDLY(), .OFB(), //.TFB(), .CE1(), .CE2(), .DYNCLKSEL(), .CLK(clk1), .CLKB(clk2), .OCLK(), .OCLKB(), .DYNCLKDIVSEL(), .CLKDIV(), .CLKDIVP(), .RST(), .BITSLIP(), .O(x[8]), .Q1(x[0]), .Q2(x[1]), .Q3(x[2]), .Q4(x[3]), .Q5(x[4]), .Q6(x[5]), .Q7(x[6]), .Q8(x[7]), .SHIFTIN1(shiftin[0]), .SHIFTIN2(shiftin[1]), .SHIFTOUT1(shiftout[0]), .SHIFTOUT2(shiftout[1]) ); end else if (IS_USED && BEL_TYPE == "IDDR") begin // IDDR (* LOC=SITE_LOC, KEEP, DONT_TOUCH *) IDDR # ( .IS_C_INVERTED(IS_C_INVERTED), .IS_D_INVERTED(IS_D_INVERTED), .DDR_CLK_EDGE(DDR_CLK_EDGE), .INIT_Q1(INIT_Q1), .INIT_Q2(INIT_Q2), .SRTYPE(SRTYPE) ) iddr ( .C(clk1), .CE( (CE1USED) ? ce : 1'hx ), .D( (IFFDELMUX) ? ddly : I ), .S( (SR_MODE == "SET") ? rst : 1'd0 ), .R( (SR_MODE == "RST") ? rst : 1'd0 ), .Q1(x[0]), .Q2(x[1]) ); assign x[8] = (IDELMUX) ? ddly : I; assign x[7:2] = 0; end else if (IS_USED && BEL_TYPE == "IDDR_NO_CLK") begin // IDDR (* LOC=SITE_LOC, KEEP, DONT_TOUCH *) IDDR # ( .IS_C_INVERTED(IS_C_INVERTED), .IS_D_INVERTED(IS_D_INVERTED), .DDR_CLK_EDGE(DDR_CLK_EDGE), .INIT_Q1(INIT_Q1), .INIT_Q2(INIT_Q2), .SRTYPE(SRTYPE) ) iddr ( .C(), .CE( (CE1USED) ? ce : 1'hx ), .D( (IFFDELMUX) ? ddly : I ), .S( (SR_MODE == "SET") ? rst : 1'd0 ), .R( (SR_MODE == "RST") ? rst : 1'd0 ), .Q1(x[0]), .Q2(x[1]) ); assign x[8] = (IDELMUX) ? ddly : I; assign x[7:2] = 0; end else begin assign x[0] = I; assign x[1] = I; assign x[2] = I; assign x[3] = I; assign x[4] = I; assign x[5] = I; assign x[6] = I; assign x[7] = I; assign x[8] = I; end endgenerate // Output assign O = |x; endmodule ''')
def use_direct_and_iddr(p, luts, connects): p['mux_config'] = random.choice(( 'direct', 'idelay', 'none', )) p['iddr_mux_config'] = random.choice(( 'direct', 'idelay', 'none', )) if p['iddr_mux_config'] != 'none': p['INIT_Q1'] = random.randint(0, 1) p['INIT_Q2'] = random.randint(0, 1) p['IS_C_INVERTED'] = random.randint(0, 1) p['IS_D_INVERTED'] = random.randint(0, 1) p['SRTYPE'] = verilog.quote(random.choice(('SYNC', 'ASYNC'))) p['DDR_CLK_EDGE'] = verilog.quote( random.choice(( 'OPPOSITE_EDGE', 'SAME_EDGE', 'SAME_EDGE_PIPELINED', ))) print(''' (* KEEP, DONT_TOUCH, LOC = "{ilogic_loc}" *) IDDR #( .IS_D_INVERTED({IS_D_INVERTED}), .IS_C_INVERTED({IS_C_INVERTED}), .INIT_Q1({INIT_Q1}), .INIT_Q2({INIT_Q2}), .SRTYPE({SRTYPE}), .DDR_CLK_EDGE({DDR_CLK_EDGE}) ) iddr_{site} ( .C({cnet}), .D(iddr_d_{site}), .Q1({q1}), .Q2({q2}) ); '''.format(cnet=luts.get_next_output_net(), q1=luts.get_next_input_net(), q2=luts.get_next_input_net(), **p), file=connects) if p['iddr_mux_config'] == 'idelay' or p['mux_config'] == 'idelay' or p[ 'iddr_mux_config'] == 'tristate_feedback': print(""" wire idelay_{site}; (* KEEP, DONT_TOUCH, LOC = "{idelay_loc}" *) IDELAYE2 #( ) idelay_site_{site} ( .IDATAIN({iwire}), .DATAOUT(idelay_{site}) );""".format(**p), file=connects) print(""" assign {owire} = {onet}; assign {twire} = {tnet}; """.format(onet=luts.get_next_output_net(), tnet=luts.get_next_output_net(), **p), file=connects) if p['iddr_mux_config'] == 'direct': print(''' assign iddr_d_{site} = {iwire};'''.format(**p, ), file=connects) elif p['iddr_mux_config'] == 'idelay': print(''' assign iddr_d_{site} = idelay_{site};'''.format(**p, ), file=connects) elif p['iddr_mux_config'] == 'tristate_feedback': print(''' assign iddr_d_{site} = tfb_{site} ? ofb_{site} : idelay_{site};'''.format( **p, ), file=connects) elif p['iddr_mux_config'] == 'none': pass else: assert False, p['mux_config'] if p['mux_config'] == 'direct': print(''' assign {net} = {iwire};'''.format( net=luts.get_next_input_net(), **p, ), file=connects) elif p['mux_config'] == 'idelay': print(''' assign {net} = idelay_{site};'''.format( net=luts.get_next_input_net(), **p, ), file=connects) elif p['mux_config'] == 'none': pass else: assert False, p['mux_config']
def run(): segmk = Segmaker("design.bits", verbose=True) print("Loading tags") with open('params.json', 'r') as fp: data = json.load(fp) used_dsps = set() for params in data['instances']: dsp = "DSP_0" if params['SITE'][-1] in "02468" else "DSP_1" site = params['SITE'] if params['USE_DPORT'] == quote( "TRUE") and params['USE_MULT'] != quote("NONE"): add(segmk, site, dsp, 'ADREG', 0, to_int(params['ADREG']), 1) add(segmk, site, dsp, 'ALUMODEREG', 0, to_int(params['ALUMODEREG']), 1) if params['A_INPUT'] == quote("DIRECT"): add(segmk, site, dsp, 'AREG_0', 0, int(to_int(params['AREG']) == 0), 0, False) add(segmk, site, dsp, 'AREG_2', 0, int(to_int(params['AREG']) == 2), 0, False) if params['B_INPUT'] == quote("DIRECT"): add(segmk, site, dsp, 'BREG_0', 0, int(to_int(params['BREG']) == 0), 0, False) add(segmk, site, dsp, 'BREG_2', 0, int(to_int(params['BREG']) == 2), 0, False) if params['A_INPUT'] == quote("CASCADE"): add( segmk, site, dsp, 'AREG_2_ACASCREG_1', 0, int( to_int(params['AREG']) == 2 and to_int(params['ACASCREG']) == 1), 0, False) add( segmk, site, dsp, 'AREG_2_ACASCREG_1', 0, int( to_int(params['AREG']) == 2 and to_int(params['ACASCREG']) == 1), 1, False) if params['B_INPUT'] == quote("CASCADE"): add( segmk, site, dsp, 'BREG_2_BCASCREG_1', 0, int( to_int(params['BREG']) == 2 and to_int(params['BCASCREG']) == 1), 0, False) add( segmk, site, dsp, 'BREG_2_BCASCREG_1', 0, int( to_int(params['BREG']) == 2 and to_int(params['BCASCREG']) == 1), 1, False) add(segmk, site, dsp, 'CARRYINREG', 0, to_int(params['CARRYINREG']), 1) add(segmk, site, dsp, 'CARRYINSELREG', 0, to_int(params['CARRYINSELREG']), 1) add(segmk, site, dsp, 'CREG', 0, to_int(params['CREG']), 1) if params['USE_DPORT'] == quote( "TRUE") and params['USE_MULT'] != quote("NONE"): add(segmk, site, dsp, 'DREG', 0, to_int(params['DREG']), 1) add(segmk, site, dsp, 'INMODEREG', 0, to_int(params['INMODEREG']), 1) add(segmk, site, dsp, 'OPMODEREG', 0, to_int(params['OPMODEREG']), 1) add(segmk, site, dsp, 'PREG', 0, to_int(params['PREG']), 1) INPUT = {} INPUT[quote('DIRECT')] = 0 INPUT[quote('CASCADE')] = 1 add(segmk, site, dsp, 'A_INPUT', 0, INPUT[params['A_INPUT']], 0) add(segmk, site, dsp, 'B_INPUT', 0, INPUT[params['B_INPUT']], 0) BOOL = {} BOOL[quote('FALSE')] = 0 BOOL[quote('TRUE')] = 1 add(segmk, site, dsp, 'USE_DPORT', 0, BOOL[params['USE_DPORT']], 0) add(segmk, site, dsp, 'USE_SIMD_FOUR12', 0, params['USE_SIMD'] == quote("FOUR12"), 0, False) add(segmk, site, dsp, 'USE_SIMD_FOUR12_TWO24', 0, params['USE_SIMD'] in (quote("TWO24"), quote("FOUR12")), 0, False) MULT = {} MULT[quote('NONE')] = 0 MULT[quote('MULTIPLY')] = 1 MULT[quote('DYNAMIC')] = 2 for i in range(2): add(segmk, site, dsp, 'USE_MULT', i, MULT[params['USE_MULT']], 0) add(segmk, site, dsp, 'MREG', 0, to_int(params['MREG']), 1) AUTORESET = {} AUTORESET[quote('NO_RESET')] = 0 AUTORESET[quote('RESET_NOT_MATCH')] = 1 AUTORESET[quote('RESET_MATCH')] = 2 add(segmk, site, dsp, 'AUTORESET_PATDET_RESET_NOT_MATCH', 0, params['AUTORESET_PATDET'] == quote("RESET_NOT_MATCH"), 0, False) add( segmk, site, dsp, 'AUTORESET_PATDET_RESET', 0, params['AUTORESET_PATDET'] in (quote("RESET_NOT_MATCH"), quote("RESET_MATCH")), 0, False) for i in range(48): add(segmk, site, dsp, 'MASK', i, to_int(params['MASK']), 0) for i in range(48): add(segmk, site, dsp, 'PATTERN', i, to_int(params['PATTERN']), 0) if params['USE_PATTERN_DETECT'] == quote("PATDET"): add_site_group_zero(segmk, site, dsp + ".", [ "SEL_MASK_%s" % x for x in ["MASK", "C", "ROUNDING_MODE1", "ROUNDING_MODE2"] ], "SEL_MASK_MASK", "SEL_MASK_%s" % (params['SEL_MASK'][1:-1])) USE_PATTERN_DETECT = {} USE_PATTERN_DETECT[quote('NO_PATDET')] = 0 USE_PATTERN_DETECT[quote('PATDET')] = 1 add(segmk, site, dsp, 'USE_PATTERN_DETECT', 0, USE_PATTERN_DETECT[params['USE_PATTERN_DETECT']], 0) inv_ports = [ ("ALUMODE", 4), ("CARRYIN", 1), ("CLK", 1), ("INMODE", 5), ("OPMODE", 7), ] for port, width in inv_ports: param = 'IS_{}_INVERTED'.format(port) for i in range(width): add(segmk, site, dsp, param, i, to_int(params[param]), 1, width > 1) segmk.compile() segmk.write()
def gen_true_false(p): if random.random() <= p: return verilog.quote("TRUE") else: return verilog.quote("FALSE")
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 main(): """ BUFHCE's can be driven from: MMCME2_ADV PLLE2_ADV BUFGCTRL Local INT connect PS7 (Zynq) """ print(''' // SEED={} module top(); '''.format(os.getenv('SEED'))) is_zynq = os.getenv('XRAY_DATABASE') == 'zynq7' clock_sources = ClockSources() site_to_cmt = dict(read_site_to_cmt()) if is_zynq: pss_clocks = list(read_pss_clocks()) # To ensure that all left or right sources are used, sometimes only MMCM/PLL # sources are allowed. The force of ODD/EVEN/BOTH further biases the # clock sources to the left or right column inputs. mmcm_pll_only = random.randint(0, 1) mmcm_pll_dir = random.choice(('ODD', 'EVEN', 'BOTH', 'NONE')) todos = read_todo() if only_gclk_left(todos): mmcm_pll_dir = 'NONE' if not mmcm_pll_only: if need_int_connections(todos): for _ in range(10): clock_sources.add_clock_source('one', 'ANY') clock_sources.add_clock_source('zero', 'ANY') print(""" wire zero = 0; wire one = 1;""") for loc, _, site in gen_sites('MMCME2_ADV'): mmcm_clocks = [ 'mmcm_clock_{site}_{idx}'.format(site=site, idx=idx) for idx in range(13) ] if check_allowed(mmcm_pll_dir, site_to_cmt[site]): for clk in mmcm_clocks: clock_sources.add_clock_source(clk, site_to_cmt[site], loc) print(""" wire {c0}, {c1}, {c2}, {c3}, {c4}, {c5}; (* KEEP, DONT_TOUCH, LOC = "{site}" *) MMCME2_ADV pll_{site} ( .CLKOUT0({c0}), .CLKOUT0B({c1}), .CLKOUT1({c2}), .CLKOUT1B({c3}), .CLKOUT2({c4}), .CLKOUT2B({c5}), .CLKOUT3({c6}), .CLKOUT3B({c7}), .CLKOUT4({c8}), .CLKOUT5({c9}), .CLKOUT6({c10}), .CLKFBOUT({c11}), .CLKFBOUTB({c12}) ); """.format( site=site, c0=mmcm_clocks[0], c1=mmcm_clocks[1], c2=mmcm_clocks[2], c3=mmcm_clocks[3], c4=mmcm_clocks[4], c5=mmcm_clocks[5], c6=mmcm_clocks[6], c7=mmcm_clocks[7], c8=mmcm_clocks[8], c9=mmcm_clocks[9], c10=mmcm_clocks[10], c11=mmcm_clocks[11], c12=mmcm_clocks[12], )) for loc, _, site in gen_sites('PLLE2_ADV'): pll_clocks = [ 'pll_clock_{site}_{idx}'.format(site=site, idx=idx) for idx in range(6) ] if check_allowed(mmcm_pll_dir, site_to_cmt[site]): for clk in pll_clocks: clock_sources.add_clock_source(clk, site_to_cmt[site], loc) print(""" wire {c0}, {c1}, {c2}, {c3}, {c4}, {c5}; (* KEEP, DONT_TOUCH, LOC = "{site}" *) PLLE2_ADV pll_{site} ( .CLKOUT0({c0}), .CLKOUT1({c1}), .CLKOUT2({c2}), .CLKOUT3({c3}), .CLKOUT4({c4}), .CLKOUT5({c5}) ); """.format( site=site, c0=pll_clocks[0], c1=pll_clocks[1], c2=pll_clocks[2], c3=pll_clocks[3], c4=pll_clocks[4], c5=pll_clocks[5], )) for loc, _, site in gen_sites('BUFR'): clock_sources.add_bufg_clock_source('O_{site}'.format(site=site), site_to_cmt[site], loc) print(""" wire O_{site}; (* KEEP, DONT_TOUCH, LOC = "{site}" *) BUFR bufr_{site} ( .O(O_{site}) );""".format(site=site)) if is_zynq: # FCLK clocks. Those are generated by the PS and go directly to one of # the CLK_HROW tile. clocks = [ "PSS_FCLKCLK0", "PSS_FCLKCLK1", "PSS_FCLKCLK2", "PSS_FCLKCLK3", ] loc, _, site = next(gen_sites('PS7')) print("") # Add clock sources and generate wires for wire in clocks: clock_info = [d for d in pss_clocks if d["pin"] == wire][0] # CMT tile cmt_tile = clock_info["tile"] cmt_loc = get_cmt_loc(cmt_tile) # Add only if the input wire is in the todo list dsts = [k for k, v in todos.items() if clock_info["wire"] in v] if len(dsts) > 0: # Wire source clock region. The PS7 is always left of the # CLK_HROW tile, but it does not matter here. regions = clock_info["clock_regions"].split() regions = sorted([(int(r[1]), int(r[3])) for r in regions]) # Add the clock source cmt = "X{}Y{}".format(regions[0][0], regions[0][1]) clock_sources.add_clock_source(wire, cmt, cmt_loc) print(" wire {};".format(wire)) print(""" (* KEEP, DONT_TOUCH, LOC = "{site}" *) PS7 ps7_{site} ( .FCLKCLK({{{fclk3}, {fclk2}, {fclk1}, {fclk0}}}) ); """.format(site=site, fclk0=clocks[0], fclk1=clocks[1], fclk2=clocks[2], fclk3=clocks[3])) luts = LutMaker() bufhs = StringIO() bufgs = StringIO() gclks = [] for _, _, site in sorted(gen_sites("BUFGCTRL"), key=lambda x: BUFGCTRL_XY_FUN(x[2])): wire_name = 'gclk_{}'.format(site) gclks.append(wire_name) include_source = True if mmcm_pll_only: include_source = False elif only_gclk_left(todos): include_source = need_gclk_connection(todos, site) if include_source: clock_sources.add_clock_source(wire_name, 'ANY') print(""" wire {wire_name}; """.format(wire_name=wire_name)) print(""" wire I1_{site}; wire I0_{site}; (* KEEP, DONT_TOUCH, LOC = "{site}" *) BUFGCTRL bufg_{site} ( .O({wire_name}), .S1({s1net}), .S0({s0net}), .IGNORE1({ignore1net}), .IGNORE0({ignore0net}), .I1(I1_{site}), .I0(I0_{site}), .CE1({ce1net}), .CE0({ce0net}) ); """.format( site=site, wire_name=wire_name, s1net=luts.get_next_output_net(), s0net=luts.get_next_output_net(), ignore1net=luts.get_next_output_net(), ignore0net=luts.get_next_output_net(), ce1net=luts.get_next_output_net(), ce0net=luts.get_next_output_net(), ), file=bufgs) any_bufhce = False for tile_name, sites in gen_bufhce_sites(): for site in sites: if not bufhce_in_todo(todos, site): continue any_bufhce = True print(""" wire I_{site}; (* KEEP, DONT_TOUCH, LOC = "{site}" *) BUFHCE buf_{site} ( .I(I_{site}) ); """.format(site=site, ), file=bufhs) if random.random() > .05: wire_name = clock_sources.get_random_source(site_to_cmt[site]) if wire_name is None: continue print(""" assign I_{site} = {wire_name};""".format( site=site, wire_name=wire_name, ), file=bufhs) if not any_bufhce: for tile_name, sites in gen_bufhce_sites(): for site in sites: print(""" (* KEEP, DONT_TOUCH, LOC = "{site}" *) BUFHCE #( .INIT_OUT({INIT_OUT}), .CE_TYPE({CE_TYPE}), .IS_CE_INVERTED({IS_CE_INVERTED}) ) buf_{site} ( .I({wire_name}) ); """.format( INIT_OUT=random.randint(0, 1), CE_TYPE=verilog.quote(random.choice(('SYNC', 'ASYNC'))), IS_CE_INVERTED=random.randint(0, 1), site=site, wire_name=gclks[0], )) break break for l in luts.create_wires_and_luts(): print(l) print(bufhs.getvalue()) print(bufgs.getvalue()) used_only = random.random() < .25 for loc, tile_type, site in sorted(gen_sites("BUFGCTRL"), key=lambda x: BUFGCTRL_XY_FUN(x[2])): if random.randint(0, 1): wire_name = clock_sources.get_bufg_source(loc, tile_type, site, todos, 1, used_only) if wire_name is not None: print(""" assign I1_{site} = {wire_name};""".format( site=site, wire_name=wire_name, )) if random.randint(0, 1): wire_name = clock_sources.get_bufg_source(loc, tile_type, site, todos, 0, used_only) if wire_name is not None: print(""" assign I0_{site} = {wire_name};""".format( site=site, wire_name=wire_name, )) print("endmodule")
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 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 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 run(): print("module top();") clocks = ClockSources() clocks.init_clocks() """ ISERDESE2 clock sources: CLK/CLKB: - Allows LEAF_GCLK, IOCLKS, RCLKS and fabric - Dedicated pips CLKDIV: - No dedicated pips, uses fabric clock in. CLKDIVP: - Has pips, MIG only, PHASER or fabric. OCLK/OCLKB: - Allows LEAF_GCLK, IOCLKS, RCLKS and fabric - Must match OSERDESE2:CLK/CLKB OSERDESE2 clock sources: CLKDIV/CLKDIVB: - Allows LEAF_GCLK and RCLKS and fabric - Dedicated pips CLKDIVF/CLKDIVFB: - Allows LEAF_GCLK and RCLKS and fabric - No explicit port, follows CLKDIV/CLKDIVB? """ output = [] for tile in gen_sites(): if tile['tile_type'] in NOT_INCLUDED_TILES: continue for xy in tile['ioi_sites']: ilogic_site_type = random.choice([None, 'ISERDESE2', 'IDDR']) use_oserdes = random.randint(0, 1) ilogic_site = tile['ioi_sites'][xy]['ILOGICE3'] ologic_site = tile['ioi_sites'][xy]['OLOGICE3'] if use_oserdes: oclk, _ = clocks.get_clock( ologic_site, allow_ioclks=True, allow_rclks=True) oclkb = oclk else: oclk, is_lut = clocks.get_clock( ilogic_site, allow_ioclks=True, allow_rclks=True) if random.randint(0, 1): oclkb = oclk else: if random.randint(0, 1): oclkb, _ = clocks.get_clock( ilogic_site, allow_ioclks=True, allow_rclks=True, allow_fabric=not is_lut) else: # Explicitly provide IMUX stimulus to resolve IMUX pips oclk = random.randint(0, 1) oclkb = random.randint(0, 1) DATA_RATE = random.choice(['DDR', 'SDR']) clk, is_lut = clocks.get_clock( ilogic_site, allow_ioclks=True, allow_rclks=True, allow_empty=DATA_RATE == 'SDR') if False: clkb = clk else: clkb = clk if random.randint(0, 1): while clkb == clk: clkb, _ = clocks.get_clock( ilogic_site, allow_ioclks=True, allow_rclks=True, allow_empty=False) else: # Explicitly provide IMUX stimulus to resolve IMUX pips clk = random.randint(0, 1) clkb = random.randint(0, 1) if ilogic_site_type is None: pass elif ilogic_site_type == 'ISERDESE2': INTERFACE_TYPE = random.choice( [ 'MEMORY', 'MEMORY_DDR3', 'MEMORY_QDR', 'NETWORKING', 'OVERSAMPLE', ]) ports = [] add_port(ports, 'CLK', clk) add_port(ports, 'CLKB', clkb) add_port(ports, 'OCLK', oclk) add_port(ports, 'OCLKB', oclkb) output.append( """ (* KEEP, DONT_TOUCH, LOC="{site}" *) ISERDESE2 #( .DATA_RATE({DATA_RATE}), .INTERFACE_TYPE({INTERFACE_TYPE}), .IS_CLK_INVERTED({IS_CLK_INVERTED}), .IS_CLKB_INVERTED({IS_CLKB_INVERTED}), .IS_OCLK_INVERTED({IS_OCLK_INVERTED}), .IS_OCLKB_INVERTED({IS_OCLKB_INVERTED}), .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}) ) iserdes_{site}( {ports});""".format( site=ilogic_site, ports=',\n'.join(ports), DATA_RATE=verilog.quote(DATA_RATE), INTERFACE_TYPE=verilog.quote(INTERFACE_TYPE), IS_CLK_INVERTED=random.randint(0, 1), IS_CLKB_INVERTED=random.randint(0, 1), IS_OCLK_INVERTED=random.randint(0, 1), IS_OCLKB_INVERTED=random.randint(0, 1), 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), )) elif ilogic_site_type == 'IDDR': ports = [] add_port(ports, 'C', clk) add_port(ports, 'CB', clkb) output.append( """ (* KEEP, DONT_TOUCH, LOC="{site}" *) IDDR_2CLK #( .INIT_Q1({INIT_Q1}), .INIT_Q2({INIT_Q2}), .SRTYPE({SRTYPE}) ) iserdes_{site}( {ports});""".format( site=ilogic_site, ports=',\n'.join(ports), INIT_Q1=random.randint(0, 1), INIT_Q2=random.randint(0, 1), SRTYPE=verilog.quote(random.choice(['ASYNC', 'SYNC'])), )) else: assert False, ilogic_site_type if use_oserdes: ports = [] add_port( ports, 'CLKDIV', clocks.get_clock( ologic_site, allow_ioclks=False, allow_rclks=True, )[0]) add_port(ports, 'CLK', oclk) output.append( """ (* KEEP, DONT_TOUCH, LOC = "{site}" *) OSERDESE2 #( .IS_CLK_INVERTED({IS_CLK_INVERTED}), .DATA_RATE_OQ("SDR"), .DATA_RATE_TQ("SDR") ) oserdes_{site} ( {ports});""".format( IS_CLK_INVERTED=random.randint(0, 1), site=ologic_site, ports=',\n'.join(ports), )) for s in clocks.lut_maker.create_wires_and_luts(): print(s) for s in output: print(s) print("endmodule")
def main(): print(''' module top( input wire in, output wire out ); assign out = in; ''') luts = LutMaker() params_dict = {"tile_type": None} params_list = list() clkswing_cfg_tiles = dict() ibufds_out_wires = dict() for tile_name, _, site_name, _ in gen_sites("GTP_COMMON", "IBUFDS_GTE2"): # Both the IBUFDS_GTE2 in the same tile need to have # the same CLKSWING_CFG parameter if tile_name not in clkswing_cfg_tiles: clkswing_cfg = random.randint(0, 3) clkswing_cfg_tiles[tile_name] = clkswing_cfg else: clkswing_cfg = clkswing_cfg_tiles[tile_name] in_use = bool(random.randint(0, 9)) params = { "site": site_name, "tile": tile_name, "IN_USE": in_use, "CLKRCV_TRST": verilog.quote("TRUE" if random.randint(0, 1) else "FALSE"), "CLKCM_CFG": verilog.quote("TRUE" if random.randint(0, 1) else "FALSE"), "CLKSWING_CFG": clkswing_cfg, } if in_use: ibufds_out_wire = "{}_O".format(site_name) if tile_name not in ibufds_out_wires: ibufds_out_wires[tile_name] = list() ibufds_out_wires[tile_name].append( (ibufds_out_wire, int(site_name[-1]) % 2)) print("wire {};".format(ibufds_out_wire)) print("(* KEEP, DONT_TOUCH, LOC=\"{}\" *)".format(site_name)) print(""" IBUFDS_GTE2 #( .CLKRCV_TRST({CLKRCV_TRST}), .CLKCM_CFG({CLKCM_CFG}), .CLKSWING_CFG({CLKSWING_CFG}) ) {site} ( .O({out}) );""".format(**params, out=ibufds_out_wire)) params_list.append(params) DRP_PORTS = [("DRPCLK", "clk"), ("DRPEN", "in"), ("DRPWE", "in"), ("DRPRDY", "out")] for tile_name, tile_type, site_name, cmt in gen_sites( "GTP_COMMON", "GTPE2_COMMON"): params_dict["tile_type"] = tile_type params = dict() params['site'] = site_name params['tile'] = tile_name verilog_attr = "" verilog_attr = "#(" fuz_dir = os.getenv("FUZDIR", None) assert fuz_dir with open(os.path.join(fuz_dir, "attrs.json"), "r") as attrs_file: attrs = json.load(attrs_file) in_use = bool(random.randint(0, 9)) params["IN_USE"] = in_use if in_use: for param, param_info in attrs.items(): param_type = param_info["type"] param_values = param_info["values"] param_digits = param_info["digits"] if param_type == INT: value = random.choice(param_values) value_str = value else: assert param_type == BIN value = random.randint(0, param_values[0]) value_str = "{digits}'b{value:0{digits}b}".format( value=value, digits=param_digits) params[param] = value verilog_attr += """ .{}({}),""".format(param, value_str) for param in ["PLL0LOCKDETCLK", "PLL1LOCKDETCLK", "DRPCLK"]: is_inverted = random.randint(0, 1) params[param] = is_inverted verilog_attr += """ .IS_{}_INVERTED({}),""".format(param, is_inverted) verilog_attr = verilog_attr.rstrip(",") verilog_attr += "\n)" verilog_ports = "" for param in [ "GTREFCLK0_USED", "GTREFCLK1_USED", "BOTH_GTREFCLK_USED" ]: params[param] = 0 if tile_name in ibufds_out_wires: gtrefclk_ports_used = 0 for wire, location in ibufds_out_wires[tile_name]: if random.random() < 0.5: continue verilog_ports += """ .GTREFCLK{}({}),""".format(location, wire) gtrefclk_ports_used += 1 params["GTREFCLK{}_USED".format(location)] = 1 if gtrefclk_ports_used == 2: params["BOTH_GTREFCLK_USED"] = 1 enable_drp = random.randint(0, 1) params["ENABLE_DRP"] = enable_drp for _, _, channel_site_name, _ in gen_sites( "GTP_CHANNEL", "GTPE2_CHANNEL", cmt): if not enable_drp: break verilog_ports_channel = "" for port, direction in DRP_PORTS: if direction == "in": verilog_ports_channel += """ .{}({}),""".format(port, luts.get_next_output_net()) elif direction == "clk": # DRPCLK needs to come from a clock source print(""" wire clk_bufg_{site}; (* KEEP, DONT_TOUCH *) BUFG bufg_{site} (.O(clk_bufg_{site}));""".format(site=channel_site_name)) verilog_ports_channel += """ .{}(clk_bufg_{}),""".format(port, channel_site_name) elif direction == "out": verilog_ports_channel += """ .{}({}),""".format(port, luts.get_next_input_net()) print(""" (* KEEP, DONT_TOUCH, LOC=\"{site}\" *) GTPE2_CHANNEL {site} ( {ports} );""".format(ports=verilog_ports_channel.rstrip(","), site=channel_site_name)) print(""" (* KEEP, DONT_TOUCH, LOC=\"{site}\" *) GTPE2_COMMON {attrs} {site} ( {ports} );""".format(attrs=verilog_attr, ports=verilog_ports.rstrip(","), site=site_name)) params_list.append(params) for l in luts.create_wires_and_luts(): print(l) print("endmodule") params_dict["params"] = params_list with open('params.json', 'w') as f: json.dump(params_dict, f, indent=2)
def main(): db = Database(util.get_db_root(), util.get_part()) grid = db.grid() print(''' module top(); ''') params = [] for tile_name, bram36_site_name, bram18_site_name, fifo18_site_name in gen_bram36( grid): if random.random() < .8: ram_extension_a = random.choice(RAM_EXTENSION_OPTS) ram_extension_b = random.choice(RAM_EXTENSION_OPTS) en_ecc_read = random.randint(0, 1) en_ecc_write = random.randint(0, 1) print(''' (* KEEP, DONT_TOUCH, LOC = "{site}" *) RAMB36E1 #( .READ_WIDTH_A(1), .WRITE_WIDTH_A(1), .READ_WIDTH_B(1), .WRITE_WIDTH_B(1), .RAM_EXTENSION_A({ram_extension_a}), .RAM_EXTENSION_B({ram_extension_b}), .EN_ECC_READ({en_ecc_read}), .EN_ECC_WRITE({en_ecc_write}) ) bram_{site} ( .CLKARDCLK(), .CLKBWRCLK(), .ENARDEN(), .ENBWREN(), .REGCEAREGCE(), .REGCEB(), .RSTRAMARSTRAM(), .RSTRAMB(), .RSTREGARSTREG(), .RSTREGB(), .ADDRARDADDR(), .ADDRBWRADDR(), .DIADI(), .DIBDI(), .DIPADIP(), .DIPBDIP(), .WEA(), .WEBWE(), .DOADO(), .DOBDO(), .DOPADOP(), .DOPBDOP()); '''.format( site=bram36_site_name, ram_extension_a=verilog.quote(ram_extension_a), ram_extension_b=verilog.quote(ram_extension_b), en_ecc_read=en_ecc_read, en_ecc_write=en_ecc_write, )) params.append({ 'tile': tile_name, 'BRAM36_IN_USE': True, 'site': bram36_site_name, 'RAM_EXTENSION_A': ram_extension_a, 'RAM_EXTENSION_B': ram_extension_b, 'EN_ECC_READ': en_ecc_read, 'EN_ECC_WRITE': en_ecc_write, }) else: print(''' (* KEEP, DONT_TOUCH, LOC = "{bram18}" *) RAMB18E1 #( .READ_WIDTH_A(1), .WRITE_WIDTH_A(1), .READ_WIDTH_B(1), .WRITE_WIDTH_B(1) ) bram_{bram18} ( .CLKARDCLK(), .CLKBWRCLK(), .ENARDEN(), .ENBWREN(), .REGCEAREGCE(), .REGCEB(), .RSTRAMARSTRAM(), .RSTRAMB(), .RSTREGARSTREG(), .RSTREGB(), .ADDRARDADDR(), .ADDRBWRADDR(), .DIADI(), .DIBDI(), .DIPADIP(), .DIPBDIP(), .WEA(), .WEBWE(), .DOADO(), .DOBDO(), .DOPADOP(), .DOPBDOP()); (* KEEP, DONT_TOUCH, LOC = "{fifo18}" *) RAMB18E1 #( .READ_WIDTH_A(1), .WRITE_WIDTH_A(1), .READ_WIDTH_B(1), .WRITE_WIDTH_B(1) ) bram_{fifo18} ( .CLKARDCLK(), .CLKBWRCLK(), .ENARDEN(), .ENBWREN(), .REGCEAREGCE(), .REGCEB(), .RSTRAMARSTRAM(), .RSTRAMB(), .RSTREGARSTREG(), .RSTREGB(), .ADDRARDADDR(), .ADDRBWRADDR(), .DIADI(), .DIBDI(), .DIPADIP(), .DIPBDIP(), .WEA(), .WEBWE(), .DOADO(), .DOBDO(), .DOPADOP(), .DOPBDOP()); '''.format( bram18=bram18_site_name, fifo18=fifo18_site_name, )) params.append({ 'tile': tile_name, 'BRAM36_IN_USE': False, 'site': bram36_site_name, }) print("endmodule") with open('params.json', 'w') as f: json.dump(params, f, indent=2)
def main(): print(''' module top(); ''') params = [] for tile_name, site_name in gen_bram36(): ram_extension_a = random.choice(RAM_EXTENSION_OPTS) ram_extension_b = random.choice(RAM_EXTENSION_OPTS) en_ecc_read = random.randint(0, 1) en_ecc_write = random.randint(0, 1) print(''' (* KEEP, DONT_TOUCH, LOC = "{site}" *) RAMB36E1 #( .READ_WIDTH_A(1), .WRITE_WIDTH_A(1), .READ_WIDTH_B(1), .WRITE_WIDTH_B(1), .RAM_EXTENSION_A({ram_extension_a}), .RAM_EXTENSION_B({ram_extension_b}), .EN_ECC_READ({en_ecc_read}), .EN_ECC_WRITE({en_ecc_write}) ) bram_{site} ( .CLKARDCLK(), .CLKBWRCLK(), .ENARDEN(), .ENBWREN(), .REGCEAREGCE(), .REGCEB(), .RSTRAMARSTRAM(), .RSTRAMB(), .RSTREGARSTREG(), .RSTREGB(), .ADDRARDADDR(), .ADDRBWRADDR(), .DIADI(), .DIBDI(), .DIPADIP(), .DIPBDIP(), .WEA(), .WEBWE(), .DOADO(), .DOBDO(), .DOPADOP(), .DOPBDOP()); '''.format( site=site_name, ram_extension_a=verilog.quote(ram_extension_a), ram_extension_b=verilog.quote(ram_extension_b), en_ecc_read=en_ecc_read, en_ecc_write=en_ecc_write, )) params.append({ 'tile': tile_name, 'site': site_name, 'RAM_EXTENSION_A': ram_extension_a, 'RAM_EXTENSION_B': ram_extension_b, 'EN_ECC_READ': en_ecc_read, 'EN_ECC_WRITE': en_ecc_write, }) print("endmodule") with open('params.json', 'w') as f: json.dump(params, f, indent=2)
def main(): print(''' module top( input wire in, output wire out ); assign out = in; ''') primitives_list = list() for tile_name, tile_type, site_name, site_type in gen_sites( "GTPE2_CHANNEL"): params_list = list() params_dict = dict() params_dict["tile_type"] = tile_type params = dict() params['site'] = site_name verilog_attr = "" verilog_attr = "#(" fuz_dir = os.getenv("FUZDIR", None) assert fuz_dir with open(os.path.join(fuz_dir, "attrs.json"), "r") as attrs_file: attrs = json.load(attrs_file) in_use = bool(random.randint(0, 9)) params["IN_USE"] = in_use if in_use: for param, param_info in attrs.items(): param_type = param_info["type"] param_values = param_info["values"] param_digits = param_info["digits"] if param_type == INT: value = random.choice(param_values) value_str = value elif param_type == BIN: value = random.randint(0, param_values[0]) value_str = "{digits}'b{value:0{digits}b}".format( value=value, digits=param_digits) elif param_type in [BOOL, STR]: value = random.choice(param_values) value_str = verilog.quote(value) params[param] = value verilog_attr += """ .{}({}),""".format(param, value_str) for param in [ "TXUSRCLK", "TXUSRCLK2", "TXPHDLYTSTCLK", "SIGVALIDCLK", "RXUSRCLK", "RXUSRCLK2", "DRPCLK", "DMONITORCLK", "CLKRSVD0", "CLKRSVD1" ]: is_inverted = random.randint(0, 1) params[param] = is_inverted verilog_attr += """ .IS_{}_INVERTED({}),""".format(param, is_inverted) verilog_attr = verilog_attr.rstrip(",") verilog_attr += "\n)" print("(* KEEP, DONT_TOUCH, LOC=\"{}\" *)".format(site_name)) print("""GTPE2_CHANNEL {} {} (); """.format(verilog_attr, tile_type.lower())) params_list.append(params) params_dict["params"] = params_list primitives_list.append(params_dict) print("endmodule") with open('params.json', 'w') as f: json.dump(primitives_list, f, indent=2)
def ramb36(tile_name, luts, lines, sites): """ RAMB36 consuming entire tile. """ params = {} params['tile'] = tile_name params['Y0_IN_USE'] = True params['Y1_IN_USE'] = True params['FIFO_Y0_IN_USE'] = False params['FIFO_Y1_IN_USE'] = False site = sites['RAMBFIFO36E1'] lines.append(""" wire [7:0] webwe_{site}; wire [3:0] wea_{site}; wire regce_{site}; wire [15:0] rdaddr_{site}; wire [15:0] wraddr_{site}; """.format(site=site)) for bit in range(15): lines.append('assign rdaddr_{site}[{bit}] = {net};'.format( bit=bit, site=site, net=luts.get_next_output_net())) lines.append('assign wraddr_{site}[{bit}] = {net};'.format( bit=bit, site=site, net=luts.get_next_output_net())) for bit in range(8): lines.append('assign webwe_{site}[{bit}] = {net};'.format( bit=bit, site=site, net=luts.get_next_output_net())) for bit in range(4): lines.append('assign wea_{site}[{bit}] = {net};'.format( bit=bit, site=site, net=luts.get_next_output_net())) lines.append('assign regce_{site} = {net};'.format( bit=bit, site=site, net=luts.get_next_output_net())) do_reg = verilog.vrandbit() ram_mode = random.choice(('SDP', 'TDP')) READ_WIDTH_A = 0 READ_WIDTH_B = 0 if ram_mode == 'TDP': write_mode_a = random.choice(WRITE_MODES) write_mode_b = random.choice(WRITE_MODES) WRITE_WIDTH_A = 36 WRITE_WIDTH_B = 36 else: write_mode_a = 'WRITE_FIRST' write_mode_b = 'WRITE_FIRST' WRITE_WIDTH_A = 72 WRITE_WIDTH_B = 72 lines.append(''' (* KEEP, DONT_TOUCH, LOC = "{site}" *) RAMB36E1 #( .DOA_REG({doa_reg}), .DOB_REG({dob_reg}), .WRITE_MODE_A({write_mode_a}), .WRITE_MODE_B({write_mode_b}), .READ_WIDTH_A({READ_WIDTH_A}), .READ_WIDTH_B({READ_WIDTH_B}), .WRITE_WIDTH_A({WRITE_WIDTH_A}), .WRITE_WIDTH_B({WRITE_WIDTH_B}), .INIT_A(36'hFF_FFFF_FFFF), .SRVAL_A(36'hFF_FFFF_FFFF), .INIT_B(36'hFF_FFFF_FFFF), .SRVAL_B(36'hFF_FFFF_FFFF), .RAM_MODE({ram_mode}) ) bram_{site} ( .ADDRARDADDR(rdaddr_{site}), .ADDRBWRADDR(wraddr_{site}), .REGCEAREGCE(regce_{site}), .REGCEB(regce_{site}), .WEBWE(webwe_{site}), .WEA(wea_{site}) ); '''.format( site=site, doa_reg=do_reg, dob_reg=do_reg, write_mode_a=verilog.quote(write_mode_a), write_mode_b=verilog.quote(write_mode_b), ram_mode=verilog.quote(ram_mode), READ_WIDTH_A=READ_WIDTH_A, READ_WIDTH_B=READ_WIDTH_B, WRITE_WIDTH_A=WRITE_WIDTH_A, WRITE_WIDTH_B=WRITE_WIDTH_B, )) return params
def run(): segmk = Segmaker("design.bits", verbose=True) print("Loading tags") with open('params.json', 'r') as fp: data = json.load(fp) for params in data['instances']: dsp = "DSP_0" if params['SITE'][-1] in "02468" else "DSP_1" site = params['SITE'] add(segmk, site, dsp, 'ADREG', 0, to_int(params['ADREG']), 0) add(segmk, site, dsp, 'ALUMODEREG', 0, to_int(params['ALUMODEREG']), 1) for i in range(2): add(segmk, site, dsp, 'AREG', i, to_int(params['AREG']), 1) for i in range(2): add(segmk, site, dsp, 'ACASCREG', i, to_int(params['ACASCREG']), 1) for i in range(2): add(segmk, site, dsp, 'BREG', i, to_int(params['BREG']), 1) for i in range(2): add(segmk, site, dsp, 'BCASCREG', i, to_int(params['BCASCREG']), 1) add(segmk, site, dsp, 'CARRYINREG', 0, to_int(params['CARRYINREG']), 1) add( segmk, site, dsp, 'CARRYINSELREG', 0, to_int(params['CARRYINSELREG']), 1) add(segmk, site, dsp, 'CREG', 0, to_int(params['CREG']), 1) add(segmk, site, dsp, 'DREG', 0, to_int(params['DREG']), 0) add(segmk, site, dsp, 'INMODEREG', 0, to_int(params['INMODEREG']), 1) add(segmk, site, dsp, 'OPMODEREG', 0, to_int(params['OPMODEREG']), 1) add(segmk, site, dsp, 'PREG', 0, to_int(params['PREG']), 1) INPUT = {} INPUT[quote('DIRECT')] = 0 INPUT[quote('CASCADE')] = 1 add(segmk, site, dsp, 'A_INPUT', 0, INPUT[params['A_INPUT']], 0) add(segmk, site, dsp, 'B_INPUT', 0, INPUT[params['B_INPUT']], 0) BOOL = {} BOOL[quote('FALSE')] = 0 BOOL[quote('TRUE')] = 1 add(segmk, site, dsp, 'USE_DPORT', 0, BOOL[params['USE_DPORT']], 0) SIMD = {} SIMD[quote('ONE48')] = 0 SIMD[quote('TWO24')] = 1 SIMD[quote('FOUR12')] = 2 for i in range(2): add(segmk, site, dsp, 'USE_SIMD', i, SIMD[params['USE_SIMD']], 0) MULT = {} MULT[quote('NONE')] = 0 MULT[quote('MULTIPLY')] = 1 MULT[quote('DYNAMIC')] = 2 for i in range(2): add(segmk, site, dsp, 'USE_MULT', i, MULT[params['USE_MULT']], 0) add(segmk, site, dsp, 'MREG', 0, to_int(params['MREG']), 1) AUTORESET = {} AUTORESET[quote('NO_RESET')] = 0 AUTORESET[quote('RESET_NOT_MATCH')] = 1 AUTORESET[quote('RESET_MATCH')] = 2 add( segmk, site, dsp, 'AUTORESET_PATDET', 0, AUTORESET[params['AUTORESET_PATDET']], 0) add( segmk, site, dsp, 'AUTORESET_PATDET', 1, AUTORESET[params['AUTORESET_PATDET']], 1) for i in range(48): add(segmk, site, dsp, 'MASK', i, to_int(params['MASK']), 0) for i in range(48): add(segmk, site, dsp, 'PATTERN', i, to_int(params['PATTERN']), 0) SEL_MASK = {} SEL_MASK[quote('MASK')] = 0 SEL_MASK[quote('C')] = 1 SEL_MASK[quote('ROUNDING_MODE1')] = 2 SEL_MASK[quote('ROUNDING_MODE2')] = 3 for i in range(2): add( segmk, site, dsp, 'SEL_MASK', i, SEL_MASK[params['SEL_MASK']], 0) USE_PATTERN_DETECT = {} USE_PATTERN_DETECT[quote('NO_PATDET')] = 0 USE_PATTERN_DETECT[quote('PATDET')] = 1 add( segmk, site, dsp, 'USE_PATTERN_DETECT', 0, USE_PATTERN_DETECT[params['USE_PATTERN_DETECT']], 0) segmk.compile() segmk.write()
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 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)