mirror of https://github.com/openXC7/prjxray.git
Add initial FIFO configuration.
Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
This commit is contained in:
parent
055ed637ed
commit
0edc3facde
|
|
@ -0,0 +1,22 @@
|
|||
# read/write width is relatively slow to resolve
|
||||
# Even slower with multi bit masks...
|
||||
N ?= 20
|
||||
|
||||
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,47 @@
|
|||
#!/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['site'], '{}_{}'.format(key, opt), params[key] == opt)
|
||||
|
||||
def output_integer_tags(segmk, params, key, invert=False):
|
||||
site = params['site']
|
||||
bits = verilog.parse_bitstr(params[key])
|
||||
for bit, tag_val in enumerate(bits):
|
||||
if not invert:
|
||||
segmk.add_site_tag(site, "{}[{}]".format(key, len(bits)-bit-1), tag_val)
|
||||
else:
|
||||
segmk.add_site_tag(site, "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:
|
||||
#add_enum_bits(segmk, tile_param, 'DATA_WIDTH', [4, 9, 18, 36])
|
||||
#add_enum_bits(segmk, tile_param, 'FIFO_MODE', ['FIFO18', 'FIFO18_36'])
|
||||
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)
|
||||
#output_integer_tags(segmk, tile_param, 'INIT', 36, invert=True)
|
||||
#output_integer_tags(segmk, tile_param, 'SRVAL', 36, invert=True)
|
||||
|
||||
for param in ('EN_SYN', 'FIRST_WORD_FALL_THROUGH'):
|
||||
segmk.add_site_tag(
|
||||
tile_param['site'], 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,191 @@
|
|||
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['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,13 +70,13 @@ proc write_bram_ppips_db {filename tile} {
|
|||
if {[get_pips -uphill -of_objects [get_nodes -of_objects $dst_wire]] == $pip} {
|
||||
set src_wire [get_wires -uphill -of_objects $pip]
|
||||
puts $fp "${tile_type}.[regsub {.*/} $dst_wire ""].[regsub {.*/} $src_wire ""] always"
|
||||
}
|
||||
|
||||
# LOGIC_OUTS pips appear to be always, even thought multiple inputs to
|
||||
# the pip junction. Best guess is that the underlying hardware is
|
||||
# actually just one wire, and there is no actually junction.
|
||||
if [string match "*LOGIC_OUTS*" dst_wire] {
|
||||
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
|
||||
# the pip junction. Best guess is that the underlying hardware is
|
||||
# actually just one wire, and there is no actually junction.
|
||||
foreach src_wire [get_wires -uphill -of_objects $pip] {
|
||||
puts $fp "${tile_type}.[regsub {.*/} $dst_wire ""].[regsub {.*/} $src_wire ""] always"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@ $(eval $(call fuzzer,018-clb-ram,005-tilegrid))
|
|||
$(eval $(call fuzzer,019-clb-ndi1mux,005-tilegrid))
|
||||
$(eval $(call fuzzer,025-bram-config,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,051-pip-imuxlout-bypalts,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))
|
||||
ifneq ($(QUICK),Y)
|
||||
$(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)
|
||||
$(eval $(call fuzzer,072-ordered_wires,))
|
||||
$(eval $(call fuzzer,073-get_counts,))
|
||||
|
|
|
|||
Loading…
Reference in New Issue