mirror of https://github.com/openXC7/prjxray.git
Merge pull request #61 from mcmasterg/fasm2frame_oparg
Fasm2frame oparg
This commit is contained in:
commit
c78b9513c7
|
|
@ -4,9 +4,36 @@ import os
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import json
|
import json
|
||||||
|
import collections
|
||||||
|
|
||||||
# Based on segprint function
|
|
||||||
# Modified to return dict instead of list
|
class FASMSyntaxError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def parsebit(val):
|
||||||
|
'''Return "!012_23" => (12, 23, False)'''
|
||||||
|
isset = True
|
||||||
|
# Default is 0. Skip explicit call outs
|
||||||
|
if val[0] == '!':
|
||||||
|
isset = False
|
||||||
|
val = val[1:]
|
||||||
|
# 28_05 => 28, 05
|
||||||
|
seg_word_column, word_bit_n = val.split('_')
|
||||||
|
return int(seg_word_column), int(word_bit_n), isset
|
||||||
|
|
||||||
|
|
||||||
|
'''
|
||||||
|
Loosely based on segprint function
|
||||||
|
Maybe better to return as two distinct dictionaries?
|
||||||
|
|
||||||
|
{
|
||||||
|
'tile.meh': {
|
||||||
|
'O5': [(11, 2, False), (12, 2, True)],
|
||||||
|
'O6': [(11, 2, True), (12, 2, False)],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
'''
|
||||||
segbitsdb = dict()
|
segbitsdb = dict()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -16,25 +43,48 @@ def get_database(segtype):
|
||||||
|
|
||||||
segbitsdb[segtype] = {}
|
segbitsdb[segtype] = {}
|
||||||
|
|
||||||
|
def process(l):
|
||||||
|
l = l.strip()
|
||||||
|
|
||||||
|
# CLBLM_L.SLICEL_X1.ALUT.INIT[10] 29_14
|
||||||
|
parts = line.split()
|
||||||
|
name = parts[0]
|
||||||
|
bit_vals = parts[1:]
|
||||||
|
|
||||||
|
# Assumption
|
||||||
|
# only 1 bit => non-enumerated value
|
||||||
|
if len(bit_vals) == 1:
|
||||||
|
seg_word_column, word_bit_n, isset = parsebit(bit_vals[0])
|
||||||
|
if not isset:
|
||||||
|
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] = {
|
||||||
|
'0': [(seg_word_column, word_bit_n, 0)],
|
||||||
|
'1': [(seg_word_column, word_bit_n, 1)],
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
# An enumerated value
|
||||||
|
# Split the base name and selected key
|
||||||
|
m = re.match(r'(.+)[.](.+)', name)
|
||||||
|
name = m.group(1)
|
||||||
|
key = m.group(2)
|
||||||
|
|
||||||
|
# May or may not be the first key encountered
|
||||||
|
bits_map = segbitsdb[segtype].setdefault(name, {})
|
||||||
|
bits_map[key] = [parsebit(x) for x in bit_vals]
|
||||||
|
|
||||||
with open("%s/%s/segbits_%s.db" % (os.getenv("XRAY_DATABASE_DIR"),
|
with open("%s/%s/segbits_%s.db" % (os.getenv("XRAY_DATABASE_DIR"),
|
||||||
os.getenv("XRAY_DATABASE"), segtype),
|
os.getenv("XRAY_DATABASE"), segtype),
|
||||||
"r") as f:
|
"r") as f:
|
||||||
for line in f:
|
for line in f:
|
||||||
# CLBLM_L.SLICEL_X1.ALUT.INIT[10] 29_14
|
process(line)
|
||||||
parts = line.split()
|
|
||||||
name = parts[0]
|
|
||||||
vals = parts[1:]
|
|
||||||
segbitsdb[segtype][name] = vals
|
|
||||||
|
|
||||||
with open("%s/%s/segbits_int_%s.db" %
|
with open("%s/%s/segbits_int_%s.db" %
|
||||||
(os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE"),
|
(os.getenv("XRAY_DATABASE_DIR"), os.getenv("XRAY_DATABASE"),
|
||||||
segtype[-1]), "r") as f:
|
segtype[-1]), "r") as f:
|
||||||
for line in f:
|
for line in f:
|
||||||
# CLBLM_L.SLICEL_X1.ALUT.INIT[10] 29_14
|
process(line)
|
||||||
parts = line.split()
|
|
||||||
name = parts[0]
|
|
||||||
vals = parts[1:]
|
|
||||||
segbitsdb[segtype][name] = vals
|
|
||||||
|
|
||||||
return segbitsdb[segtype]
|
return segbitsdb[segtype]
|
||||||
|
|
||||||
|
|
@ -79,6 +129,10 @@ def dump_frm(f, frames):
|
||||||
def run(f_in, f_out, sparse=False, debug=False):
|
def run(f_in, f_out, sparse=False, debug=False):
|
||||||
# address to array of 101 32 bit words
|
# address to array of 101 32 bit words
|
||||||
frames = {}
|
frames = {}
|
||||||
|
# Directives we've seen so far
|
||||||
|
# Complain if there is a duplicate
|
||||||
|
# Contains line number of last entry
|
||||||
|
used_names = {}
|
||||||
|
|
||||||
def frames_init():
|
def frames_init():
|
||||||
'''Set all frames to 0'''
|
'''Set all frames to 0'''
|
||||||
|
|
@ -97,6 +151,10 @@ def run(f_in, f_out, sparse=False, debug=False):
|
||||||
'''Set given bit in given frame address and word'''
|
'''Set given bit in given frame address and word'''
|
||||||
frames[frame_addr][word_addr] |= 1 << bit_index
|
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)
|
||||||
|
|
||||||
with open("%s/%s/tilegrid.json" % (os.getenv("XRAY_DATABASE_DIR"),
|
with open("%s/%s/tilegrid.json" % (os.getenv("XRAY_DATABASE_DIR"),
|
||||||
os.getenv("XRAY_DATABASE")), "r") as f:
|
os.getenv("XRAY_DATABASE")), "r") as f:
|
||||||
grid = json.load(f)
|
grid = json.load(f)
|
||||||
|
|
@ -105,7 +163,7 @@ def run(f_in, f_out, sparse=False, debug=False):
|
||||||
# Initiaize bitstream to 0
|
# Initiaize bitstream to 0
|
||||||
frames_init()
|
frames_init()
|
||||||
|
|
||||||
for l in f_in:
|
for line_number, l in enumerate(f_in, 1):
|
||||||
# Comment
|
# Comment
|
||||||
# Remove all text including and after #
|
# Remove all text including and after #
|
||||||
i = l.rfind('#')
|
i = l.rfind('#')
|
||||||
|
|
@ -119,16 +177,22 @@ def run(f_in, f_out, sparse=False, debug=False):
|
||||||
|
|
||||||
# tile.site.stuff value
|
# tile.site.stuff value
|
||||||
# INT_L_X10Y102.CENTER_INTER_L.IMUX_L1 EE2END0
|
# INT_L_X10Y102.CENTER_INTER_L.IMUX_L1 EE2END0
|
||||||
m = re.match(
|
# Optional value
|
||||||
r'([a-zA-Z0-9_]+)[.]([a-zA-Z0-9_]+)[.]([a-zA-Z0-9_.\[\]]+)[ ](.+)',
|
m = re.match(r'([a-zA-Z0-9_]+)[.]([a-zA-Z0-9_.\[\]]+)([ ](.+))?', l)
|
||||||
l)
|
|
||||||
if not m:
|
if not m:
|
||||||
raise Exception("Bad line: %s" % l)
|
raise FASMSyntaxError("Bad line: %s" % l)
|
||||||
tile = m.group(1)
|
tile = m.group(1)
|
||||||
site = m.group(2)
|
name = m.group(2)
|
||||||
suffix = m.group(3)
|
|
||||||
value = m.group(4)
|
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]
|
tilej = grid['tiles'][tile]
|
||||||
seg = tilej['segment']
|
seg = tilej['segment']
|
||||||
segj = grid['segments'][seg]
|
segj = grid['segments'][seg]
|
||||||
|
|
@ -140,53 +204,46 @@ def run(f_in, f_out, sparse=False, debug=False):
|
||||||
for coli in range(segj['frames']):
|
for coli in range(segj['frames']):
|
||||||
frame_init(seg_baseaddr + coli)
|
frame_init(seg_baseaddr + coli)
|
||||||
|
|
||||||
# Now lets look up the bits we need frames for
|
def update_segbit(seg_word_column, word_bit_n, isset):
|
||||||
segdb = get_database(segj['type'])
|
'''Set or clear a single bit in a segment at the given word column and word bit position'''
|
||||||
|
|
||||||
def clb2dbkey(tile, tilej, site, suffix, value):
|
|
||||||
db_k = '%s.%s.%s' % (tilej['type'], site, suffix)
|
|
||||||
return db_k
|
|
||||||
|
|
||||||
def int2dbkey(tile, tilej, site, suffix, value):
|
|
||||||
return '%s.%s.%s' % (tilej['type'], suffix, value)
|
|
||||||
|
|
||||||
tile2dbkey = {
|
|
||||||
'CLBLL_L': clb2dbkey,
|
|
||||||
'CLBLL_R': clb2dbkey,
|
|
||||||
'CLBLM_L': clb2dbkey,
|
|
||||||
'CLBLM_R': clb2dbkey,
|
|
||||||
'INT_L': int2dbkey,
|
|
||||||
'INT_R': int2dbkey,
|
|
||||||
'HCLK_L': int2dbkey,
|
|
||||||
'HCLK_R': int2dbkey,
|
|
||||||
}
|
|
||||||
|
|
||||||
f = tile2dbkey.get(tilej['type'], None)
|
|
||||||
if f is None:
|
|
||||||
raise Exception("Unhandled segment type %s" % tilej['type'])
|
|
||||||
db_k = f(tile, tilej, site, suffix, value)
|
|
||||||
|
|
||||||
try:
|
|
||||||
db_vals = segdb[db_k]
|
|
||||||
except KeyError:
|
|
||||||
raise Exception(
|
|
||||||
"Key %s (from line '%s') not found in segment DB %s" %
|
|
||||||
(db_k, l, segj['type']))
|
|
||||||
|
|
||||||
for val in db_vals:
|
|
||||||
# Default is 0. Skip explicit call outs
|
|
||||||
if val[0] == '!':
|
|
||||||
continue
|
|
||||||
# 28_05 => 28, 05
|
|
||||||
seg_word_column, word_bit_n = val.split('_')
|
|
||||||
seg_word_column, word_bit_n = int(seg_word_column), int(word_bit_n)
|
|
||||||
# Now we have the word column and word bit index
|
# Now we have the word column and word bit index
|
||||||
# Combine with the segments relative frame position to fully get the position
|
# Combine with the segments relative frame position to fully get the position
|
||||||
frame_addr = seg_baseaddr + seg_word_column
|
frame_addr = seg_baseaddr + seg_word_column
|
||||||
# 2 words per segment
|
# 2 words per segment
|
||||||
word_addr = seg_word_base + word_bit_n // 32
|
word_addr = seg_word_base + word_bit_n // 32
|
||||||
bit_index = word_bit_n % 32
|
bit_index = word_bit_n % 32
|
||||||
|
if isset:
|
||||||
frame_set(frame_addr, word_addr, bit_index)
|
frame_set(frame_addr, word_addr, bit_index)
|
||||||
|
else:
|
||||||
|
frame_clear(frame_addr, word_addr, bit_index)
|
||||||
|
|
||||||
|
# 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]
|
||||||
|
except KeyError:
|
||||||
|
raise FASMSyntaxError(
|
||||||
|
"Segment DB %s, key %s not found from line '%s'" %
|
||||||
|
(segj['type'], db_k, l))
|
||||||
|
|
||||||
|
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)
|
||||||
|
# Get the specific entry we need
|
||||||
|
try:
|
||||||
|
db_vals = db_vals[value]
|
||||||
|
except KeyError:
|
||||||
|
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)
|
||||||
|
|
||||||
if debug:
|
if debug:
|
||||||
#dump_frames_verbose(frames)
|
#dump_frames_verbose(frames)
|
||||||
|
|
|
||||||
|
|
@ -5,29 +5,50 @@ import re
|
||||||
import sys
|
import sys
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
enumdb = dict()
|
||||||
|
|
||||||
|
|
||||||
|
def get_enums(segtype):
|
||||||
|
if segtype in enumdb:
|
||||||
|
return enumdb[segtype]
|
||||||
|
|
||||||
|
enumdb[segtype] = {}
|
||||||
|
|
||||||
|
def process(l):
|
||||||
|
l = l.strip()
|
||||||
|
|
||||||
|
# CLBLM_L.SLICEL_X1.ALUT.INIT[10] 29_14
|
||||||
|
parts = line.split()
|
||||||
|
name = parts[0]
|
||||||
|
bit_vals = parts[1:]
|
||||||
|
|
||||||
|
# Assumption
|
||||||
|
# only 1 bit => non-enumerated value
|
||||||
|
enumdb[segtype][name] = len(bit_vals) != 1
|
||||||
|
|
||||||
|
with open("%s/%s/segbits_%s.db" % (os.getenv("XRAY_DATABASE_DIR"),
|
||||||
|
os.getenv("XRAY_DATABASE"), segtype),
|
||||||
|
"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:
|
||||||
|
for line in f:
|
||||||
|
process(line)
|
||||||
|
|
||||||
|
return enumdb[segtype]
|
||||||
|
|
||||||
|
|
||||||
|
def isenum(segtype, tag):
|
||||||
|
return get_enums(segtype)[tag]
|
||||||
|
|
||||||
|
|
||||||
def tag2fasm(grid, seg, tag):
|
def tag2fasm(grid, seg, tag):
|
||||||
'''Given tilegrid, segment name and tag, return fasm directive'''
|
'''Given tilegrid, segment name and tag, return fasm directive'''
|
||||||
segj = grid['segments'][seg]
|
segj = grid['segments'][seg]
|
||||||
|
|
||||||
def clbf(seg, tile, tag_post):
|
|
||||||
return '%s.%s 1' % (tile, tag_post)
|
|
||||||
|
|
||||||
def intf(seg, tile, tag_post):
|
|
||||||
# Make the selection an argument of the configruation
|
|
||||||
m = re.match(r'(.*)[.]([A-Za-z0-9_]+)', tag_post)
|
|
||||||
which = m.group(1)
|
|
||||||
value = m.group(2)
|
|
||||||
site = {
|
|
||||||
'clbll_l': 'CENTER_INTER_L',
|
|
||||||
'clbll_r': 'CENTER_INTER_R',
|
|
||||||
'clblm_l': 'CENTER_INTER_L',
|
|
||||||
'clblm_r': 'CENTER_INTER_R',
|
|
||||||
'hclk_l': 'HCLK_L',
|
|
||||||
'hclk_r': 'HCLK_R',
|
|
||||||
}[segj['type']]
|
|
||||||
return '%s.%s.%s %s' % (tile, site, which, value)
|
|
||||||
|
|
||||||
m = re.match(r'([A-Za-z0-9_]+)[.](.*)', tag)
|
m = re.match(r'([A-Za-z0-9_]+)[.](.*)', tag)
|
||||||
tile_type = m.group(1)
|
tile_type = m.group(1)
|
||||||
tag_post = m.group(2)
|
tag_post = m.group(2)
|
||||||
|
|
@ -39,20 +60,14 @@ def tag2fasm(grid, seg, tag):
|
||||||
else:
|
else:
|
||||||
raise Exception("Couldn't find tile type %s" % tile_type)
|
raise Exception("Couldn't find tile type %s" % tile_type)
|
||||||
|
|
||||||
tag2asm = {
|
if not isenum(segj['type'], tag):
|
||||||
'CLBLL_L': clbf,
|
return '%s.%s 1' % (tile, tag_post)
|
||||||
'CLBLL_R': clbf,
|
else:
|
||||||
'CLBLM_L': clbf,
|
# Make the selection an argument of the configruation
|
||||||
'CLBLM_R': clbf,
|
m = re.match(r'(.*)[.]([A-Za-z0-9_]+)', tag_post)
|
||||||
'INT_L': intf,
|
which = m.group(1)
|
||||||
'INT_R': intf,
|
value = m.group(2)
|
||||||
'HCLK_L': intf,
|
return '%s.%s %s' % (tile, which, value)
|
||||||
'HCLK_R': intf,
|
|
||||||
}
|
|
||||||
f = tag2asm.get(tile_type, None)
|
|
||||||
if f is None:
|
|
||||||
raise Exception("Unhandled segment type %s" % tile_type)
|
|
||||||
return f(seg, tile, tag_post)
|
|
||||||
|
|
||||||
|
|
||||||
def run(f_in, f_out, sparse=False):
|
def run(f_in, f_out, sparse=False):
|
||||||
|
|
|
||||||
|
|
@ -2,23 +2,22 @@
|
||||||
# segprint -zd test_data/clb_ff/design.bits
|
# segprint -zd test_data/clb_ff/design.bits
|
||||||
|
|
||||||
# FF as LDCE
|
# FF as LDCE
|
||||||
CLBLM_L_X10Y102.SLICEM_X0.AFF.DMUX.AX 1
|
CLBLM_L_X10Y102.SLICEM_X0.AFF.DMUX AX
|
||||||
CLBLM_L_X10Y102.SLICEM_X0.AFF.ZINI 1
|
CLBLM_L_X10Y102.SLICEM_X0.AFF.ZINI 1
|
||||||
CLBLM_L_X10Y102.SLICEM_X0.AFF.ZRST 1
|
CLBLM_L_X10Y102.SLICEM_X0.AFF.ZRST 1
|
||||||
CLBLM_L_X10Y102.SLICEM_X0.CEUSEDMUX 1
|
CLBLM_L_X10Y102.SLICEM_X0.CEUSEDMUX 1
|
||||||
|
# CLBLM_L_X10Y102.SLICEM_X0.SRUSEDMUX 1
|
||||||
CLBLM_L_X10Y102.SLICEM_X0.SRUSEDMUX 1
|
CLBLM_L_X10Y102.SLICEM_X0.SRUSEDMUX 1
|
||||||
# CLBLM_L_X10Y102.SLICEM_X0.FFSYNC 0
|
|
||||||
# CLBLM_L_X10Y102.SLICEM_X0.LATCH 0
|
|
||||||
|
|
||||||
# Note: a number of pseudo pips here
|
# Note: a number of pseudo pips here
|
||||||
# Omitted
|
# Omitted
|
||||||
INT_L_X10Y102.CENTER_INTER_L.BYP_ALT0 EE2END0
|
INT_L_X10Y102.BYP_ALT0 EE2END0
|
||||||
INT_L_X10Y102.CENTER_INTER_L.BYP_ALT1 EL1END1
|
INT_L_X10Y102.BYP_ALT1 EL1END1
|
||||||
INT_L_X10Y102.CENTER_INTER_L.CLK_L1 GCLK_L_B11_WEST
|
INT_L_X10Y102.CLK_L1 GCLK_L_B11_WEST
|
||||||
INT_L_X10Y102.CENTER_INTER_L.CTRL_L1 ER1END2
|
INT_L_X10Y102.CTRL_L1 ER1END2
|
||||||
INT_L_X10Y102.CENTER_INTER_L.FAN_ALT7 BYP_BOUNCE0
|
INT_L_X10Y102.FAN_ALT7 BYP_BOUNCE0
|
||||||
INT_L_X10Y102.CENTER_INTER_L.WW2BEG0 LOGIC_OUTS_L4
|
INT_L_X10Y102.WW2BEG0 LOGIC_OUTS_L4
|
||||||
|
|
||||||
HCLK_L_X31Y130.HCLK_L.ENABLE_BUFFER HCLK_CK_BUFHCLK8
|
HCLK_L_X31Y130.ENABLE_BUFFER.HCLK_CK_BUFHCLK8 1
|
||||||
HCLK_L_X31Y130.HCLK_L.HCLK_LEAF_CLK_B_BOTL5 HCLK_CK_BUFHCLK8
|
HCLK_L_X31Y130.HCLK_LEAF_CLK_B_BOTL5 HCLK_CK_BUFHCLK8
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
# Loosely based on
|
||||||
|
# segprint -zd test_data/clb_ff/design.bits
|
||||||
|
|
||||||
|
# FF as LDCE
|
||||||
|
CLBLM_L_X10Y102.SLICEM_X0.AFF.DMUX AX
|
||||||
|
CLBLM_L_X10Y102.SLICEM_X0.AFF.ZINI 1
|
||||||
|
CLBLM_L_X10Y102.SLICEM_X0.AFF.ZRST 1
|
||||||
|
CLBLM_L_X10Y102.SLICEM_X0.CEUSEDMUX 1
|
||||||
|
CLBLM_L_X10Y102.SLICEM_X0.SRUSEDMUX 1
|
||||||
|
# Unused bits explicitly set to 0
|
||||||
|
CLBLM_L_X10Y102.SLICEM_X0.FFSYNC 0
|
||||||
|
CLBLM_L_X10Y102.SLICEM_X0.LATCH 0
|
||||||
|
|
||||||
|
# Note: a number of pseudo pips here
|
||||||
|
# Omitted
|
||||||
|
INT_L_X10Y102.BYP_ALT0 EE2END0
|
||||||
|
INT_L_X10Y102.BYP_ALT1 EL1END1
|
||||||
|
INT_L_X10Y102.CLK_L1 GCLK_L_B11_WEST
|
||||||
|
INT_L_X10Y102.CTRL_L1 ER1END2
|
||||||
|
INT_L_X10Y102.FAN_ALT7 BYP_BOUNCE0
|
||||||
|
INT_L_X10Y102.WW2BEG0 LOGIC_OUTS_L4
|
||||||
|
|
||||||
|
HCLK_L_X31Y130.ENABLE_BUFFER.HCLK_CK_BUFHCLK8 1
|
||||||
|
HCLK_L_X31Y130.HCLK_LEAF_CLK_B_BOTL5 HCLK_CK_BUFHCLK8
|
||||||
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
# Loosely based on
|
||||||
|
# segprint -zd test_data/clb_ff/design.bits
|
||||||
|
|
||||||
|
# FF as LDCE
|
||||||
|
CLBLM_L_X10Y102.SLICEM_X0.AFF.DMUX AX
|
||||||
|
CLBLM_L_X10Y102.SLICEM_X0.AFF.ZINI 1
|
||||||
|
CLBLM_L_X10Y102.SLICEM_X0.AFF.ZRST 1
|
||||||
|
CLBLM_L_X10Y102.SLICEM_X0.CEUSEDMUX 1
|
||||||
|
# CLBLM_L_X10Y102.SLICEM_X0.SRUSEDMUX 1
|
||||||
|
# Optional entry
|
||||||
|
CLBLM_L_X10Y102.SLICEM_X0.SRUSEDMUX
|
||||||
|
|
||||||
|
# Note: a number of pseudo pips here
|
||||||
|
# Omitted
|
||||||
|
INT_L_X10Y102.BYP_ALT0 EE2END0
|
||||||
|
INT_L_X10Y102.BYP_ALT1 EL1END1
|
||||||
|
INT_L_X10Y102.CLK_L1 GCLK_L_B11_WEST
|
||||||
|
INT_L_X10Y102.CTRL_L1 ER1END2
|
||||||
|
INT_L_X10Y102.FAN_ALT7 BYP_BOUNCE0
|
||||||
|
INT_L_X10Y102.WW2BEG0 LOGIC_OUTS_L4
|
||||||
|
|
||||||
|
HCLK_L_X31Y130.ENABLE_BUFFER.HCLK_CK_BUFHCLK8 1
|
||||||
|
HCLK_L_X31Y130.HCLK_LEAF_CLK_B_BOTL5 HCLK_CK_BUFHCLK8
|
||||||
|
|
||||||
|
|
@ -18,18 +18,18 @@ CLBLM_L_X10Y102.SLICEM_X0.ALUT.INIT[63] 1
|
||||||
|
|
||||||
# din bus
|
# din bus
|
||||||
# din[0]
|
# din[0]
|
||||||
INT_L_X10Y102.CENTER_INTER_L.IMUX_L1 EE2END0
|
INT_L_X10Y102.IMUX_L1 EE2END0
|
||||||
# din[1]
|
# din[1]
|
||||||
INT_L_X10Y102.CENTER_INTER_L.IMUX_L2 EE2END1
|
INT_L_X10Y102.IMUX_L2 EE2END1
|
||||||
# din[2]
|
# din[2]
|
||||||
INT_L_X10Y102.CENTER_INTER_L.IMUX_L4 EE2END2
|
INT_L_X10Y102.IMUX_L4 EE2END2
|
||||||
# din[3]
|
# din[3]
|
||||||
INT_L_X10Y102.CENTER_INTER_L.IMUX_L7 EE2END3
|
INT_L_X10Y102.IMUX_L7 EE2END3
|
||||||
# din[4]
|
# din[4]
|
||||||
INT_L_X10Y102.CENTER_INTER_L.IMUX_L8 EL1END0
|
INT_L_X10Y102.IMUX_L8 EL1END0
|
||||||
# din[5]
|
# din[5]
|
||||||
INT_L_X10Y102.CENTER_INTER_L.IMUX_L11 EL1END1
|
INT_L_X10Y102.IMUX_L11 EL1END1
|
||||||
|
|
||||||
# dout[0]
|
# dout[0]
|
||||||
INT_L_X10Y102.CENTER_INTER_L.WW2BEG0 LOGIC_OUTS_L12
|
INT_L_X10Y102.WW2BEG0 LOGIC_OUTS_L12
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
# TODO: need better coverage for different tile types
|
||||||
|
|
||||||
import fasm2frame
|
import fasm2frame
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
|
|
@ -74,6 +76,63 @@ class TestStringMethods(unittest.TestCase):
|
||||||
self.bitread_frm_equals(
|
self.bitread_frm_equals(
|
||||||
'test_data/ff_int.fasm', 'test_data/ff_int/design.bits')
|
'test_data/ff_int.fasm', 'test_data/ff_int/design.bits')
|
||||||
|
|
||||||
|
def test_ff_int_op1(self):
|
||||||
|
'''Omitted key set to '''
|
||||||
|
self.bitread_frm_equals(
|
||||||
|
'test_data/ff_int_op1.fasm', 'test_data/ff_int/design.bits')
|
||||||
|
|
||||||
|
# Same check as above, but isolated test case
|
||||||
|
def test_opkey_01_default(self):
|
||||||
|
'''Optional key with binary omitted value should produce valid result'''
|
||||||
|
fin = StringIO.StringIO("CLBLM_L_X10Y102.SLICEM_X0.SRUSEDMUX")
|
||||||
|
fout = StringIO.StringIO()
|
||||||
|
fasm2frame.run(fin, fout)
|
||||||
|
|
||||||
|
def test_opkey_01_1(self):
|
||||||
|
fin = StringIO.StringIO("CLBLM_L_X10Y102.SLICEM_X0.SRUSEDMUX 1")
|
||||||
|
fout = StringIO.StringIO()
|
||||||
|
fasm2frame.run(fin, fout)
|
||||||
|
|
||||||
|
def test_opkey_enum(self):
|
||||||
|
'''Optional key with enumerated value should produce syntax error'''
|
||||||
|
# CLBLM_L.SLICEM_X0.AMUX.O6 !30_06 !30_07 !30_08 30_11
|
||||||
|
fin = StringIO.StringIO("CLBLM_L_X10Y102.SLICEM_X0.AMUX.O6")
|
||||||
|
fout = StringIO.StringIO()
|
||||||
|
try:
|
||||||
|
fasm2frame.run(fin, fout)
|
||||||
|
self.fail("Expected syntax error")
|
||||||
|
except fasm2frame.FASMSyntaxError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_ff_int_0s(self):
|
||||||
|
'''Explicit 0 entries'''
|
||||||
|
self.bitread_frm_equals(
|
||||||
|
'test_data/ff_int_0s.fasm', 'test_data/ff_int/design.bits')
|
||||||
|
|
||||||
|
def test_badkey(self):
|
||||||
|
'''Bad key should throw syntax error'''
|
||||||
|
fin = StringIO.StringIO("CLBLM_L_X10Y102.SLICEM_X0.SRUSEDMUX 2")
|
||||||
|
fout = StringIO.StringIO()
|
||||||
|
try:
|
||||||
|
fasm2frame.run(fin, fout)
|
||||||
|
self.fail("Expected syntax error")
|
||||||
|
except fasm2frame.FASMSyntaxError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_dupkey(self):
|
||||||
|
'''Duplicate key should throw syntax error'''
|
||||||
|
fin = StringIO.StringIO(
|
||||||
|
"""\
|
||||||
|
CLBLM_L_X10Y102.SLICEM_X0.SRUSEDMUX 0
|
||||||
|
CLBLM_L_X10Y102.SLICEM_X0.SRUSEDMUX 1
|
||||||
|
""")
|
||||||
|
fout = StringIO.StringIO()
|
||||||
|
try:
|
||||||
|
fasm2frame.run(fin, fout)
|
||||||
|
self.fail("Expected syntax error")
|
||||||
|
except fasm2frame.FASMSyntaxError:
|
||||||
|
pass
|
||||||
|
|
||||||
def test_sparse(self):
|
def test_sparse(self):
|
||||||
'''Verify sparse equivilent to normal encoding'''
|
'''Verify sparse equivilent to normal encoding'''
|
||||||
frm_fn = 'test_data/lut_int.fasm'
|
frm_fn = 'test_data/lut_int.fasm'
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue