mirror of https://github.com/openXC7/prjxray.git
fasm2bits: working
Signed-off-by: John McMaster <johndmcmaster@gmail.com>
This commit is contained in:
parent
e7e010179b
commit
c8ee9d4f16
|
|
@ -23,5 +23,6 @@ export XRAY_MASKMERGE="bash ${XRAY_UTILS_DIR}/maskmerge.sh"
|
|||
export XRAY_SEGMATCH="${XRAY_TOOLS_DIR}/segmatch"
|
||||
export XRAY_SEGPRINT="python3 ${XRAY_UTILS_DIR}/segprint.py"
|
||||
export XRAY_BITS2FASM="python3 ${XRAY_UTILS_DIR}/bits2fasm.py"
|
||||
export XRAY_FASM2BITS="python3 ${XRAY_UTILS_DIR}/fasm2bits.py"
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -37,11 +37,11 @@ Maybe better to return as two distinct dictionaries?
|
|||
segbitsdb = dict()
|
||||
|
||||
|
||||
def get_database(segtype):
|
||||
if segtype in segbitsdb:
|
||||
return segbitsdb[segtype]
|
||||
def get_database(tile_type):
|
||||
if tile_type in segbitsdb:
|
||||
return segbitsdb[tile_type]
|
||||
|
||||
segbitsdb[segtype] = {}
|
||||
segbitsdb[tile_type] = {}
|
||||
|
||||
def process(l):
|
||||
l = l.strip()
|
||||
|
|
@ -59,7 +59,7 @@ def get_database(segtype):
|
|||
raise Exception(
|
||||
"Expect single bit DB entries to be set, got %s" % l)
|
||||
# Treat like an enumerated value with keys 0 or 1
|
||||
segbitsdb[segtype][name] = {
|
||||
segbitsdb[tile_type][name] = {
|
||||
'0': [(seg_word_column, word_bit_n, 0)],
|
||||
'1': [(seg_word_column, word_bit_n, 1)],
|
||||
}
|
||||
|
|
@ -71,22 +71,28 @@ def get_database(segtype):
|
|||
key = m.group(2)
|
||||
|
||||
# May or may not be the first key encountered
|
||||
bits_map = segbitsdb[segtype].setdefault(name, {})
|
||||
bits_map = segbitsdb[tile_type].setdefault(name, {})
|
||||
bits_map[key] = [parsebit(x) for x in bit_vals]
|
||||
|
||||
with open("%s/%s/segbits_%s.db" % (os.getenv("XRAY_DATABASE_DIR"),
|
||||
os.getenv("XRAY_DATABASE"), segtype),
|
||||
"r") as f:
|
||||
main_fn = "%s/%s/segbits_%s.db" % (
|
||||
os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE"),
|
||||
tile_type.lower())
|
||||
int_fn = "%s/%s/segbits_int_%s.db" % (
|
||||
os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE"),
|
||||
tile_type[-1].lower())
|
||||
|
||||
if not os.path.exists(main_fn) or not os.path.exists(int_fn):
|
||||
raise Exception(tile_type)
|
||||
|
||||
with open(main_fn, "r") as f:
|
||||
for line in f:
|
||||
process(line)
|
||||
|
||||
with open("%s/%s/segbits_int_%s.db" %
|
||||
(os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE"),
|
||||
segtype[-1]), "r") as f:
|
||||
with open(int_fn, "r") as f:
|
||||
for line in f:
|
||||
process(line)
|
||||
|
||||
return segbitsdb[segtype]
|
||||
return segbitsdb[tile_type]
|
||||
|
||||
|
||||
def dump_frames_verbose(frames):
|
||||
|
|
@ -126,34 +132,13 @@ def dump_frm(f, frames):
|
|||
'0x%08X ' % addr + ','.join(['0x%08X' % w for w in words]) + '\n')
|
||||
|
||||
|
||||
def run(f_in, f_out, sparse=False, debug=False):
|
||||
# address to array of 101 32 bit words
|
||||
frames = {}
|
||||
# Directives we've seen so far
|
||||
# Complain if there is a duplicate
|
||||
# Contains line number of last entry
|
||||
used_names = {}
|
||||
def mksegment(tile_name, block_name):
|
||||
'''Create a segment name'''
|
||||
return '%s:%s' % (tile_name, block_name)
|
||||
|
||||
def frames_init():
|
||||
'''Set all frames to 0'''
|
||||
for segj in grid['segments'].values():
|
||||
seg_baseaddr, seg_word_base = segj['baseaddr']
|
||||
seg_baseaddr = int(seg_baseaddr, 0)
|
||||
for coli in range(segj['frames']):
|
||||
frame_init(seg_baseaddr + coli)
|
||||
|
||||
def frame_init(addr):
|
||||
'''Set given frame to 0'''
|
||||
if not addr in frames:
|
||||
frames[addr] = [0 for _i in range(101)]
|
||||
|
||||
def frame_set(frame_addr, word_addr, bit_index):
|
||||
'''Set given bit in given frame address and word'''
|
||||
frames[frame_addr][word_addr] |= 1 << bit_index
|
||||
|
||||
def frame_clear(frame_addr, word_addr, bit_index):
|
||||
'''Set given bit in given frame address and word'''
|
||||
frames[frame_addr][word_addr] &= 0xFFFFFFFF ^ (1 << bit_index)
|
||||
def mk_grid():
|
||||
'''Load tilegrid, flattening all blocks into one dictionary'''
|
||||
|
||||
with open("%s/%s/tilegrid.json" % (os.getenv("XRAY_DATABASE_DIR"),
|
||||
os.getenv("XRAY_DATABASE")), "r") as f:
|
||||
|
|
@ -162,80 +147,124 @@ def run(f_in, f_out, sparse=False, debug=False):
|
|||
# TODO: Migrate to new tilegrid format via library.
|
||||
grid = {'tiles': new_grid, 'segments': {}}
|
||||
|
||||
for tile in grid['tiles'].values():
|
||||
if 'segment' in tile:
|
||||
segment = tile['segment']
|
||||
grid['segments'][segment] = {
|
||||
for tile_name, tile in grid['tiles'].items():
|
||||
for block_name, block in tile['bits'].items():
|
||||
segname = mksegment(tile_name, block_name)
|
||||
grid['segments'][segname] = {
|
||||
'baseaddr': [
|
||||
tile['baseaddr'],
|
||||
tile['offset'],
|
||||
block['baseaddr'],
|
||||
block['offset'],
|
||||
],
|
||||
'type': tile['segment_type'],
|
||||
'frames': tile['frames'],
|
||||
'words': tile['words'],
|
||||
'type': tile['type'],
|
||||
'frames': block['frames'],
|
||||
'words': block['words'],
|
||||
'tile_name': tile_name,
|
||||
'block_name': block_name,
|
||||
}
|
||||
return grid
|
||||
|
||||
if not sparse:
|
||||
# Initiaize bitstream to 0
|
||||
frames_init()
|
||||
def frame_init(frames, addr):
|
||||
'''Set given frame to 0'''
|
||||
if not addr in frames:
|
||||
frames[addr] = [0 for _i in range(101)]
|
||||
|
||||
for line_number, l in enumerate(f_in, 1):
|
||||
# Comment
|
||||
# Remove all text including and after #
|
||||
i = l.rfind('#')
|
||||
if i >= 0:
|
||||
l = l[0:i]
|
||||
l = l.strip()
|
||||
|
||||
# Ignore blank lines
|
||||
if not l:
|
||||
continue
|
||||
|
||||
# tile.site.stuff value
|
||||
# INT_L_X10Y102.CENTER_INTER_L.IMUX_L1 EE2END0
|
||||
# Optional value
|
||||
m = re.match(r'([a-zA-Z0-9_]+)[.]([a-zA-Z0-9_.\[\]]+)([ ](.+))?', l)
|
||||
if not m:
|
||||
raise FASMSyntaxError("Bad line: %s" % l)
|
||||
tile = m.group(1)
|
||||
name = m.group(2)
|
||||
value = m.group(4)
|
||||
|
||||
used_name = (tile, name)
|
||||
old_line_number = used_names.get(used_name, None)
|
||||
if old_line_number:
|
||||
raise FASMSyntaxError(
|
||||
"Duplicate name lines %d and %d, second line: %s" %
|
||||
(old_line_number, line_number, l))
|
||||
used_names[used_name] = line_number
|
||||
|
||||
tilej = grid['tiles'][tile]
|
||||
seg = tilej['segment']
|
||||
segj = grid['segments'][seg]
|
||||
def frames_init(frames, grid):
|
||||
'''Set all frames to 0'''
|
||||
for segj in grid['segments'].values():
|
||||
seg_baseaddr, seg_word_base = segj['baseaddr']
|
||||
seg_baseaddr = int(seg_baseaddr, 0)
|
||||
for coli in range(segj['frames']):
|
||||
frame_init(frames, seg_baseaddr + coli)
|
||||
|
||||
def frame_set(frames, frame_addr, word_addr, bit_index):
|
||||
'''Set given bit in given frame address and word'''
|
||||
frames[frame_addr][word_addr] |= 1 << bit_index
|
||||
|
||||
def frame_clear(frames, frame_addr, word_addr, bit_index):
|
||||
'''Set given bit in given frame address and word'''
|
||||
frames[frame_addr][word_addr] &= 0xFFFFFFFF ^ (1 << bit_index)
|
||||
|
||||
|
||||
def parse_line(l):
|
||||
# Comment
|
||||
# Remove all text including and after #
|
||||
i = l.rfind('#')
|
||||
if i >= 0:
|
||||
l = l[0:i]
|
||||
l = l.strip()
|
||||
|
||||
# Ignore blank lines
|
||||
if not l:
|
||||
return
|
||||
|
||||
# tile.site.stuff value
|
||||
# INT_L_X10Y102.CENTER_INTER_L.IMUX_L1 EE2END0
|
||||
# Optional value
|
||||
m = re.match(r'([a-zA-Z0-9_]+)[.]([a-zA-Z0-9_.\[\]]+)([ ](.+))?', l)
|
||||
if not m:
|
||||
raise FASMSyntaxError("Bad line: %s" % l)
|
||||
tile = m.group(1)
|
||||
name = m.group(2)
|
||||
value = m.group(4)
|
||||
|
||||
return tile, name, value
|
||||
|
||||
def check_duplicate(used_names, tile, name, l, line_number):
|
||||
'''Throw an exception if a conflicting FASM directive was given'''
|
||||
used_name = (tile, name)
|
||||
old_line_number = used_names.get(used_name, None)
|
||||
if old_line_number:
|
||||
raise FASMSyntaxError(
|
||||
"Duplicate name lines %d and %d, second line: %s" %
|
||||
(old_line_number, line_number, l))
|
||||
used_names[used_name] = line_number
|
||||
|
||||
def update_segbit(frames, seg_word_column, word_bit_n, isset, seg_baseaddr, seg_word_base):
|
||||
'''Set or clear a single bit in a segment at the given word column and word bit position'''
|
||||
# Now we have the word column and word bit index
|
||||
# Combine with the segments relative frame position to fully get the position
|
||||
frame_addr = seg_baseaddr + seg_word_column
|
||||
# 2 words per segment
|
||||
word_addr = seg_word_base + word_bit_n // 32
|
||||
bit_index = word_bit_n % 32
|
||||
if isset:
|
||||
frame_set(frames, frame_addr, word_addr, bit_index)
|
||||
else:
|
||||
frame_clear(frames, frame_addr, word_addr, bit_index)
|
||||
|
||||
def default_value(db_vals, name):
|
||||
# If its binary, allow omitted value default to 1
|
||||
if tuple(sorted(db_vals.keys())) == ('0', '1'):
|
||||
return '1'
|
||||
else:
|
||||
raise FASMSyntaxError(
|
||||
"Enumerable entry %s must have explicit value" % name)
|
||||
|
||||
|
||||
def process_line(line_number, l, grid, frames, used_names):
|
||||
parsed = parse_line(l)
|
||||
# empty line
|
||||
if not parsed:
|
||||
return
|
||||
tile_name, name, value = parsed
|
||||
check_duplicate(used_names, tile_name, name, l, line_number)
|
||||
|
||||
tilej = grid['tiles'][tile_name]
|
||||
for block_name, block in tilej['bits'].items():
|
||||
segname = mksegment(tile_name, block_name)
|
||||
|
||||
segj = grid['segments'][segname]
|
||||
seg_baseaddr, seg_word_base = segj['baseaddr']
|
||||
seg_baseaddr = int(seg_baseaddr, 0)
|
||||
|
||||
# Ensure that all frames exist for this segment
|
||||
# FIXME: type dependent
|
||||
for coli in range(segj['frames']):
|
||||
frame_init(seg_baseaddr + coli)
|
||||
|
||||
def update_segbit(seg_word_column, word_bit_n, isset):
|
||||
'''Set or clear a single bit in a segment at the given word column and word bit position'''
|
||||
# Now we have the word column and word bit index
|
||||
# Combine with the segments relative frame position to fully get the position
|
||||
frame_addr = seg_baseaddr + seg_word_column
|
||||
# 2 words per segment
|
||||
word_addr = seg_word_base + word_bit_n // 32
|
||||
bit_index = word_bit_n % 32
|
||||
if isset:
|
||||
frame_set(frame_addr, word_addr, bit_index)
|
||||
else:
|
||||
frame_clear(frame_addr, word_addr, bit_index)
|
||||
|
||||
frame_init(frames, seg_baseaddr + coli)
|
||||
|
||||
# Now lets look up the bits we need frames for
|
||||
segdb = get_database(segj['type'])
|
||||
|
||||
|
||||
db_k = '%s.%s' % (tilej['type'], name)
|
||||
try:
|
||||
db_vals = segdb[db_k]
|
||||
|
|
@ -243,14 +272,10 @@ def run(f_in, f_out, sparse=False, debug=False):
|
|||
raise FASMSyntaxError(
|
||||
"Segment DB %s, key %s not found from line '%s'" %
|
||||
(segj['type'], db_k, l)) from None
|
||||
|
||||
|
||||
if not value:
|
||||
# If its binary, allow omitted value default to 1
|
||||
if tuple(sorted(db_vals.keys())) == ('0', '1'):
|
||||
value = '1'
|
||||
else:
|
||||
raise FASMSyntaxError(
|
||||
"Enumerable entry %s must have explicit value" % name)
|
||||
value = default_value(db_vals, name)
|
||||
|
||||
# Get the specific entry we need
|
||||
try:
|
||||
db_vals = db_vals[value]
|
||||
|
|
@ -258,8 +283,27 @@ def run(f_in, f_out, sparse=False, debug=False):
|
|||
raise FASMSyntaxError(
|
||||
"Invalid entry %s. Valid entries are %s" %
|
||||
(value, db_vals.keys()))
|
||||
|
||||
for seg_word_column, word_bit_n, isset in db_vals:
|
||||
update_segbit(seg_word_column, word_bit_n, isset)
|
||||
update_segbit(frames, seg_word_column, word_bit_n, isset, seg_baseaddr, seg_word_base)
|
||||
|
||||
|
||||
def run(f_in, f_out, sparse=False, debug=False):
|
||||
# address to array of 101 32 bit words
|
||||
frames = {}
|
||||
# Directives we've seen so far
|
||||
# Complain if there is a duplicate
|
||||
# Contains line number of last entry
|
||||
used_names = {}
|
||||
|
||||
grid = mk_grid()
|
||||
|
||||
if not sparse:
|
||||
# Initiaize bitstream to 0
|
||||
frames_init(frames, grid)
|
||||
|
||||
for line_number, l in enumerate(f_in, 1):
|
||||
process_line(line_number, l, grid, frames, used_names)
|
||||
|
||||
if debug:
|
||||
#dump_frames_verbose(frames)
|
||||
|
|
|
|||
Loading…
Reference in New Issue