| #!/usr/bin/env python3 | 
 |  | 
 | import os, sys | 
 |  | 
 | device = "up5k" | 
 |  | 
 | # This script is designed to determine which DSPs have configuration bits | 
 | # not in their usual position, as in some cases DSP and IPConnect tiles have | 
 | # their config bits swapped | 
 |  | 
 | # Unfortunately, arbitrary configurations are not allowed by icecube, so | 
 | # we define a set that gives us maximum coverage (full coverage is not | 
 | # possible as one CBIT is never set) | 
 |  | 
 | allowed_configs = ["1110000010000001001110110", "0010000101000010111111111", "0001111000101100000000000"] | 
 |  | 
 | coverage = set() | 
 | for c in allowed_configs: | 
 |     for i in range(25): | 
 |         if c[i] == "1": | 
 |             coverage.add(i) | 
 |  | 
 | assert len(coverage) >= 24 | 
 |  | 
 | def parse_exp(f): | 
 |     current_x = 0 | 
 |     current_y = 0 | 
 |     bits = set() | 
 |     for line in f: | 
 |         splitline = line.split(' ') | 
 |         if splitline[0].endswith("_tile"): | 
 |             current_x = int(splitline[1]) | 
 |             current_y = int(splitline[2]) | 
 |         elif splitline[0] == "IpConfig": | 
 |             if splitline[1][:5] == "CBIT_": | 
 |                 bitidx = int(splitline[1][5:]) | 
 |                 bits.add((current_x, current_y, bitidx))     | 
 |     return bits | 
 | dsp_locs = [( 0, 5, 0), ( 0, 10, 0), ( 0, 15, 0), ( 0, 23, 0), | 
 |             (25, 5, 0), (25, 10, 0), (25, 15, 0), (25, 23, 0)] | 
 |              | 
 | dsp_data = {} | 
 |  | 
 | if not os.path.exists("./work_dsp_cbit"): | 
 |     os.mkdir("./work_dsp_cbit") | 
 |  | 
 | for loc in dsp_locs: | 
 |     x, y, z = loc | 
 |     missing_bits = set() | 
 |     new_bits = set() | 
 |     for config in allowed_configs: | 
 |         params = config[::-1] | 
 |         with open("./work_dsp_cbit/dsp_cbit.v","w") as f: | 
 |             print(""" | 
 |             module top(input clk, input a, input b, input c, input d, output y); | 
 |             """, file=f) | 
 |             print(""" | 
 |                 SB_MAC16 #( | 
 |                     .C_REG(1'b%s), | 
 |                     .A_REG(1'b%s), | 
 |                     .B_REG(1'b%s), | 
 |                     .D_REG(1'b%s), | 
 |                     .TOP_8x8_MULT_REG(1'b%s), | 
 |                     .BOT_8x8_MULT_REG(1'b%s), | 
 |                     .PIPELINE_16x16_MULT_REG1(1'b%s), | 
 |                     .PIPELINE_16x16_MULT_REG2(1'b%s), | 
 |                     .TOPOUTPUT_SELECT(2'b%s), | 
 |                     .TOPADDSUB_LOWERINPUT(2'b%s), | 
 |                     .TOPADDSUB_UPPERINPUT(1'b%s), | 
 |                     .TOPADDSUB_CARRYSELECT(2'b%s), | 
 |                     .BOTOUTPUT_SELECT(2'b%s), | 
 |                     .BOTADDSUB_LOWERINPUT(2'b%s), | 
 |                     .BOTADDSUB_UPPERINPUT(1'b%s), | 
 |                     .BOTADDSUB_CARRYSELECT(2'b%s), | 
 |                     .MODE_8x8(1'b%s), | 
 |                     .A_SIGNED(1'b%s), | 
 |                     .B_SIGNED(1'b%s) | 
 |                 ) dsp ( | 
 |                     .CLK(clk), | 
 |                     .C(c), | 
 |                     .A(a), | 
 |                     .B(b), | 
 |                     .D(d), | 
 |                     .O(y) | 
 |                 );""" | 
 |                 % ( | 
 |                 params[0], params[1], params[2], params[3], | 
 |                 params[4], params[5], params[6], params[7], | 
 |                 params[8:10][::-1], params[10:12][::-1], params[12], params[13:15][::-1], | 
 |                 params[15:17][::-1], params[17:19][::-1], params[19], params[20:22][::-1], | 
 |                 params[22], params[23], params[24]), file=f) | 
 |             print("endmodule",file=f) | 
 |         with open("./work_dsp_cbit/dsp_cbit.pcf","w") as f: | 
 |             print("set_location dsp %d %d %d" % loc, file=f) | 
 |         retval = os.system("bash ../../icecube.sh -" + device + " ./work_dsp_cbit/dsp_cbit.v > ./work_dsp_cbit/icecube.log 2>&1") | 
 |         if retval != 0: | 
 |             sys.stderr.write('ERROR: icecube returned non-zero error code\n') | 
 |             sys.exit(1) | 
 |         retval = os.system("../../../icebox/icebox_explain.py ./work_dsp_cbit/dsp_cbit.asc > ./work_dsp_cbit/dsp_cbit.exp") | 
 |         if retval != 0: | 
 |             sys.stderr.write('ERROR: icebox_explain returned non-zero error code\n') | 
 |             sys.exit(1) | 
 |         bits = set() | 
 |         known = set() | 
 |         with open('./work_dsp_cbit/dsp_cbit.exp', 'r') as f: | 
 |             bits = parse_exp(f) | 
 |         for i in range(25): | 
 |             if params[i] == "1": | 
 |                 exp_pos = (x, y + (i // 8), i % 8) | 
 |                 if exp_pos not in bits: | 
 |                     missing_bits.add(exp_pos) | 
 |                 else: | 
 |                     known.add(exp_pos) | 
 |         for bit in bits: | 
 |             if bit not in known: | 
 |                 new_bits.add(bit) | 
 |     if len(missing_bits) > 0 or len(new_bits) > 0: | 
 |         print("DSP (%d, %d):" % (x, y)) | 
 |         for bit in missing_bits: | 
 |             print("\tMissing (%d, %d, CBIT_%d)" % bit) | 
 |         for bit in new_bits: | 
 |             print("\tNew: (%d, %d, CBIT_%d)" % bit) | 
 |         dsp_data[loc] = (missing_bits, new_bits) | 
 | with open("dsp_cbits_%s.txt" % device, 'w') as f: | 
 |     for loc in dsp_data: | 
 |         x, y, z = loc | 
 |         missing_bits, new_bits = dsp_data[loc] | 
 |         print("DSP (%d, %d):" % (x, y), file=f) | 
 |         for bit in missing_bits: | 
 |             print("\tMissing (%d, %d, CBIT_%d)" % bit,file=f) | 
 |         for bit in new_bits: | 
 |             print("\tNew: (%d, %d, CBIT_%d)" % bit,file=f) |