mirror of https://github.com/openXC7/prjxray.git
Filter out non-IOB bits.
Also add output from LiteX to verify IOB FASM features. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
This commit is contained in:
parent
aa331131f2
commit
a7ba547acb
|
|
@ -13,6 +13,7 @@ The second time that the database is run, the FASM files in the specimen's
|
|||
will have the bits documented by fuzzer.
|
||||
|
||||
"""
|
||||
import argparse
|
||||
import os
|
||||
import os.path
|
||||
from prjxray import verilog
|
||||
|
|
@ -21,11 +22,8 @@ import generate
|
|||
|
||||
|
||||
def process_parts(parts):
|
||||
if parts[0] == 'INOUT':
|
||||
yield 'type', 'IOBUF_INTERMDISABLE'
|
||||
|
||||
if parts[-1] == 'IN_ONLY':
|
||||
yield 'type', 'IBUF'
|
||||
yield 'type', ['IBUF']
|
||||
|
||||
if len(parts) > 2 and parts[-2] == 'SLEW':
|
||||
yield 'SLEW', verilog.quote(parts[-1])
|
||||
|
|
@ -35,6 +33,7 @@ def process_parts(parts):
|
|||
|
||||
if len(parts) > 1 and parts[1] == 'IN':
|
||||
yield 'IOSTANDARDS', parts[0].split('_')
|
||||
yield 'IN', True
|
||||
|
||||
if len(parts) > 1 and parts[1] == 'DRIVE':
|
||||
yield 'IOSTANDARDS', parts[0].split('_')
|
||||
|
|
@ -45,10 +44,10 @@ def process_parts(parts):
|
|||
yield 'DRIVES', parts[2].split('_')
|
||||
|
||||
|
||||
def create_sites_from_fasm(root):
|
||||
def create_sites_from_fasm(fasm_file):
|
||||
sites = {}
|
||||
|
||||
with open(os.path.join(root, 'design.fasm')) as f:
|
||||
with open(fasm_file) as f:
|
||||
for l in f:
|
||||
if 'IOB33' not in l:
|
||||
continue
|
||||
|
|
@ -72,74 +71,124 @@ def create_sites_from_fasm(root):
|
|||
else:
|
||||
assert 'IOSTANDARDS' in sites[key], sites[key]
|
||||
assert 'DRIVES' in sites[key], sites[key]
|
||||
sites[key]['type'] = "OBUF"
|
||||
|
||||
if 'IN' in sites[key]:
|
||||
sites[key]['type'] = ['IOBUF', 'IOBUF_INTERMDISABLE']
|
||||
else:
|
||||
sites[key]['type'] = [
|
||||
"OBUF",
|
||||
"OBUFDS_DUAL_BUF",
|
||||
"OBUFTDS_DUAL_BUF",
|
||||
]
|
||||
|
||||
return sites
|
||||
|
||||
|
||||
def process_specimen(root):
|
||||
sites = create_sites_from_fasm(root)
|
||||
def process_specimen(fasm_file, params_json):
|
||||
sites = create_sites_from_fasm(fasm_file)
|
||||
|
||||
with open(os.path.join(root, 'params.json')) as f:
|
||||
with open(params_json) as f:
|
||||
params = json.load(f)
|
||||
|
||||
for p in params['tiles']:
|
||||
tile = p['tile']
|
||||
site = p['site']
|
||||
site_y = int(site[site.find('Y') + 1:]) % 2
|
||||
for site in p['site'].split(' '):
|
||||
site_y = int(site[site.find('Y') + 1:]) % 2
|
||||
|
||||
if generate.skip_broken_tiles(p):
|
||||
continue
|
||||
if generate.skip_broken_tiles(p):
|
||||
continue
|
||||
|
||||
site_key = 'IOB_Y{}'.format(site_y)
|
||||
site_key = 'IOB_Y{}'.format(site_y)
|
||||
|
||||
if (tile, site_key) not in sites:
|
||||
assert p['type'] is None, p
|
||||
continue
|
||||
if (tile, site_key) not in sites:
|
||||
assert p['type'] is None, p
|
||||
continue
|
||||
|
||||
site_from_fasm = sites[(tile, site_key)]
|
||||
site_from_fasm = sites[(tile, site_key)]
|
||||
|
||||
assert p['type'] == site_from_fasm['type'], (
|
||||
tile, site_key, p['type'], site_from_fasm['type'])
|
||||
assert p['type'] in site_from_fasm['type'], (
|
||||
tile, site_key, p['type'], site_from_fasm['type'])
|
||||
|
||||
if p['type'] is None:
|
||||
continue
|
||||
if p['type'] is None:
|
||||
continue
|
||||
|
||||
assert p['PULLTYPE'] == site_from_fasm['PULLTYPE'], (
|
||||
tile, site_key, p, site_from_fasm)
|
||||
assert 'PULLTYPE' in p, p
|
||||
assert 'PULLTYPE' in site_from_fasm, site_from_fasm
|
||||
|
||||
assert 'IOSTANDARDS' in site_from_fasm, (root, tile, site)
|
||||
if verilog.unquote(p['PULLTYPE']) == '':
|
||||
# Default is None.
|
||||
pulltype = verilog.quote('NONE')
|
||||
else:
|
||||
pulltype = p['PULLTYPE']
|
||||
|
||||
assert verilog.unquote(
|
||||
p['IOSTANDARD']) in site_from_fasm['IOSTANDARDS'], (
|
||||
p['IOSTANDARD'],
|
||||
site_from_fasm['IOSTANDARDS'],
|
||||
)
|
||||
|
||||
if p['type'] != 'IBUF':
|
||||
assert p['SLEW'] == site_from_fasm['SLEW'], (
|
||||
assert pulltype == site_from_fasm['PULLTYPE'], (
|
||||
tile, site_key, p, site_from_fasm)
|
||||
|
||||
assert 'DRIVES' not in p, p
|
||||
assert 'DRIVES' in site_from_fasm, (
|
||||
tile, site, p['type'], site_from_fasm)
|
||||
assert 'IOSTANDARDS' in site_from_fasm, (tile, site)
|
||||
|
||||
if p['DRIVE'] is None:
|
||||
assert None in site_from_fasm['DRIVES'], (
|
||||
tile, site_key, p['DRIVE'], site_from_fasm['DRIVES'])
|
||||
else:
|
||||
assert 'I{}'.format(p['DRIVE']) in site_from_fasm['DRIVES'], (
|
||||
tile, site_key, p['DRIVE'], site_from_fasm['DRIVES'])
|
||||
iostandard = verilog.unquote(p['IOSTANDARD'])
|
||||
if iostandard.startswith('DIFF_'):
|
||||
iostandard = iostandard[5:]
|
||||
|
||||
assert iostandard in site_from_fasm['IOSTANDARDS'], (
|
||||
p['IOSTANDARD'],
|
||||
site_from_fasm['IOSTANDARDS'],
|
||||
)
|
||||
|
||||
if p['type'] != 'IBUF':
|
||||
if verilog.unquote(p['SLEW']) == '':
|
||||
# Default is None.
|
||||
slew = verilog.quote('SLOW')
|
||||
else:
|
||||
slew = p['SLEW']
|
||||
|
||||
assert slew == site_from_fasm['SLEW'], (
|
||||
tile, site_key, p, site_from_fasm)
|
||||
|
||||
assert 'DRIVES' not in p, p
|
||||
assert 'DRIVES' in site_from_fasm, (
|
||||
tile, site, p['type'], site_from_fasm)
|
||||
|
||||
if p['DRIVE'] is None:
|
||||
assert None in site_from_fasm['DRIVES'], (
|
||||
tile, site_key, p['DRIVE'], site_from_fasm['DRIVES'])
|
||||
elif p['DRIVE'] is '':
|
||||
if None in site_from_fasm['DRIVES']:
|
||||
# IOSTANDARD has not DRIVE setting, ignore
|
||||
pass
|
||||
else:
|
||||
# Check that drive is at default
|
||||
assert 'I12' in site_from_fasm['DRIVES'], (
|
||||
tile, site_key, p['DRIVE'], site_from_fasm['DRIVES'])
|
||||
else:
|
||||
assert 'I{}'.format(p['DRIVE']) in site_from_fasm['DRIVES'], (
|
||||
tile, site_key, p['DRIVE'], site_from_fasm['DRIVES'])
|
||||
|
||||
|
||||
def main():
|
||||
def scan_specimens():
|
||||
for root, dirs, files in os.walk('build'):
|
||||
if os.path.basename(root).startswith('specimen_'):
|
||||
print('Processing', os.path.basename(root))
|
||||
process_specimen(root)
|
||||
process_specimen(
|
||||
fasm_file=os.path.join(root, 'design.fasm'),
|
||||
params_json=os.path.join(root, 'params.json'))
|
||||
|
||||
print('No errors found!')
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Verify IOB FASM vs BELs.")
|
||||
|
||||
parser.add_argument('--fasm')
|
||||
parser.add_argument('--params')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if not args.fasm and not args.params:
|
||||
scan_specimens()
|
||||
else:
|
||||
process_specimen(fasm_file=args.fasm, params_json=args.params)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import json
|
|||
|
||||
|
||||
def bitfilter(frame, word):
|
||||
if frame < 26:
|
||||
if frame < 38:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -99,6 +99,8 @@ proc run {} {
|
|||
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-79}]
|
||||
set_property IS_ENABLED 0 [get_drc_checks {REQP-144}]
|
||||
set_property IS_ENABLED 0 [get_drc_checks {AVAL-74}]
|
||||
|
||||
write_checkpoint -force design_pre_place.dcp
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ top.edif: $(YOSYS) synth.ys $(SOURCES)
|
|||
top.bit: $(VIVADO) top.edif top.xdc top.tcl
|
||||
mkdir -p build
|
||||
cd build && $(XRAY_VIVADO) -mode batch -source ../top.tcl -nojournal -tempDir build -log vivado.log -verbose
|
||||
python3 $(XRAY_DIR)/minitests/timing/clean_json5.py < build/iobuf_report.json5 > build/iobuf_report.json
|
||||
cp build/*.bit ./
|
||||
|
||||
top.fasm: top.bit
|
||||
|
|
|
|||
|
|
@ -1,3 +1,33 @@
|
|||
proc write_iobuf_report {filename} {
|
||||
set fp [open $filename w]
|
||||
puts $fp "{ \"tiles\": \["
|
||||
foreach port [get_ports] {
|
||||
set net [get_nets -of $port]
|
||||
if { $net == "" } {
|
||||
continue
|
||||
}
|
||||
|
||||
set cell [get_cells -of $net]
|
||||
set site [get_sites -of $cell]
|
||||
set tile [get_tiles -of $site]
|
||||
|
||||
puts $fp "{"
|
||||
puts $fp "\"port\": \"$port\","
|
||||
puts $fp "\"pad_wire\": \"$net\","
|
||||
puts $fp "\"cell\": \"$cell\","
|
||||
puts $fp "\"site\": \"$site\","
|
||||
puts $fp "\"tile\": \"$tile\","
|
||||
puts $fp "\"type\": \"[get_property REF_NAME $cell]\","
|
||||
puts $fp "\"IOSTANDARD\": \"\\\"[get_property IOSTANDARD $cell]\\\"\","
|
||||
puts $fp "\"PULLTYPE\": \"\\\"[get_property PULLTYPE $cell]\\\"\","
|
||||
puts $fp "\"DRIVE\": \"[get_property DRIVE $cell]\","
|
||||
puts $fp "\"SLEW\": \"\\\"[get_property SLEW $cell]\\\"\","
|
||||
puts $fp "},"
|
||||
}
|
||||
puts $fp "\]}"
|
||||
close $fp
|
||||
}
|
||||
|
||||
create_project -force -name top -part xc7a35ticsg324-1L
|
||||
read_xdc ../top.xdc
|
||||
read_edif ../top.edif
|
||||
|
|
@ -23,4 +53,8 @@ report_power -file top_power.rpt
|
|||
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
|
||||
write_bitstream -force top.bit
|
||||
write_cfgmem -force -format bin -interface spix4 -size 16 -loadbit "up 0x0 top.bit" -file top.bin
|
||||
|
||||
write_iobuf_report iobuf_report.json5
|
||||
|
||||
|
||||
quit
|
||||
|
|
|
|||
Loading…
Reference in New Issue