mirror of https://github.com/openXC7/prjxray.git
118 lines
3.2 KiB
Python
118 lines
3.2 KiB
Python
import json
|
|
import os
|
|
from prjxray 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("XRAY_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
|