Merge pull request #51 from mcmasterg/segprint2fasm

Segprint2fasm
This commit is contained in:
Rick Altherr 2018-01-18 16:56:51 -08:00 committed by GitHub
commit d587030ea5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 200 additions and 2 deletions

View File

@ -231,8 +231,16 @@ if __name__ == '__main__':
'--sparse', action='store_true', help="Don't zero fill all frames")
parser.add_argument(
'--debug', action='store_true', help="Print debug dump")
parser.add_argument('fn_in', help='Input FPGA assembly (.fasm) file')
parser.add_argument('fn_out', help='Output FPGA frame (.frm) file')
parser.add_argument(
'fn_in',
default='/dev/stdin',
nargs='?',
help='Input FPGA assembly (.fasm) file')
parser.add_argument(
'fn_out',
default='/dev/stdout',
nargs='?',
help='Output FPGA frame (.frm) file')
args = parser.parse_args()
run(

107
tools/segprint2fasm.py Normal file
View File

@ -0,0 +1,107 @@
#!/usr/bin/env python3
import os
import re
import sys
import json
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 = {
'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)
# Find associated tile
for tile in segj['tiles']:
if grid['tiles'][tile]['type'] == tile_type:
break
else:
raise Exception("Couldn't find tile type %s" % tile_type)
tag2asm = {
'CLBLM_L': clbf,
'CLBLM_R': clbf,
'INT_L': intf,
'INT_R': intf,
'HCLK_L': intf,
}
f = tag2asm.get(tile_type, None)
if f is None:
raise Exception("Unhandled segment type %s" % tilej['type'])
return f(seg, tile, tag_post)
def run(f_in, f_out, sparse=False):
with open("%s/%s/tilegrid.json" % (os.getenv("XRAY_DATABASE_DIR"),
os.getenv("XRAY_DATABASE")), "r") as f:
grid = json.load(f)
seg = None
for l in f_in:
l = l.strip()
if not l:
continue
# seg SEG_CLBLM_L_X10Y102
# tag CLBLM_L.SLICEM_X0.ALUT.INIT[00]
m = re.match('(seg|tag) (.*)', l)
if not m:
raise Exception("Invalid line %s" % l)
type = m.group(1)
if type == 'seg':
seg = m.group(2)
elif type == 'tag':
f_out.write(tag2fasm(grid, seg, m.group(2)) + '\n')
else:
raise Exception("Invalid type %s" % type)
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser(
description='Convert segprint -d output to .fasm file (FPGA assembly)')
parser.add_argument(
'fn_in', default='/dev/stdin', nargs='?', help='Input segment file')
parser.add_argument(
'fn_out', default='/dev/stdout', nargs='?', help='Output .fasm file')
args = parser.parse_args()
run(open(args.fn_in, 'r'), open(args.fn_out, 'w'))

View File

@ -0,0 +1,17 @@
seg SEG_HCLK_L_X31Y130
tag HCLK_L.ENABLE_BUFFER.HCLK_CK_BUFHCLK8
tag HCLK_L.HCLK_LEAF_CLK_B_BOTL5.HCLK_CK_BUFHCLK8
seg SEG_CLBLM_L_X10Y102
tag CLBLM_L.SLICEM_X0.AFF.DMUX.AX
tag CLBLM_L.SLICEM_X0.AFF.ZINI
tag CLBLM_L.SLICEM_X0.AFF.ZRST
tag CLBLM_L.SLICEM_X0.CEUSEDMUX
tag CLBLM_L.SLICEM_X0.SRUSEDMUX
tag INT_L.BYP_ALT0.EE2END0
tag INT_L.BYP_ALT1.EL1END1
tag INT_L.CLK_L1.GCLK_L_B11_WEST
tag INT_L.CTRL_L1.ER1END2
tag INT_L.FAN_ALT7.BYP_BOUNCE0
tag INT_L.WW2BEG0.LOGIC_OUTS_L4

View File

@ -0,0 +1,22 @@
seg SEG_CLBLM_L_X10Y102
tag CLBLM_L.SLICEM_X0.ALUT.INIT[00]
tag CLBLM_L.SLICEM_X0.ALUT.INIT[08]
tag CLBLM_L.SLICEM_X0.ALUT.INIT[10]
tag CLBLM_L.SLICEM_X0.ALUT.INIT[11]
tag CLBLM_L.SLICEM_X0.ALUT.INIT[13]
tag CLBLM_L.SLICEM_X0.ALUT.INIT[14]
tag CLBLM_L.SLICEM_X0.ALUT.INIT[15]
tag CLBLM_L.SLICEM_X0.ALUT.INIT[41]
tag CLBLM_L.SLICEM_X0.ALUT.INIT[43]
tag CLBLM_L.SLICEM_X0.ALUT.INIT[44]
tag CLBLM_L.SLICEM_X0.ALUT.INIT[46]
tag CLBLM_L.SLICEM_X0.ALUT.INIT[47]
tag CLBLM_L.SLICEM_X0.ALUT.INIT[63]
tag INT_L.IMUX_L1.EE2END0
tag INT_L.IMUX_L11.EL1END1
tag INT_L.IMUX_L2.EE2END1
tag INT_L.IMUX_L4.EE2END2
tag INT_L.IMUX_L7.EE2END3
tag INT_L.IMUX_L8.EL1END0
tag INT_L.WW2BEG0.LOGIC_OUTS_L12

View File

@ -0,0 +1,44 @@
import segprint2fasm
import unittest
import StringIO
import re
class TestStringMethods(unittest.TestCase):
def check_segprint_fasm_equiv(self, segp_fn, fasm_fn):
fout = StringIO.StringIO()
segprint2fasm.run(open(segp_fn, 'r'), fout)
fasm_out = fout.getvalue()
fasm_ref = open(fasm_fn, 'r').read()
def normalize(fasm):
'''Remove all comments and sort'''
ret = []
for l in fasm.split('\n'):
# Remove comments
i = l.rfind('#')
if i >= 0:
l = l[0:i]
l = l.strip()
if not l:
continue
ret.append(l)
return sorted(ret)
fasm_out = normalize(fasm_out)
fasm_ref = normalize(fasm_ref)
self.assertEquals(fasm_ref, fasm_out)
def test_lut_int(self):
self.check_segprint_fasm_equiv(
'test_data/clb_lut/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')
if __name__ == '__main__':
unittest.main()