mirror of https://github.com/openXC7/prjxray.git
Merge pull request #900 from litghost/extend_zero_db_features
Add support to zero db to support simple groups.
This commit is contained in:
commit
bc3fcb0db2
|
|
@ -23,14 +23,29 @@ SEGBITS=\
|
||||||
hclk \
|
hclk \
|
||||||
int \
|
int \
|
||||||
|
|
||||||
DB_SIMPLE=$(addprefix mask_,$(MASKS)) $(addprefix ppips_,$(PPIPS)) $(addprefix segbits_,$(SEGBITS))
|
SEGBITS_R=\
|
||||||
|
clk_bufg_top \
|
||||||
|
clk_bufg_bot \
|
||||||
|
$(SEGBITS)
|
||||||
|
|
||||||
# Extra (segbits|mask)_bram_(l|r).block_ram.db files
|
SEGBITS_L=\
|
||||||
# FIXME: Are these things also needed for the DSP blocks?
|
$(SEGBITS)
|
||||||
BLOCK_RAM_EXTRA_FOR=mask_bram segbits_bram
|
|
||||||
BLOCK_RAM_EXTRA_DB_FILES=$(addsuffix .block_ram.db,$(addsuffix _l,$(BLOCK_RAM_EXTRA_FOR)) $(addsuffix _r,$(BLOCK_RAM_EXTRA_FOR)))
|
|
||||||
|
|
||||||
DB_FILES=$(sort $(addsuffix _l.db,$(DB_SIMPLE)) $(addsuffix _r.db,$(DB_SIMPLE)) $(BLOCK_RAM_EXTRA_DB_FILES))
|
DB_SIMPLE_LR=$(addprefix mask_,$(MASKS)) $(addprefix ppips_,$(PPIPS))
|
||||||
|
DB_SIMPLE_L=$(addprefix segbits_,$(SEGBITS_L))
|
||||||
|
DB_SIMPLE_R=$(addprefix segbits_,$(SEGBITS_R))
|
||||||
|
DB_SIMPLE=\
|
||||||
|
$(addsuffix _l, $(DB_SIMPLE_LR) $(DB_SIMPLE_L)) \
|
||||||
|
$(addsuffix _r, $(DB_SIMPLE_LR) $(DB_SIMPLE_R))
|
||||||
|
|
||||||
|
BLOCK_RAM_EXTRA_FOR=\
|
||||||
|
mask_bram \
|
||||||
|
segbits_bram
|
||||||
|
BLOCK_RAM_EXTRA_DB_FILES=\
|
||||||
|
$(addsuffix .block_ram.db,$(addsuffix _l,$(BLOCK_RAM_EXTRA_FOR)) $(addsuffix _r,$(BLOCK_RAM_EXTRA_FOR)))
|
||||||
|
|
||||||
|
|
||||||
|
DB_FILES=$(sort $(addsuffix .origin_info.db,$(DB_SIMPLE)) $(addsuffix .db,$(DB_SIMPLE)) $(BLOCK_RAM_EXTRA_DB_FILES))
|
||||||
DB_FILES_PATH=$(addprefix $(XRAY_DATABASE_DIR)/$(XRAY_DATABASE)/,$(DB_FILES))
|
DB_FILES_PATH=$(addprefix $(XRAY_DATABASE_DIR)/$(XRAY_DATABASE)/,$(DB_FILES))
|
||||||
|
|
||||||
check:
|
check:
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
N := 1
|
N := 1
|
||||||
|
CLB_DBFIXUP=Y
|
||||||
include ../clb.mk
|
include ../clb.mk
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
# NOCLKINV is inverse of CLKINV
|
||||||
|
CLB.SLICE_X0.CLKINV ^ CLB.SLICE_X0.NOCLKINV
|
||||||
|
CLB.SLICE_X1.CLKINV ^ CLB.SLICE_X1.NOCLKINV
|
||||||
|
|
@ -94,8 +94,10 @@ with open("design.txt", "r") as f:
|
||||||
# CLKINV turns out to be more complicated than origianlly thought
|
# CLKINV turns out to be more complicated than origianlly thought
|
||||||
if isff(cel_prim):
|
if isff(cel_prim):
|
||||||
segmk.add_site_tag(site, "CLKINV", cinv)
|
segmk.add_site_tag(site, "CLKINV", cinv)
|
||||||
|
segmk.add_site_tag(site, "NOCLKINV", 1 ^ cinv)
|
||||||
else:
|
else:
|
||||||
segmk.add_site_tag(site, "CLKINV", 1 ^ cinv)
|
segmk.add_site_tag(site, "CLKINV", 1 ^ cinv)
|
||||||
|
segmk.add_site_tag(site, "NOCLKINV", cinv)
|
||||||
|
|
||||||
# Synchronous vs asynchronous FF
|
# Synchronous vs asynchronous FF
|
||||||
# Unlike most bits, shared between all CLB FFs
|
# Unlike most bits, shared between all CLB FFs
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
N := 3
|
N := 3
|
||||||
SLICEL ?= N
|
SLICEL ?= N
|
||||||
|
CLB_DBFIXUP=Y
|
||||||
include ../clb.mk
|
include ../clb.mk
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
CLB.SLICE_X0.ALUT.DI1MUX.AI ^ CLB.SLICE_X0.ALUT.DI1MUX.BDI1_BMC31
|
||||||
|
CLB.SLICE_X0.BLUT.DI1MUX.BI ^ CLB.SLICE_X0.BLUT.DI1MUX.DI_CMC31
|
||||||
|
CLB.SLICE_X0.CLUT.DI1MUX.CI ^ CLB.SLICE_X0.CLUT.DI1MUX.DI_DMC31
|
||||||
|
|
@ -25,8 +25,11 @@ for l in f:
|
||||||
b31 = int(b31)
|
b31 = int(b31)
|
||||||
a31 = int(a31)
|
a31 = int(a31)
|
||||||
segmk.add_site_tag(loc, "ALUT.DI1MUX.AI", 1 ^ a31)
|
segmk.add_site_tag(loc, "ALUT.DI1MUX.AI", 1 ^ a31)
|
||||||
|
segmk.add_site_tag(loc, "ALUT.DI1MUX.BDI1_BMC31", a31)
|
||||||
segmk.add_site_tag(loc, "BLUT.DI1MUX.BI", 1 ^ b31)
|
segmk.add_site_tag(loc, "BLUT.DI1MUX.BI", 1 ^ b31)
|
||||||
|
segmk.add_site_tag(loc, "BLUT.DI1MUX.DI_CMC31", b31)
|
||||||
segmk.add_site_tag(loc, "CLUT.DI1MUX.CI", 1 ^ c31)
|
segmk.add_site_tag(loc, "CLUT.DI1MUX.CI", 1 ^ c31)
|
||||||
|
segmk.add_site_tag(loc, "CLUT.DI1MUX.DI_DMC31", c31)
|
||||||
|
|
||||||
segmk.compile()
|
segmk.compile()
|
||||||
segmk.write()
|
segmk.write()
|
||||||
|
|
|
||||||
146
utils/dbfixup.py
146
utils/dbfixup.py
|
|
@ -51,10 +51,27 @@ def bits_str(bits):
|
||||||
return ' '.join(sorted(list(bits)))
|
return ' '.join(sorted(list(bits)))
|
||||||
|
|
||||||
|
|
||||||
def zero_groups(tag, bits, zero_db, strict=True, verbose=False):
|
class ZeroGroups(object):
|
||||||
"""
|
def __init__(self, zero_db):
|
||||||
See if a line occurs within a bit group
|
self.groups = []
|
||||||
If it does, add 0 bits
|
self.bit_to_group = {}
|
||||||
|
self.tag_to_groups = {}
|
||||||
|
self.zero_tag_to_group = {}
|
||||||
|
self.parse_zero_db(zero_db)
|
||||||
|
|
||||||
|
def print_groups(self):
|
||||||
|
print('Zero groups:')
|
||||||
|
for bits in self.groups:
|
||||||
|
print(bits_str(bits))
|
||||||
|
|
||||||
|
print('Zero tags:')
|
||||||
|
for tag in self.zero_tag_to_group:
|
||||||
|
print(tag, bits_str(self.zero_tag_to_group[tag]))
|
||||||
|
|
||||||
|
def parse_zero_db(self, zero_db):
|
||||||
|
""" Convert zero db format into data structure
|
||||||
|
|
||||||
|
Zero db format examples:
|
||||||
|
|
||||||
Ex: 01_02 04_05
|
Ex: 01_02 04_05
|
||||||
Means find a line that has either of these bits
|
Means find a line that has either of these bits
|
||||||
|
|
@ -68,9 +85,29 @@ def zero_groups(tag, bits, zero_db, strict=True, verbose=False):
|
||||||
ALL_ZERO is an enum that is part of the group but is all 0
|
ALL_ZERO is an enum that is part of the group but is all 0
|
||||||
It must have 0 candidates
|
It must have 0 candidates
|
||||||
|
|
||||||
strict: assert that the size of the given group is the size of the given mask
|
Ex: CLB.SLICE_X0.CLKINV ^ CLB.SLICE_X0.NOCLKINV
|
||||||
|
CLB.SLICE_X0.NOCLKINV is all bits in CLB.SLICE_X0.CLKINV unset
|
||||||
|
|
||||||
|
Ex: A | B ^ C
|
||||||
|
C is all bits in (A)|(B) unset
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
for zdb in zero_db:
|
for zdb in zero_db:
|
||||||
|
|
||||||
|
if "^" in zdb:
|
||||||
|
self.groups.append(set())
|
||||||
|
zero_group = self.groups[-1]
|
||||||
|
|
||||||
|
other_tags, allzero_tag = zdb.split('^')
|
||||||
|
allzero_tag = allzero_tag.strip()
|
||||||
|
|
||||||
|
for tag in other_tags.split():
|
||||||
|
self.tag_to_groups[tag.strip()] = [zero_group]
|
||||||
|
|
||||||
|
self.zero_tag_to_group[allzero_tag] = zero_group
|
||||||
|
continue
|
||||||
|
|
||||||
allzero_tag = None
|
allzero_tag = None
|
||||||
if "," in zdb:
|
if "," in zdb:
|
||||||
zdb, allzero_tag = zdb.split(",")
|
zdb, allzero_tag = zdb.split(",")
|
||||||
|
|
@ -79,29 +116,87 @@ def zero_groups(tag, bits, zero_db, strict=True, verbose=False):
|
||||||
a, b = zdb.split("|")
|
a, b = zdb.split("|")
|
||||||
a = a.split()
|
a = a.split()
|
||||||
b = b.split()
|
b = b.split()
|
||||||
|
|
||||||
|
self.groups.append(set(b))
|
||||||
|
zero_group = self.groups[-1]
|
||||||
else:
|
else:
|
||||||
a = zdb.split()
|
a = zdb.split()
|
||||||
b = a
|
self.groups.append(set(a))
|
||||||
|
zero_group = self.groups[-1]
|
||||||
|
|
||||||
|
if allzero_tag is not None:
|
||||||
|
self.zero_tag_to_group[allzero_tag] = zero_group
|
||||||
|
|
||||||
bitmatch = False
|
|
||||||
for bit in a:
|
for bit in a:
|
||||||
if bit in bits:
|
self.bit_to_group[bit] = zero_group
|
||||||
bitmatch = True
|
|
||||||
|
|
||||||
if not (bitmatch or allzero_tag == tag):
|
def add_tag_bits(self, tag, bits):
|
||||||
continue
|
if tag in self.zero_tag_to_group:
|
||||||
|
return
|
||||||
|
|
||||||
|
group_ids = set()
|
||||||
|
groups = []
|
||||||
|
|
||||||
|
if tag in self.tag_to_groups:
|
||||||
|
assert len(self.tag_to_groups[tag]) == 1
|
||||||
|
|
||||||
|
self.tag_to_groups[tag][0] |= bits
|
||||||
|
|
||||||
|
for bit in bits:
|
||||||
|
if bit in self.bit_to_group:
|
||||||
|
# Make sure each bit only belongs to one group
|
||||||
|
assert id(self.bit_to_group[bit]) == id(
|
||||||
|
self.tag_to_groups[tag])
|
||||||
|
else:
|
||||||
|
self.bit_to_group[bit] = self.tag_to_groups[tag]
|
||||||
|
|
||||||
|
group_ids.add(id(self.tag_to_groups[tag]))
|
||||||
|
groups = self.tag_to_groups[tag]
|
||||||
|
|
||||||
|
for bit in bits:
|
||||||
|
if bit in self.bit_to_group:
|
||||||
|
if id(self.bit_to_group[bit]) not in group_ids:
|
||||||
|
group_ids.add(id(self.bit_to_group[bit]))
|
||||||
|
groups.append(self.bit_to_group[bit])
|
||||||
|
|
||||||
|
self.tag_to_groups[tag] = groups
|
||||||
|
|
||||||
|
def add_bits_from_zero_groups(self, tag, bits, strict=True, verbose=False):
|
||||||
|
""" Add bits from a zero group, if needed
|
||||||
|
|
||||||
|
Arguments
|
||||||
|
---------
|
||||||
|
tag : str
|
||||||
|
Tag being to examine for zero group
|
||||||
|
bits : set of str
|
||||||
|
Set of bits set on this tag
|
||||||
|
strict : bool
|
||||||
|
Assert that the size of the given group is the size of the given
|
||||||
|
mask.
|
||||||
|
verbose : bool
|
||||||
|
Print to stdout grouping being made
|
||||||
|
"""
|
||||||
|
|
||||||
|
tag_is_masked = tag in self.tag_to_groups
|
||||||
|
tag_is_zero = tag in self.zero_tag_to_group
|
||||||
|
|
||||||
|
# Should not have a tag that is both masked and a zero tag.
|
||||||
|
assert not (tag_is_masked and tag_is_zero)
|
||||||
|
|
||||||
|
if tag_is_masked:
|
||||||
|
for b in self.tag_to_groups[tag]:
|
||||||
bits_orig = set(bits)
|
bits_orig = set(bits)
|
||||||
for bit in b:
|
for bit in b:
|
||||||
if bit not in bits:
|
if bit not in bits:
|
||||||
bits.add("!" + bit)
|
bits.add("!" + bit)
|
||||||
|
|
||||||
verbose and print(
|
verbose and print(
|
||||||
"Grouped %s: %s => %s" %
|
"Grouped %s: %s => %s" %
|
||||||
(tag, bits_str(bits_orig), bits_str(bits)))
|
(tag, bits_str(bits_orig), bits_str(bits)))
|
||||||
if a == b and strict:
|
|
||||||
assert len(bits) == len(
|
if tag_is_zero:
|
||||||
a), "Mask size %u != DB entry size %u: %s" % (
|
for bit in self.zero_tag_to_group[tag]:
|
||||||
len(a), len(bits), bits_str(bits))
|
bits.add("!" + bit)
|
||||||
|
|
||||||
|
|
||||||
def add_zero_bits(fn_in, zero_db, clb_int=False, strict=True, verbose=False):
|
def add_zero_bits(fn_in, zero_db, clb_int=False, strict=True, verbose=False):
|
||||||
|
|
@ -111,11 +206,15 @@ def add_zero_bits(fn_in, zero_db, clb_int=False, strict=True, verbose=False):
|
||||||
If an entry has any of the
|
If an entry has any of the
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
zero_groups = ZeroGroups(zero_db)
|
||||||
|
|
||||||
|
lines = []
|
||||||
new_lines = set()
|
new_lines = set()
|
||||||
changes = 0
|
changes = 0
|
||||||
|
|
||||||
llast = None
|
llast = None
|
||||||
drops = 0
|
drops = 0
|
||||||
|
|
||||||
with open(fn_in, "r") as f:
|
with open(fn_in, "r") as f:
|
||||||
for line in f:
|
for line in f:
|
||||||
# Hack: skip duplicate lines
|
# Hack: skip duplicate lines
|
||||||
|
|
@ -124,12 +223,22 @@ def add_zero_bits(fn_in, zero_db, clb_int=False, strict=True, verbose=False):
|
||||||
if line == llast:
|
if line == llast:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
lines.append(line)
|
||||||
|
|
||||||
|
tag, bits, mode, _ = util.parse_db_line(line)
|
||||||
|
|
||||||
|
if bits is not None and mode is None:
|
||||||
|
zero_groups.add_tag_bits(tag, bits)
|
||||||
|
|
||||||
|
if verbose:
|
||||||
|
zero_groups.print_groups()
|
||||||
|
|
||||||
|
for line in lines:
|
||||||
tag, bits, mode, _ = util.parse_db_line(line)
|
tag, bits, mode, _ = util.parse_db_line(line)
|
||||||
# an enum that needs masking
|
# an enum that needs masking
|
||||||
# check below asserts that a mask was actually applied
|
# check below asserts that a mask was actually applied
|
||||||
if mode and mode != "<0 candidates>" and not strict:
|
if mode and mode != "<0 candidates>" and not strict:
|
||||||
verbose and print(
|
verbose and print("WARNING: dropping unresolved line: %s" % line)
|
||||||
"WARNING: dropping unresolved line: %s" % line)
|
|
||||||
drops += 1
|
drops += 1
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
@ -151,7 +260,8 @@ def add_zero_bits(fn_in, zero_db, clb_int=False, strict=True, verbose=False):
|
||||||
"""
|
"""
|
||||||
if clb_int:
|
if clb_int:
|
||||||
zero_range(tag, bits, 22, 25)
|
zero_range(tag, bits, 22, 25)
|
||||||
zero_groups(tag, bits, zero_db, strict=strict, verbose=verbose)
|
zero_groups.add_bits_from_zero_groups(
|
||||||
|
tag, bits, strict=strict, verbose=verbose)
|
||||||
|
|
||||||
if strict:
|
if strict:
|
||||||
assert len(bits) > 0, 'Line {} found no bits.'.format(line)
|
assert len(bits) > 0, 'Line {} found no bits.'.format(line)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue