| import json |
| import os |
| from utils import util |
| |
| # Break frames into WORD_SIZE bit words. |
| WORD_SIZE_BITS = 32 |
| |
| # How many 32-bit words for frame in a 7-series bitstream? |
| FRAME_WORD_COUNT = 101 |
| |
| # What alignment is expect for columns. |
| FRAME_ALIGNMENT = 0x80 |
| ''' |
| Sample: |
| bit_0002000f_079_06 |
| |
| Where: |
| -0002000f: FDRI address |
| -079: FDIR word number (0-100) |
| -06: bit index (0-31) |
| ''' |
| |
| |
| def load_bitdata(f): |
| """ Read bit file and return bitdata map. |
| Similar to segbits file |
| |
| bitdata is a map of of two sets. |
| The map key is the frame address. |
| The first sets are the word columns that have any bits set. |
| Word columsn are WORD_SIZE_BITS wide. |
| The second sets are bit index within the frame and word if it is set. |
| """ |
| bitdata = dict() |
| |
| for line in f: |
| line = line.split("_") |
| frame = int(line[1], 16) |
| wordidx = int(line[2], 10) |
| bitidx = int(line[3], 10) |
| |
| if frame not in bitdata: |
| bitdata[frame] = set(), set() |
| |
| bitdata[frame][0].add(wordidx) |
| bitdata[frame][1].add(wordidx * WORD_SIZE_BITS + bitidx) |
| |
| return bitdata |
| |
| |
| # used by segprint |
| # TODO: merge these |
| def load_bitdata2(f): |
| ''' |
| return as bitdata[frame][wordidx].add(bitidx) |
| ie indexed by frame, word index, and then a set with bit indexes |
| Similar to .bits file: bit_00020012_014_20 |
| ''' |
| |
| bitdata = dict() |
| |
| for lineraw in f: |
| lineraw = lineraw.strip() |
| line = lineraw.split("_") |
| try: |
| frame = int(line[1], 16) |
| wordidx = int(line[2], 10) |
| bitidx = int(line[3], 10) |
| except: |
| print("Invalid line %s" % lineraw) |
| raise |
| |
| if frame not in bitdata: |
| bitdata[frame] = dict() |
| |
| if wordidx not in bitdata[frame]: |
| bitdata[frame][wordidx] = set() |
| |
| bitdata[frame][wordidx].add(bitidx) |
| return bitdata |
| |
| |
| def gen_part_base_addrs(): |
| """ |
| Return (block_type, top_bottom, cfg_row, cfg_col, frame_count) |
| Where: |
| -block_type ("bus"): typically CLB_IO_CLK, sometimes BLOCK_RAM |
| -top_bottom: either "top" or "bottom" |
| -cfg_row: a relative row |
| -cfg_col: a relative column |
| -frame_count: number of frames to fully configure this minor address |
| |
| Example: |
| ('CLB_IO_CLK', 'bottom', 0, 3, 36) |
| ('BLOCK_RAM', 'top', 0, 1, 128) |
| ('CLB_IO_CLK', 'top', 1, 34, 28) |
| """ |
| fn = os.getenv("URAY_PART_YAML").replace(".yaml", ".json") |
| j = json.load(open(fn, "r")) |
| for tbk, tbv in j["global_clock_regions"].items(): |
| for rowk, rowv in tbv["rows"].items(): |
| for busk, busv in rowv["configuration_buses"].items(): |
| for colk, colv in busv["configuration_columns"].items(): |
| yield (busk, tbk, int(rowk), int(colk), |
| colv["frame_count"]) |
| |
| |
| def addr_bits2word(block_type, top_bottom, cfg_row, cfg_col, minor_addr): |
| """Convert a deconstructed address to a 32 bit word""" |
| # https://www.xilinx.com/support/documentation/user_guides/ug470_7Series_Config.pdf |
| ret = 0 |
| ret |= util.block_type_s2i[block_type] << 23 |
| ret |= {"top": 0, "bottom": 1}[top_bottom] << 22 |
| ret |= cfg_row << 17 |
| ret |= cfg_col << 7 |
| ret |= minor_addr |
| return ret |