diff --git a/tools/fasm2frame.py b/tools/fasm2frame.py index a21aa330..c4e845a3 100755 --- a/tools/fasm2frame.py +++ b/tools/fasm2frame.py @@ -4,9 +4,36 @@ import os import re import sys 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() @@ -16,25 +43,48 @@ def get_database(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"), os.getenv("XRAY_DATABASE"), segtype), "r") as f: for line in f: - # CLBLM_L.SLICEL_X1.ALUT.INIT[10] 29_14 - parts = line.split() - name = parts[0] - vals = parts[1:] - segbitsdb[segtype][name] = vals + 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: - # CLBLM_L.SLICEL_X1.ALUT.INIT[10] 29_14 - parts = line.split() - name = parts[0] - vals = parts[1:] - segbitsdb[segtype][name] = vals + process(line) return segbitsdb[segtype] @@ -79,6 +129,10 @@ def dump_frm(f, frames): 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 frames_init(): '''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''' 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"), os.getenv("XRAY_DATABASE")), "r") as f: grid = json.load(f) @@ -105,7 +163,7 @@ def run(f_in, f_out, sparse=False, debug=False): # Initiaize bitstream to 0 frames_init() - for l in f_in: + for line_number, l in enumerate(f_in, 1): # Comment # Remove all text including and after # i = l.rfind('#') @@ -119,16 +177,22 @@ def run(f_in, f_out, sparse=False, debug=False): # tile.site.stuff value # INT_L_X10Y102.CENTER_INTER_L.IMUX_L1 EE2END0 - m = re.match( - r'([a-zA-Z0-9_]+)[.]([a-zA-Z0-9_]+)[.]([a-zA-Z0-9_.\[\]]+)[ ](.+)', - l) + # Optional value + m = re.match(r'([a-zA-Z0-9_]+)[.]([a-zA-Z0-9_.\[\]]+)([ ](.+))?', l) if not m: - raise Exception("Bad line: %s" % l) + raise FASMSyntaxError("Bad line: %s" % l) tile = m.group(1) - site = m.group(2) - suffix = m.group(3) + 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] @@ -140,80 +204,46 @@ def run(f_in, f_out, sparse=False, debug=False): for coli in range(segj['frames']): frame_init(seg_baseaddr + coli) - # Now lets look up the bits we need frames for - segdb = get_database(segj['type']) - - def clb2dbkey(tile, tilej, site, suffix, value): - def slice_global2x01(tile_name, tile_type, site): - # SLICE_X12Y102 => SLICEL_X0 - m = re.match(r'SLICE_X([0-9]+)Y[0-9]+', site) - xg = int(m.group(1)) - - prefix = { - 'CLBLL_L': { - 0: 'SLICEL', - 1: 'SLICEL' - }, - 'CLBLM_L': { - 0: 'SLICEM', - 1: 'SLICEL' - }, - 'CLBLL_R': { - 0: 'SLICEL', - 1: 'SLICEL' - }, - 'CLBLM_R': { - 0: 'SLICEM', - 1: 'SLICEL' - }, - } - x01 = xg % 2 - return '%s_X%d' % (prefix[tile_type][x01], x01) - - db_site = slice_global2x01(tile, tilej['type'], site) - db_k = '%s.%s.%s' % (tilej['type'], db_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) + 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 - frame_set(frame_addr, word_addr, bit_index) + if isset: + 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: #dump_frames_verbose(frames) diff --git a/tools/segprint2fasm.py b/tools/segprint2fasm.py index d0732888..5906044f 100755 --- a/tools/segprint2fasm.py +++ b/tools/segprint2fasm.py @@ -5,47 +5,50 @@ import re import sys 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): '''Given tilegrid, segment name and tag, return fasm directive''' segj = grid['segments'][seg] - def clbf(seg, tile, tag_post): - # seg: SEG_CLBLM_L_X10Y102 - # tile_type: CLBLM_L - # tag_post: SLICEM_X0.ALUT.INIT[43] - # To: CLBLM_L_X10Y102.SLICE_X12Y102.ALUT.INIT[43] 1 - m = re.match(r'(SLICE[LM])_X([01])[.](.*)', tag_post) - slicelm = m.group(1) - off01 = int(m.group(2)) - post = m.group(3) - - # xxx: actually this might not work on decimal overflow (9 => 10) - for site in grid['tiles'][tile]['sites'].keys(): - m = re.match(r'SLICE_X(.*)Y.*', site) - sitex = int(m.group(1)) - if sitex % 2 == off01: - break - else: - raise Exception("Failed to match site") - - return '%s.%s.%s 1' % (tile, site, 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) tile_type = m.group(1) tag_post = m.group(2) @@ -57,20 +60,14 @@ def tag2fasm(grid, seg, tag): else: raise Exception("Couldn't find tile type %s" % tile_type) - tag2asm = { - 'CLBLL_L': clbf, - 'CLBLL_R': clbf, - 'CLBLM_L': clbf, - 'CLBLM_R': clbf, - 'INT_L': intf, - 'INT_R': intf, - 'HCLK_L': intf, - '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) + if not isenum(segj['type'], tag): + return '%s.%s 1' % (tile, tag_post) + else: + # 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) + return '%s.%s %s' % (tile, which, value) def run(f_in, f_out, sparse=False): diff --git a/tools/test_data/ff_int.fasm b/tools/test_data/ff_int.fasm index 222423ee..4406ed65 100644 --- a/tools/test_data/ff_int.fasm +++ b/tools/test_data/ff_int.fasm @@ -2,23 +2,22 @@ # segprint -zd test_data/clb_ff/design.bits # FF as LDCE -CLBLM_L_X10Y102.SLICE_X12Y102.AFF.DMUX.AX 1 -CLBLM_L_X10Y102.SLICE_X12Y102.AFF.ZINI 1 -CLBLM_L_X10Y102.SLICE_X12Y102.AFF.ZRST 1 -CLBLM_L_X10Y102.SLICE_X12Y102.CEUSEDMUX 1 -CLBLM_L_X10Y102.SLICE_X12Y102.SRUSEDMUX 1 -# CLBLM_L_X10Y102.SLICE_X12Y102.FFSYNC 0 -# CLBLM_L_X10Y102.SLICE_X12Y102.LATCH 0 +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 +CLBLM_L_X10Y102.SLICEM_X0.SRUSEDMUX 1 # Note: a number of pseudo pips here # Omitted -INT_L_X10Y102.CENTER_INTER_L.BYP_ALT0 EE2END0 -INT_L_X10Y102.CENTER_INTER_L.BYP_ALT1 EL1END1 -INT_L_X10Y102.CENTER_INTER_L.CLK_L1 GCLK_L_B11_WEST -INT_L_X10Y102.CENTER_INTER_L.CTRL_L1 ER1END2 -INT_L_X10Y102.CENTER_INTER_L.FAN_ALT7 BYP_BOUNCE0 -INT_L_X10Y102.CENTER_INTER_L.WW2BEG0 LOGIC_OUTS_L4 +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.HCLK_L.ENABLE_BUFFER HCLK_CK_BUFHCLK8 -HCLK_L_X31Y130.HCLK_L.HCLK_LEAF_CLK_B_BOTL5 HCLK_CK_BUFHCLK8 +HCLK_L_X31Y130.ENABLE_BUFFER.HCLK_CK_BUFHCLK8 1 +HCLK_L_X31Y130.HCLK_LEAF_CLK_B_BOTL5 HCLK_CK_BUFHCLK8 diff --git a/tools/test_data/clb_ff/.gitignore b/tools/test_data/ff_int/.gitignore similarity index 100% rename from tools/test_data/clb_ff/.gitignore rename to tools/test_data/ff_int/.gitignore diff --git a/tools/test_data/clb_ff/design.bits b/tools/test_data/ff_int/design.bits similarity index 100% rename from tools/test_data/clb_ff/design.bits rename to tools/test_data/ff_int/design.bits diff --git a/tools/test_data/clb_ff/design.segp b/tools/test_data/ff_int/design.segp similarity index 100% rename from tools/test_data/clb_ff/design.segp rename to tools/test_data/ff_int/design.segp diff --git a/tools/test_data/clb_ff/top.v b/tools/test_data/ff_int/top.v similarity index 100% rename from tools/test_data/clb_ff/top.v rename to tools/test_data/ff_int/top.v diff --git a/tools/test_data/ff_int_0s.fasm b/tools/test_data/ff_int_0s.fasm new file mode 100644 index 00000000..3f113f7d --- /dev/null +++ b/tools/test_data/ff_int_0s.fasm @@ -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 + diff --git a/tools/test_data/ff_int_op1.fasm b/tools/test_data/ff_int_op1.fasm new file mode 100644 index 00000000..c77b5ffc --- /dev/null +++ b/tools/test_data/ff_int_op1.fasm @@ -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 + diff --git a/tools/test_data/lut.fasm b/tools/test_data/lut.fasm index e4975449..0bb7c941 100644 --- a/tools/test_data/lut.fasm +++ b/tools/test_data/lut.fasm @@ -1,15 +1,15 @@ # LUT -CLBLM_L_X10Y102.SLICE_X12Y102.ALUT.INIT[00] 1 -CLBLM_L_X10Y102.SLICE_X12Y102.ALUT.INIT[08] 1 -CLBLM_L_X10Y102.SLICE_X12Y102.ALUT.INIT[10] 1 -CLBLM_L_X10Y102.SLICE_X12Y102.ALUT.INIT[11] 1 -CLBLM_L_X10Y102.SLICE_X12Y102.ALUT.INIT[13] 1 -CLBLM_L_X10Y102.SLICE_X12Y102.ALUT.INIT[14] 1 -CLBLM_L_X10Y102.SLICE_X12Y102.ALUT.INIT[15] 1 -CLBLM_L_X10Y102.SLICE_X12Y102.ALUT.INIT[41] 1 -CLBLM_L_X10Y102.SLICE_X12Y102.ALUT.INIT[43] 1 -CLBLM_L_X10Y102.SLICE_X12Y102.ALUT.INIT[44] 1 -CLBLM_L_X10Y102.SLICE_X12Y102.ALUT.INIT[46] 1 -CLBLM_L_X10Y102.SLICE_X12Y102.ALUT.INIT[47] 1 -CLBLM_L_X10Y102.SLICE_X12Y102.ALUT.INIT[63] 1 +CLBLM_L_X10Y102.SLICEM_X0.ALUT.INIT[00] 1 +CLBLM_L_X10Y102.SLICEM_X0.ALUT.INIT[08] 1 +CLBLM_L_X10Y102.SLICEM_X0.ALUT.INIT[10] 1 +CLBLM_L_X10Y102.SLICEM_X0.ALUT.INIT[11] 1 +CLBLM_L_X10Y102.SLICEM_X0.ALUT.INIT[13] 1 +CLBLM_L_X10Y102.SLICEM_X0.ALUT.INIT[14] 1 +CLBLM_L_X10Y102.SLICEM_X0.ALUT.INIT[15] 1 +CLBLM_L_X10Y102.SLICEM_X0.ALUT.INIT[41] 1 +CLBLM_L_X10Y102.SLICEM_X0.ALUT.INIT[43] 1 +CLBLM_L_X10Y102.SLICEM_X0.ALUT.INIT[44] 1 +CLBLM_L_X10Y102.SLICEM_X0.ALUT.INIT[46] 1 +CLBLM_L_X10Y102.SLICEM_X0.ALUT.INIT[47] 1 +CLBLM_L_X10Y102.SLICEM_X0.ALUT.INIT[63] 1 diff --git a/tools/test_data/lut_int.fasm b/tools/test_data/lut_int.fasm index b4e32fd5..0fca2026 100644 --- a/tools/test_data/lut_int.fasm +++ b/tools/test_data/lut_int.fasm @@ -2,34 +2,34 @@ # segprint -zd test_data/clb_lut/design.bits # LUT -CLBLM_L_X10Y102.SLICE_X12Y102.ALUT.INIT[00] 1 -CLBLM_L_X10Y102.SLICE_X12Y102.ALUT.INIT[08] 1 -CLBLM_L_X10Y102.SLICE_X12Y102.ALUT.INIT[10] 1 -CLBLM_L_X10Y102.SLICE_X12Y102.ALUT.INIT[11] 1 -CLBLM_L_X10Y102.SLICE_X12Y102.ALUT.INIT[13] 1 -CLBLM_L_X10Y102.SLICE_X12Y102.ALUT.INIT[14] 1 -CLBLM_L_X10Y102.SLICE_X12Y102.ALUT.INIT[15] 1 -CLBLM_L_X10Y102.SLICE_X12Y102.ALUT.INIT[41] 1 -CLBLM_L_X10Y102.SLICE_X12Y102.ALUT.INIT[43] 1 -CLBLM_L_X10Y102.SLICE_X12Y102.ALUT.INIT[44] 1 -CLBLM_L_X10Y102.SLICE_X12Y102.ALUT.INIT[46] 1 -CLBLM_L_X10Y102.SLICE_X12Y102.ALUT.INIT[47] 1 -CLBLM_L_X10Y102.SLICE_X12Y102.ALUT.INIT[63] 1 +CLBLM_L_X10Y102.SLICEM_X0.ALUT.INIT[00] 1 +CLBLM_L_X10Y102.SLICEM_X0.ALUT.INIT[08] 1 +CLBLM_L_X10Y102.SLICEM_X0.ALUT.INIT[10] 1 +CLBLM_L_X10Y102.SLICEM_X0.ALUT.INIT[11] 1 +CLBLM_L_X10Y102.SLICEM_X0.ALUT.INIT[13] 1 +CLBLM_L_X10Y102.SLICEM_X0.ALUT.INIT[14] 1 +CLBLM_L_X10Y102.SLICEM_X0.ALUT.INIT[15] 1 +CLBLM_L_X10Y102.SLICEM_X0.ALUT.INIT[41] 1 +CLBLM_L_X10Y102.SLICEM_X0.ALUT.INIT[43] 1 +CLBLM_L_X10Y102.SLICEM_X0.ALUT.INIT[44] 1 +CLBLM_L_X10Y102.SLICEM_X0.ALUT.INIT[46] 1 +CLBLM_L_X10Y102.SLICEM_X0.ALUT.INIT[47] 1 +CLBLM_L_X10Y102.SLICEM_X0.ALUT.INIT[63] 1 # din bus # din[0] -INT_L_X10Y102.CENTER_INTER_L.IMUX_L1 EE2END0 +INT_L_X10Y102.IMUX_L1 EE2END0 # din[1] -INT_L_X10Y102.CENTER_INTER_L.IMUX_L2 EE2END1 +INT_L_X10Y102.IMUX_L2 EE2END1 # din[2] -INT_L_X10Y102.CENTER_INTER_L.IMUX_L4 EE2END2 +INT_L_X10Y102.IMUX_L4 EE2END2 # din[3] -INT_L_X10Y102.CENTER_INTER_L.IMUX_L7 EE2END3 +INT_L_X10Y102.IMUX_L7 EE2END3 # din[4] -INT_L_X10Y102.CENTER_INTER_L.IMUX_L8 EL1END0 +INT_L_X10Y102.IMUX_L8 EL1END0 # din[5] -INT_L_X10Y102.CENTER_INTER_L.IMUX_L11 EL1END1 +INT_L_X10Y102.IMUX_L11 EL1END1 # dout[0] -INT_L_X10Y102.CENTER_INTER_L.WW2BEG0 LOGIC_OUTS_L12 +INT_L_X10Y102.WW2BEG0 LOGIC_OUTS_L12 diff --git a/tools/test_data/clb_lut/.gitignore b/tools/test_data/lut_int/.gitignore similarity index 100% rename from tools/test_data/clb_lut/.gitignore rename to tools/test_data/lut_int/.gitignore diff --git a/tools/test_data/clb_lut/design.bits b/tools/test_data/lut_int/design.bits similarity index 100% rename from tools/test_data/clb_lut/design.bits rename to tools/test_data/lut_int/design.bits diff --git a/tools/test_data/clb_lut/design.segp b/tools/test_data/lut_int/design.segp similarity index 100% rename from tools/test_data/clb_lut/design.segp rename to tools/test_data/lut_int/design.segp diff --git a/tools/test_data/clb_lut/top.v b/tools/test_data/lut_int/top.v similarity index 100% rename from tools/test_data/clb_lut/top.v rename to tools/test_data/lut_int/top.v diff --git a/tools/test_fasm2frame.py b/tools/test_fasm2frame.py index 4d6ef4f8..27c2815c 100644 --- a/tools/test_fasm2frame.py +++ b/tools/test_fasm2frame.py @@ -1,3 +1,5 @@ +# TODO: need better coverage for different tile types + import fasm2frame import unittest @@ -68,11 +70,68 @@ class TestStringMethods(unittest.TestCase): def test_lut_int(self): self.bitread_frm_equals( - 'test_data/lut_int.fasm', 'test_data/clb_lut/design.bits') + 'test_data/lut_int.fasm', 'test_data/lut_int/design.bits') def test_ff_int(self): self.bitread_frm_equals( - 'test_data/ff_int.fasm', 'test_data/clb_ff/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): '''Verify sparse equivilent to normal encoding''' diff --git a/tools/test_segprint2fasm.py b/tools/test_segprint2fasm.py index 14b3b401..9865c9f4 100644 --- a/tools/test_segprint2fasm.py +++ b/tools/test_segprint2fasm.py @@ -33,11 +33,11 @@ class TestStringMethods(unittest.TestCase): def test_lut_int(self): self.check_segprint_fasm_equiv( - 'test_data/clb_lut/design.segp', 'test_data/lut_int.fasm') + 'test_data/lut_int/design.segp', 'test_data/lut_int.fasm') def test_ff_int(self): self.check_segprint_fasm_equiv( - 'test_data/clb_ff/design.segp', 'test_data/ff_int.fasm') + 'test_data/ff_int/design.segp', 'test_data/ff_int.fasm') if __name__ == '__main__':