| #!/usr/bin/env python3 |
| |
| import os, sys, json, re |
| |
| ####################################### |
| # Read |
| |
| tiles = list() |
| site_baseaddr = dict() |
| tile_baseaddr = dict() |
| |
| with open("tiles.txt") as f: |
| for line in f: |
| tiles.append(line.split()) |
| |
| for arg in sys.argv[1:]: |
| with open(arg) as f: |
| line = f.read().strip() |
| site = arg[7:-6] |
| frame = int(line[5:5 + 8], 16) |
| site_baseaddr[site] = "0x%08x" % (frame & ~0x7f) |
| |
| ####################################### |
| # Create initial database |
| |
| database = dict() |
| database["tiles"] = dict() |
| database["segments"] = dict() |
| tiles_by_grid = dict() |
| |
| for record in tiles: |
| tile_type, tile_name, grid_x, grid_y = record[0:4] |
| grid_x, grid_y = int(grid_x), int(grid_y) |
| tiles_by_grid[(grid_x, grid_y)] = tile_name |
| framebaseaddr = None |
| |
| database["tiles"][tile_name] = { |
| "type": tile_type, |
| "sites": dict(), |
| "grid_x": grid_x, |
| "grid_y": grid_y |
| } |
| |
| if len(record) > 4: |
| for i in range(4, len(record), 2): |
| site_type, site_name = record[i:i + 2] |
| if site_name in site_baseaddr: |
| framebaseaddr = site_baseaddr[site_name] |
| database["tiles"][tile_name]["sites"][site_name] = site_type |
| |
| if framebaseaddr is not None: |
| tile_baseaddr[tile_name] = [framebaseaddr, 0] |
| |
| ####################################### |
| # Add Segments |
| |
| for tile_name, tile_data in database["tiles"].items(): |
| tile_type = tile_data["type"] |
| grid_x = tile_data["grid_x"] |
| grid_y = tile_data["grid_y"] |
| |
| if tile_type in ["CLBLL_L", "CLBLL_R", "CLBLM_L", "CLBLM_R"]: |
| if tile_type in ["CLBLL_L", "CLBLM_L"]: |
| int_tile_name = tiles_by_grid[(grid_x + 1, grid_y)] |
| else: |
| int_tile_name = tiles_by_grid[(grid_x - 1, grid_y)] |
| |
| segment_name = "SEG_" + tile_name |
| segtype = tile_type.lower() |
| |
| database["segments"][segment_name] = dict() |
| database["segments"][segment_name]["tiles"] = [ |
| tile_name, int_tile_name |
| ] |
| database["segments"][segment_name]["type"] = segtype |
| database["segments"][segment_name]["frames"] = 36 |
| database["segments"][segment_name]["words"] = 2 |
| |
| if tile_name in tile_baseaddr: |
| database["segments"][segment_name]["baseaddr"] = tile_baseaddr[ |
| tile_name] |
| |
| database["tiles"][tile_name]["segment"] = segment_name |
| database["tiles"][int_tile_name]["segment"] = segment_name |
| |
| if tile_type in ["HCLK_L", "HCLK_R"]: |
| segment_name = "SEG_" + tile_name |
| segtype = tile_type.lower() |
| |
| database["segments"][segment_name] = dict() |
| database["segments"][segment_name]["tiles"] = [tile_name] |
| database["segments"][segment_name]["type"] = segtype |
| database["segments"][segment_name]["frames"] = 26 |
| database["segments"][segment_name]["words"] = 1 |
| database["tiles"][tile_name]["segment"] = segment_name |
| |
| if tile_type in ["BRAM_L", "DSP_L", "BRAM_R", "DSP_R"]: |
| for k in range(5): |
| if tile_type in ["BRAM_L", "DSP_L"]: |
| interface_tile_name = tiles_by_grid[(grid_x + 1, grid_y - k)] |
| int_tile_name = tiles_by_grid[(grid_x + 2, grid_y - k)] |
| else: |
| interface_tile_name = tiles_by_grid[(grid_x - 1, grid_y - k)] |
| int_tile_name = tiles_by_grid[(grid_x - 2, grid_y - k)] |
| |
| segment_name = "SEG_" + tile_name.replace("_", "%d_" % k, 1) |
| segtype = tile_type.lower().replace("_", "%d_" % k, 1) |
| |
| database["segments"][segment_name] = dict() |
| database["segments"][segment_name]["type"] = segtype |
| database["segments"][segment_name]["frames"] = 28 |
| database["segments"][segment_name]["words"] = 2 |
| |
| if k == 0: |
| database["segments"][segment_name]["tiles"] = [ |
| tile_name, interface_tile_name, int_tile_name |
| ] |
| database["tiles"][tile_name]["segment"] = segment_name |
| database["tiles"][interface_tile_name][ |
| "segment"] = segment_name |
| database["tiles"][int_tile_name]["segment"] = segment_name |
| else: |
| database["segments"][segment_name]["tiles"] = [ |
| interface_tile_name, int_tile_name |
| ] |
| database["tiles"][interface_tile_name][ |
| "segment"] = segment_name |
| database["tiles"][int_tile_name]["segment"] = segment_name |
| |
| ####################################### |
| # Populate segment base addresses: L/R along INT column |
| |
| for segment_name in database["segments"].keys(): |
| if "baseaddr" in database["segments"][segment_name]: |
| framebase, wordbase = database["segments"][segment_name]["baseaddr"] |
| inttile = [ |
| tile for tile in database["segments"][segment_name]["tiles"] |
| if database["tiles"][tile]["type"] in ["INT_L", "INT_R"] |
| ][0] |
| grid_x = database["tiles"][inttile]["grid_x"] |
| grid_y = database["tiles"][inttile]["grid_y"] |
| |
| if database["tiles"][inttile]["type"] == "INT_L": |
| grid_x += 1 |
| framebase = "0x%08x" % (int(framebase, 16) + 0x80) |
| else: |
| grid_x -= 1 |
| framebase = "0x%08x" % (int(framebase, 16) - 0x80) |
| |
| if (grid_x, grid_y) not in tiles_by_grid: |
| continue |
| |
| tile = tiles_by_grid[(grid_x, grid_y)] |
| |
| if database["tiles"][inttile]["type"] == "INT_L": |
| assert database["tiles"][tile]["type"] == "INT_R" |
| elif database["tiles"][inttile]["type"] == "INT_R": |
| assert database["tiles"][tile]["type"] == "INT_L" |
| else: |
| assert 0 |
| |
| assert "segment" in database["tiles"][tile] |
| |
| seg = database["tiles"][tile]["segment"] |
| |
| if "baseaddr" in database["segments"][seg]: |
| assert database["segments"][seg]["baseaddr"] == [ |
| framebase, wordbase |
| ] |
| else: |
| database["segments"][seg]["baseaddr"] = [framebase, wordbase] |
| |
| ####################################### |
| # Populate segment base addresses: Up along INT/HCLK columns |
| |
| start_segments = list() |
| |
| for segment_name in database["segments"].keys(): |
| if "baseaddr" in database["segments"][segment_name]: |
| start_segments.append(segment_name) |
| |
| for segment_name in start_segments: |
| framebase, wordbase = database["segments"][segment_name]["baseaddr"] |
| inttile = [ |
| tile for tile in database["segments"][segment_name]["tiles"] |
| if database["tiles"][tile]["type"] in ["INT_L", "INT_R"] |
| ][0] |
| grid_x = database["tiles"][inttile]["grid_x"] |
| grid_y = database["tiles"][inttile]["grid_y"] |
| |
| for i in range(50): |
| grid_y -= 1 |
| |
| if wordbase == 50: |
| wordbase += 1 |
| else: |
| wordbase += 2 |
| |
| segname = database["tiles"][tiles_by_grid[(grid_x, grid_y)]]["segment"] |
| database["segments"][segname]["baseaddr"] = [framebase, wordbase] |
| |
| ####################################### |
| # Transfer segment data into tiles |
| |
| for segment_name in database["segments"].keys(): |
| baseaddr, offset = database["segments"][segment_name]["baseaddr"] |
| for tile_name in database["segments"][segment_name]["tiles"]: |
| tile_type = database["tiles"][tile_name]["type"] |
| if tile_type in ["CLBLL_L", "CLBLL_R", "CLBLM_L", "CLBLM_R", "INT_L", |
| "INT_R"]: |
| database["tiles"][tile_name]["baseaddr"] = baseaddr |
| database["tiles"][tile_name]["offset"] = offset |
| database["tiles"][tile_name]["height"] = 2 |
| elif tile_type in ["HCLK_L", "HCLK_R"]: |
| database["tiles"][tile_name]["baseaddr"] = baseaddr |
| database["tiles"][tile_name]["offset"] = offset |
| database["tiles"][tile_name]["height"] = 1 |
| elif tile_type in ["BRAM_L", "BRAM_R", "DSP_L", "DSP_R"]: |
| database["tiles"][tile_name]["baseaddr"] = baseaddr |
| database["tiles"][tile_name]["offset"] = offset |
| database["tiles"][tile_name]["height"] = 10 |
| elif tile_type in ["INT_INTERFACE_L", "INT_INTERFACE_R", |
| "BRAM_INT_INTERFACE_L", "BRAM_INT_INTERFACE_R"]: |
| continue |
| else: |
| # print(tile_type, offset) |
| assert False |
| |
| database = database["tiles"] |
| |
| for tiledata in database.values(): |
| if "segment" in tiledata: |
| del tiledata["segment"] |
| |
| ####################################### |
| # Write |
| |
| print(json.dumps(database, sort_keys=True, indent="\t")) |