mirror of https://github.com/openXC7/prjxray.git
Merge pull request #597 from litghost/initial_fifo_bits
Add FIFO bits and fix BRAM pips output
This commit is contained in:
commit
ce482565fc
|
|
@ -1,6 +1,6 @@
|
||||||
# read/write width is relatively slow to resolve
|
# read/write width is relatively slow to resolve
|
||||||
# Even slower with multi bit masks...
|
# Even slower with multi bit masks...
|
||||||
N ?= 10
|
N ?= 15
|
||||||
|
|
||||||
include ../fuzzer.mk
|
include ../fuzzer.mk
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ build/segbits_bramx.db: build/segbits_bramx.rdb
|
||||||
${XRAY_DBFIXUP} --db-root build --zero-db bits.dbf --seg-fn-in $^ --seg-fn-out $@
|
${XRAY_DBFIXUP} --db-root build --zero-db bits.dbf --seg-fn-in $^ --seg-fn-out $@
|
||||||
${XRAY_MASKMERGE} build/mask_bramx.db $(addsuffix /segdata_bram_[lr].txt,$(SPECIMENS))
|
${XRAY_MASKMERGE} build/mask_bramx.db $(addsuffix /segdata_bram_[lr].txt,$(SPECIMENS))
|
||||||
|
|
||||||
pushdb:
|
pushdb: database
|
||||||
${XRAY_MERGEDB} bram_l build/segbits_bramx.db
|
${XRAY_MERGEDB} bram_l build/segbits_bramx.db
|
||||||
${XRAY_MERGEDB} bram_r build/segbits_bramx.db
|
${XRAY_MERGEDB} bram_r build/segbits_bramx.db
|
||||||
${XRAY_MERGEDB} mask_bram_l build/mask_bramx.db
|
${XRAY_MERGEDB} mask_bram_l build/mask_bramx.db
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
N ?= 5
|
||||||
|
|
||||||
|
include ../fuzzer.mk
|
||||||
|
|
||||||
|
database: build/segbits_bramx.db
|
||||||
|
|
||||||
|
build/segbits_bramx.rdb: $(SPECIMENS_OK)
|
||||||
|
${XRAY_SEGMATCH} -o build/segbits_bramx.rdb $(addsuffix /segdata_bram_[lr].txt,$(SPECIMENS))
|
||||||
|
|
||||||
|
build/segbits_bramx.db: build/segbits_bramx.rdb
|
||||||
|
${XRAY_DBFIXUP} --db-root build --zero-db bits.dbf --seg-fn-in $^ --seg-fn-out $@
|
||||||
|
${XRAY_MASKMERGE} build/mask_bramx.db $(addsuffix /segdata_bram_[lr].txt,$(SPECIMENS))
|
||||||
|
|
||||||
|
pushdb:
|
||||||
|
${XRAY_MERGEDB} bram_l build/segbits_bramx.db
|
||||||
|
${XRAY_MERGEDB} bram_r build/segbits_bramx.db
|
||||||
|
${XRAY_MERGEDB} mask_bram_l build/mask_bramx.db
|
||||||
|
${XRAY_MERGEDB} mask_bram_r build/mask_bramx.db
|
||||||
|
|
||||||
|
.PHONY: database pushdb
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import json
|
||||||
|
|
||||||
|
from prjxray.segmaker import Segmaker
|
||||||
|
from prjxray import verilog
|
||||||
|
|
||||||
|
|
||||||
|
def add_enum_bits(segmk, params, key, options):
|
||||||
|
for opt in options:
|
||||||
|
segmk.add_site_tag(
|
||||||
|
params['tile'], '{}_{}'.format(key, opt), params[key] == opt)
|
||||||
|
|
||||||
|
|
||||||
|
def output_integer_tags(segmk, params, key, invert=False):
|
||||||
|
tile = params['tile']
|
||||||
|
bits = verilog.parse_bitstr(params[key])
|
||||||
|
for bit, tag_val in enumerate(bits):
|
||||||
|
if not invert:
|
||||||
|
segmk.add_tile_tag(
|
||||||
|
tile, "{}[{}]".format(key,
|
||||||
|
len(bits) - bit - 1), tag_val)
|
||||||
|
else:
|
||||||
|
segmk.add_tile_tag(
|
||||||
|
tile, "Z{}[{}]".format(key,
|
||||||
|
len(bits) - bit - 1),
|
||||||
|
0 if tag_val else 1)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
segmk = Segmaker("design.bits")
|
||||||
|
|
||||||
|
print("Loading tags")
|
||||||
|
with open('params.json') as f:
|
||||||
|
params = json.load(f)
|
||||||
|
|
||||||
|
for tile_param in params:
|
||||||
|
if tile_param['EN_SYN'] and tile_param['DATA_WIDTH'] == 4:
|
||||||
|
output_integer_tags(
|
||||||
|
segmk, tile_param, 'ALMOST_EMPTY_OFFSET', invert=True)
|
||||||
|
output_integer_tags(
|
||||||
|
segmk, tile_param, 'ALMOST_FULL_OFFSET', invert=True)
|
||||||
|
|
||||||
|
for param in ('EN_SYN', 'FIRST_WORD_FALL_THROUGH'):
|
||||||
|
segmk.add_tile_tag(tile_param['tile'], param, tile_param[param])
|
||||||
|
|
||||||
|
segmk.compile()
|
||||||
|
segmk.write()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
proc run {} {
|
||||||
|
create_project -force -part $::env(XRAY_PART) design design
|
||||||
|
read_verilog top.v
|
||||||
|
synth_design -top top
|
||||||
|
|
||||||
|
set_property CFGBVS VCCO [current_design]
|
||||||
|
set_property CONFIG_VOLTAGE 3.3 [current_design]
|
||||||
|
set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design]
|
||||||
|
set_property IS_ENABLED 0 [get_drc_checks {REQP-38}]
|
||||||
|
|
||||||
|
place_design
|
||||||
|
route_design
|
||||||
|
|
||||||
|
write_checkpoint -force design.dcp
|
||||||
|
write_bitstream -force design.bit
|
||||||
|
}
|
||||||
|
|
||||||
|
run
|
||||||
|
|
@ -0,0 +1,200 @@
|
||||||
|
import json
|
||||||
|
import math
|
||||||
|
import os
|
||||||
|
import functools
|
||||||
|
import random
|
||||||
|
random.seed(int(os.getenv("SEED"), 16))
|
||||||
|
from prjxray import util
|
||||||
|
from prjxray import verilog
|
||||||
|
from prjxray.verilog import vrandbits
|
||||||
|
from prjxray.db import Database
|
||||||
|
|
||||||
|
|
||||||
|
def gen_sites():
|
||||||
|
db = Database(util.get_db_root())
|
||||||
|
grid = db.grid()
|
||||||
|
for tile_name in sorted(grid.tiles()):
|
||||||
|
loc = grid.loc_of_tilename(tile_name)
|
||||||
|
gridinfo = grid.gridinfo_at_loc(loc)
|
||||||
|
|
||||||
|
if gridinfo.tile_type not in ['BRAM_L', 'BRAM_R']:
|
||||||
|
continue
|
||||||
|
|
||||||
|
sites = {}
|
||||||
|
for site_name, site_type in gridinfo.sites.items():
|
||||||
|
sites[site_type] = site_name
|
||||||
|
|
||||||
|
yield tile_name, sites
|
||||||
|
|
||||||
|
|
||||||
|
@functools.lru_cache(maxsize=None)
|
||||||
|
def prepare_rand_int_choices(minval, maxval):
|
||||||
|
""" Creates list ints between minval and maxval to allow fuzzer to uniquely identify all bits."""
|
||||||
|
assert minval >= 0
|
||||||
|
assert maxval >= minval
|
||||||
|
|
||||||
|
min_p2 = math.floor(math.log(max(minval, 1), 2))
|
||||||
|
max_p2 = math.ceil(math.log(maxval + 1, 2))
|
||||||
|
|
||||||
|
if 2**max_p2 > maxval:
|
||||||
|
max_search_p2 = max_p2 - 1
|
||||||
|
else:
|
||||||
|
max_search_p2 = max_p2
|
||||||
|
|
||||||
|
choices = set(
|
||||||
|
[minval, maxval, 2**(min_p2 + 1) - 1, 2**(max_search_p2) - 1])
|
||||||
|
|
||||||
|
lb = min_p2
|
||||||
|
ub = max_search_p2
|
||||||
|
|
||||||
|
while lb < ub:
|
||||||
|
ub = int(round(ub / 2.))
|
||||||
|
|
||||||
|
val = 2**ub - 1
|
||||||
|
|
||||||
|
lowval = val
|
||||||
|
if lowval < minval:
|
||||||
|
lowval |= (1 << max_search_p2)
|
||||||
|
assert lowval >= minval, (val, ub)
|
||||||
|
choices.add(lowval)
|
||||||
|
|
||||||
|
highval = val << (max_search_p2 - ub)
|
||||||
|
if highval > minval:
|
||||||
|
assert highval <= maxval, (val, ub)
|
||||||
|
choices.add(highval)
|
||||||
|
|
||||||
|
for bit in range(max_search_p2):
|
||||||
|
if 2**bit > minval:
|
||||||
|
choices.add(2**bit)
|
||||||
|
else:
|
||||||
|
choices.add(2**bit | 2**max_search_p2)
|
||||||
|
choices.add(2**bit | 2**(max_search_p2 - 1))
|
||||||
|
|
||||||
|
zeros = set()
|
||||||
|
ones = set()
|
||||||
|
|
||||||
|
for choice in choices:
|
||||||
|
assert choice >= minval, choice
|
||||||
|
assert choice <= maxval, choice
|
||||||
|
|
||||||
|
for bit in range(max_p2):
|
||||||
|
if (1 << bit) & choice:
|
||||||
|
ones.add(bit)
|
||||||
|
else:
|
||||||
|
zeros.add(bit)
|
||||||
|
|
||||||
|
assert len(ones) == max_p2
|
||||||
|
assert len(zeros) == max_p2
|
||||||
|
|
||||||
|
return tuple(sorted(choices))
|
||||||
|
|
||||||
|
|
||||||
|
def rand_int(minval, maxval):
|
||||||
|
return random.choice(prepare_rand_int_choices(minval, maxval))
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print('''
|
||||||
|
module top();
|
||||||
|
''')
|
||||||
|
|
||||||
|
params_list = []
|
||||||
|
for tile_name, sites in gen_sites():
|
||||||
|
params = {}
|
||||||
|
params['tile'] = tile_name
|
||||||
|
params['site'] = sites['RAMBFIFO36E1']
|
||||||
|
|
||||||
|
params['DATA_WIDTH'] = random.choice([4, 9, 18, 36, 72])
|
||||||
|
params['EN_SYN'] = random.randint(0, 1)
|
||||||
|
params['DO_REG'] = 1
|
||||||
|
if params['EN_SYN']:
|
||||||
|
params['FIRST_WORD_FALL_THROUGH'] = 0
|
||||||
|
else:
|
||||||
|
params['FIRST_WORD_FALL_THROUGH'] = random.randint(0, 1)
|
||||||
|
|
||||||
|
if params['EN_SYN']:
|
||||||
|
MIN_ALMOST_FULL_OFFSET = 1
|
||||||
|
if params['DATA_WIDTH'] == 4:
|
||||||
|
MAX_ALMOST_FULL_OFFSET = 8190
|
||||||
|
elif params['DATA_WIDTH'] == 9:
|
||||||
|
MAX_ALMOST_FULL_OFFSET = 4094
|
||||||
|
elif params['DATA_WIDTH'] == 18:
|
||||||
|
MAX_ALMOST_FULL_OFFSET = 2046
|
||||||
|
elif params['DATA_WIDTH'] == 36:
|
||||||
|
MAX_ALMOST_FULL_OFFSET = 1022
|
||||||
|
elif params['DATA_WIDTH'] == 72:
|
||||||
|
MAX_ALMOST_FULL_OFFSET = 510
|
||||||
|
else:
|
||||||
|
assert False
|
||||||
|
|
||||||
|
MIN_ALMOST_EMPTY_OFFSET = MIN_ALMOST_FULL_OFFSET
|
||||||
|
MAX_ALMOST_EMPTY_OFFSET = MAX_ALMOST_FULL_OFFSET
|
||||||
|
else:
|
||||||
|
MIN_ALMOST_FULL_OFFSET = 4
|
||||||
|
if params['DATA_WIDTH'] == 4:
|
||||||
|
MAX_ALMOST_FULL_OFFSET = 8185
|
||||||
|
elif params['DATA_WIDTH'] == 9:
|
||||||
|
MAX_ALMOST_FULL_OFFSET = 4089
|
||||||
|
elif params['DATA_WIDTH'] == 18:
|
||||||
|
MAX_ALMOST_FULL_OFFSET = 2041
|
||||||
|
elif params['DATA_WIDTH'] == 36:
|
||||||
|
MAX_ALMOST_FULL_OFFSET = 1017
|
||||||
|
elif params['DATA_WIDTH'] == 72:
|
||||||
|
MAX_ALMOST_FULL_OFFSET = 505
|
||||||
|
else:
|
||||||
|
assert False
|
||||||
|
|
||||||
|
if params['FIRST_WORD_FALL_THROUGH']:
|
||||||
|
MIN_ALMOST_EMPTY_OFFSET = MIN_ALMOST_FULL_OFFSET + 2
|
||||||
|
MAX_ALMOST_EMPTY_OFFSET = MAX_ALMOST_FULL_OFFSET + 2
|
||||||
|
else:
|
||||||
|
MIN_ALMOST_EMPTY_OFFSET = MIN_ALMOST_FULL_OFFSET + 1
|
||||||
|
MAX_ALMOST_EMPTY_OFFSET = MAX_ALMOST_FULL_OFFSET + 1
|
||||||
|
|
||||||
|
ALMOST_EMPTY_OFFSET = rand_int(
|
||||||
|
MIN_ALMOST_EMPTY_OFFSET, MAX_ALMOST_EMPTY_OFFSET)
|
||||||
|
ALMOST_FULL_OFFSET = rand_int(
|
||||||
|
MIN_ALMOST_FULL_OFFSET, MAX_ALMOST_FULL_OFFSET)
|
||||||
|
params['ALMOST_EMPTY_OFFSET'] = "13'b{:013b}".format(
|
||||||
|
ALMOST_EMPTY_OFFSET)
|
||||||
|
params['ALMOST_FULL_OFFSET'] = "13'b{:013b}".format(ALMOST_FULL_OFFSET)
|
||||||
|
|
||||||
|
if params['DATA_WIDTH'] == 36:
|
||||||
|
params['FIFO_MODE'] = verilog.quote('FIFO36_72')
|
||||||
|
else:
|
||||||
|
params['FIFO_MODE'] = verilog.quote(
|
||||||
|
'FIFO36_72'
|
||||||
|
) #verilog.quote('FIFO18') #verilog.quote(random.choice(('FIFO18', 'FIFO18_36')))
|
||||||
|
|
||||||
|
params['INIT'] = '0' #vrandbits(36)
|
||||||
|
params['SRVAL'] = '0' #vrandbits(36)
|
||||||
|
|
||||||
|
print(
|
||||||
|
'''
|
||||||
|
(* KEEP, DONT_TOUCH, LOC = "{site}" *)
|
||||||
|
FIFO36E1 #(
|
||||||
|
.ALMOST_EMPTY_OFFSET({ALMOST_EMPTY_OFFSET}),
|
||||||
|
.ALMOST_FULL_OFFSET({ALMOST_FULL_OFFSET}),
|
||||||
|
.DATA_WIDTH({DATA_WIDTH}),
|
||||||
|
.DO_REG({DO_REG}),
|
||||||
|
.EN_SYN({EN_SYN}),
|
||||||
|
.FIFO_MODE({FIFO_MODE}),
|
||||||
|
.FIRST_WORD_FALL_THROUGH({FIRST_WORD_FALL_THROUGH}),
|
||||||
|
.INIT({INIT}),
|
||||||
|
.SRVAL({SRVAL})
|
||||||
|
) fifo_{site} (
|
||||||
|
);
|
||||||
|
'''.format(**params, ))
|
||||||
|
|
||||||
|
params['FIFO_MODE'] = verilog.unquote(params['FIFO_MODE'])
|
||||||
|
|
||||||
|
params_list.append(params)
|
||||||
|
|
||||||
|
print("endmodule")
|
||||||
|
|
||||||
|
with open('params.json', 'w') as f:
|
||||||
|
json.dump(params_list, f, indent=2)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
|
@ -70,15 +70,15 @@ proc write_bram_ppips_db {filename tile} {
|
||||||
if {[get_pips -uphill -of_objects [get_nodes -of_objects $dst_wire]] == $pip} {
|
if {[get_pips -uphill -of_objects [get_nodes -of_objects $dst_wire]] == $pip} {
|
||||||
set src_wire [get_wires -uphill -of_objects $pip]
|
set src_wire [get_wires -uphill -of_objects $pip]
|
||||||
puts $fp "${tile_type}.[regsub {.*/} $dst_wire ""].[regsub {.*/} $src_wire ""] always"
|
puts $fp "${tile_type}.[regsub {.*/} $dst_wire ""].[regsub {.*/} $src_wire ""] always"
|
||||||
}
|
} elseif [string match "*LOGIC_OUTS*" $dst_wire] {
|
||||||
|
|
||||||
# LOGIC_OUTS pips appear to be always, even thought multiple inputs to
|
# LOGIC_OUTS pips appear to be always, even thought multiple inputs to
|
||||||
# the pip junction. Best guess is that the underlying hardware is
|
# the pip junction. Best guess is that the underlying hardware is
|
||||||
# actually just one wire, and there is no actually junction.
|
# actually just one wire, and there is no actually junction.
|
||||||
if [string match "*LOGIC_OUTS*" dst_wire] {
|
foreach src_wire [get_wires -uphill -of_objects $pip] {
|
||||||
puts $fp "${tile_type}.[regsub {.*/} $dst_wire ""].[regsub {.*/} $src_wire ""] always"
|
puts $fp "${tile_type}.[regsub {.*/} $dst_wire ""].[regsub {.*/} $src_wire ""] always"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
close $fp
|
close $fp
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,8 @@ $(eval $(call fuzzer,018-clb-ram,005-tilegrid))
|
||||||
$(eval $(call fuzzer,019-clb-ndi1mux,005-tilegrid))
|
$(eval $(call fuzzer,019-clb-ndi1mux,005-tilegrid))
|
||||||
$(eval $(call fuzzer,025-bram-config,005-tilegrid))
|
$(eval $(call fuzzer,025-bram-config,005-tilegrid))
|
||||||
$(eval $(call fuzzer,026-bram-data,005-tilegrid))
|
$(eval $(call fuzzer,026-bram-data,005-tilegrid))
|
||||||
|
$(eval $(call fuzzer,027-bram36-config,005-tilegrid))
|
||||||
|
$(eval $(call fuzzer,028-fifo-config,005-tilegrid))
|
||||||
$(eval $(call fuzzer,050-pip-seed,005-tilegrid))
|
$(eval $(call fuzzer,050-pip-seed,005-tilegrid))
|
||||||
$(eval $(call fuzzer,051-pip-imuxlout-bypalts,050-pip-seed))
|
$(eval $(call fuzzer,051-pip-imuxlout-bypalts,050-pip-seed))
|
||||||
$(eval $(call fuzzer,052-pip-clkin,050-pip-seed))
|
$(eval $(call fuzzer,052-pip-clkin,050-pip-seed))
|
||||||
|
|
@ -47,7 +49,8 @@ $(eval $(call fuzzer,056-pip-rem,051-pip-imuxlout-bypalts 052-pip-clkin 053-pip-
|
||||||
$(eval $(call fuzzer,057-pip-bi,056-pip-rem))
|
$(eval $(call fuzzer,057-pip-bi,056-pip-rem))
|
||||||
ifneq ($(QUICK),Y)
|
ifneq ($(QUICK),Y)
|
||||||
$(eval $(call fuzzer,058-pip-hclk,056-pip-rem))
|
$(eval $(call fuzzer,058-pip-hclk,056-pip-rem))
|
||||||
$(eval $(call fuzzer,071-ppips,057-pip-bi 058-pip-hclk))
|
$(eval $(call fuzzer,060-bram-cascades,005-tilegrid))
|
||||||
|
$(eval $(call fuzzer,071-ppips,057-pip-bi 058-pip-hclk 060-bram-cascades))
|
||||||
ifneq ($(BITONLY),Y)
|
ifneq ($(BITONLY),Y)
|
||||||
$(eval $(call fuzzer,072-ordered_wires,))
|
$(eval $(call fuzzer,072-ordered_wires,))
|
||||||
$(eval $(call fuzzer,073-get_counts,))
|
$(eval $(call fuzzer,073-get_counts,))
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue