diff --git a/fuzzers/061-pcie-conf/Makefile b/fuzzers/061-pcie-conf/Makefile index 1a645826..d07ea05f 100644 --- a/fuzzers/061-pcie-conf/Makefile +++ b/fuzzers/061-pcie-conf/Makefile @@ -5,23 +5,67 @@ # https://opensource.org/licenses/ISC # # SPDX-License-Identifier: ISC + +SHELL = bash + N ?= 40 -include ../fuzzer.mk +BUILD_DIR = build_${XRAY_PART} -database: build/segbits_pcie_bot.db +SPECIMENS := $(addprefix ${BUILD_DIR}/specimen_,$(shell seq -f '%03.0f' $(N))) +SPECIMENS_OK := $(addsuffix /OK,$(SPECIMENS)) +FUZDIR ?= ${PWD} +CELLS_DATA_DIR = ${XRAY_FAMILY_DIR}/cells_data -build/segbits_pcie_bot.rdb: $(SPECIMENS_OK) - ${XRAY_SEGMATCH} -o build/segbits_pcie_bot.rdb $(addsuffix /segdata_pcie_bot.txt,$(SPECIMENS)) +all: database -build/segbits_pcie_bot.db: build/segbits_pcie_bot.rdb - ${XRAY_DBFIXUP} --db-root build --zero-db bits.dbf \ - --seg-fn-in build/segbits_pcie_bot.rdb \ - --seg-fn-out build/segbits_pcie_bot.db - ${XRAY_MASKMERGE} build/mask_pcie_bot.db $(addsuffix /segdata_pcie_bot.txt,$(SPECIMENS)) +$(SPECIMENS_OK): $(SPECIMENS_DEPS) + mkdir -p ${BUILD_DIR} + bash ${XRAY_DIR}/utils/top_generate.sh $(subst /OK,,$@) + +run: + $(MAKE) clean + $(MAKE) attrs + $(MAKE) database + $(MAKE) pushdb + touch run.${XRAY_PART}.ok + +clean: + rm -rf ${BUILD_DIR} run.${XRAY_PART}.ok + +.PHONY: all run clean + +attrs: $(FUZDIR)/attrs.json + +$(FUZDIR)/attrs.json: $(FUZDIR)/params.py + python3 $(FUZDIR)/params.py --attrs-file $(FUZDIR)/attrs.json + +# These are pins that are hard to parse as a regexp given that the port name ends with a number, which is misinterpreted +# as the index in the port bus +SPECIAL_PINS = EDTCHANNELSIN1,EDTCHANNELSIN2,EDTCHANNELSIN3,EDTCHANNELSIN4,EDTCHANNELSIN5,EDTCHANNELSIN6,EDTCHANNELSIN7,EDTCHANNELSIN8,LL2SENDASREQL1,LL2SENDENTERL1,LL2SENDENTERL23,USERCLK2,EDTCHANNELSOUT1,EDTCHANNELSOUT2,EDTCHANNELSOUT3,EDTCHANNELSOUT4,EDTCHANNELSOUT5,EDTCHANNELSOUT6,EDTCHANNELSOUT7,EDTCHANNELSOUT8 + +$(BUILD_DIR)/pcie_2_1_ports.csv: generate_ports.tcl + env FILE_NAME=$(BUILD_DIR)/pcie_2_1_pins.csv ${XRAY_VIVADO} -mode batch -source generate_ports.tcl + +$(BUILD_DIR)/pcie_2_1_ports.json: $(BUILD_DIR)/pcie_2_1_ports.csv + python3 ${XRAY_UTILS_DIR}/make_ports.py $(BUILD_DIR)/pcie_2_1_pins.csv $(BUILD_DIR)/pcie_2_1_ports.json --special-pins $(SPECIAL_PINS) + +database: $(BUILD_DIR)/segbits_pcie_bot.db $(BUILD_DIR)/pcie_2_1_ports.json + +$(BUILD_DIR)/segbits_pcie_bot.rdb: $(SPECIMENS_OK) + ${XRAY_SEGMATCH} -o $(BUILD_DIR)/segbits_pcie_bot.rdb $(addsuffix /segdata_pcie_bot.txt,$(SPECIMENS)) + +$(BUILD_DIR)/segbits_pcie_bot.db: $(BUILD_DIR)/segbits_pcie_bot.rdb + ${XRAY_DBFIXUP} --db-root $(BUILD_DIR) --zero-db bits.dbf \ + --seg-fn-in $(BUILD_DIR)/segbits_pcie_bot.rdb \ + --seg-fn-out $(BUILD_DIR)/segbits_pcie_bot.db + ${XRAY_MASKMERGE} $(BUILD_DIR)/mask_pcie_bot.db $(addsuffix /segdata_pcie_bot.txt,$(SPECIMENS)) pushdb: - ${XRAY_MERGEDB} pcie_bot build/segbits_pcie_bot.db - ${XRAY_MERGEDB} mask_pcie_bot build/mask_pcie_bot.db + ${XRAY_MERGEDB} pcie_bot $(BUILD_DIR)/segbits_pcie_bot.db + ${XRAY_MERGEDB} mask_pcie_bot $(BUILD_DIR)/mask_pcie_bot.db + mkdir -p $(CELLS_DATA_DIR) + cp $(FUZDIR)/attrs.json $(CELLS_DATA_DIR)/pcie_2_1_attrs.json + cp $(BUILD_DIR)/pcie_2_1_ports.json $(CELLS_DATA_DIR)/pcie_2_1_ports.json .PHONY: database pushdb diff --git a/fuzzers/061-pcie-conf/generate.py b/fuzzers/061-pcie-conf/generate.py index 8812b1b7..6a6b99bd 100644 --- a/fuzzers/061-pcie-conf/generate.py +++ b/fuzzers/061-pcie-conf/generate.py @@ -10,9 +10,12 @@ # SPDX-License-Identifier: ISC import json +import os from prjxray.segmaker import Segmaker -from params import boolean_params, hex_params, int_params + +BIN = "BIN" +BOOL = "BOOL" def bitfilter(frame, bit): @@ -26,26 +29,34 @@ def bitfilter(frame, bit): def main(): segmk = Segmaker("design.bits") + fuz_dir = os.getenv("FUZDIR", None) + assert fuz_dir + with open(os.path.join(fuz_dir, "attrs.json"), "r") as attr_file: + attrs = json.load(attr_file) + print("Loading tags") with open('params.json') as f: params = json.load(f) site = params['site'] - for param, _ in boolean_params: + for param, param_info in attrs.items(): value = params[param] + param_type = param_info["type"] + param_digits = param_info["digits"] + param_values = param_info["values"] - segmk.add_site_tag(site, param, value) + if param_type == BIN: + bitstr = [ + int(x) for x in "{value:0{digits}b}".format( + value=value, digits=param_digits)[::-1] + ] - for param, digits in hex_params + int_params: - value = int(params[param]) - bitstr = [ - int(x) for x in "{value:0{digits}b}".format( - value=value, digits=digits)[::-1] - ] - - for i in range(digits): - segmk.add_site_tag(site, '%s[%u]' % (param, i), bitstr[i]) + for i in range(param_digits): + segmk.add_site_tag(site, "%s[%u]" % (param, i), bitstr[i]) + else: + assert param_type == BOOL + segmk.add_site_tag(site, param, value == "TRUE") segmk.compile(bitfilter=bitfilter) segmk.write() diff --git a/fuzzers/061-pcie-conf/generate_ports.tcl b/fuzzers/061-pcie-conf/generate_ports.tcl new file mode 100644 index 00000000..603d37ef --- /dev/null +++ b/fuzzers/061-pcie-conf/generate_ports.tcl @@ -0,0 +1,36 @@ +# Copyright (C) 2017-2021 The Project X-Ray Authors +# +# Use of this source code is governed by a ISC-style +# license that can be found in the LICENSE file or at +# https://opensource.org/licenses/ISC +# +# SPDX-License-Identifier: ISC + +proc dump_pins {file_name site_prefix} { + set fp [open $file_name w] + + puts $fp "name,is_input,is_output" + set site [lindex [get_sites $site_prefix*] 0] + + set pins [get_site_pins -of_objects $site] + foreach pin $pins { + set connected_pip [get_pips -of_objects [get_nodes -of_objects $pin]] + + if { $connected_pip == "" } { + continue + } + + set pin_name [lindex [split $pin "/"] 1] + set is_input [get_property IS_INPUT $pin] + set is_output [get_property IS_OUTPUT $pin] + + puts $fp "$pin_name,$is_input,$is_output" + } + close $fp +} + +create_project -force -name design -part $::env(XRAY_PART) +set_property design_mode PinPlanning [current_fileset] +open_io_design -name io_1 + +dump_pins $::env(FILE_NAME) PCIE diff --git a/fuzzers/061-pcie-conf/params.py b/fuzzers/061-pcie-conf/params.py index 976ef0ce..0c17f260 100644 --- a/fuzzers/061-pcie-conf/params.py +++ b/fuzzers/061-pcie-conf/params.py @@ -9,6 +9,10 @@ # # SPDX-License-Identifier: ISC +import argparse +import json +from collections import OrderedDict + boolean_params = [ ("AER_CAP_ECRC_CHECK_CAPABLE", 1), ("AER_CAP_ECRC_GEN_CAPABLE", 1), @@ -300,3 +304,37 @@ int_params = [ ("SPARE_BIT7", 1), ("SPARE_BIT8", 1), ] + + +def dump_json(): + parser = argparse.ArgumentParser() + parser.add_argument("--attrs-file", help="JSON output path", required=True) + args = parser.parse_args() + + data = OrderedDict() + + # Prepare BOOL type attributes + for param in boolean_params: + data[param[0]] = { + "type": "BOOL", + "values": ["FALSE", "TRUE"], + "digits": param[1] + } + + # Prepare BIN type attributes + for param in (hex_params + int_params): + data[param[0]] = { + "type": "BIN", + "values": [(1 << param[1]) - 1], + "digits": param[1] + } + + data = dict(sorted(data.items())) + + # Emit JSON + with open(args.attrs_file, "w") as f: + json.dump(data, f, indent=4) + + +if __name__ == "__main__": + dump_json() diff --git a/fuzzers/061-pcie-conf/top.py b/fuzzers/061-pcie-conf/top.py index c2bf0964..baa04aa0 100644 --- a/fuzzers/061-pcie-conf/top.py +++ b/fuzzers/061-pcie-conf/top.py @@ -16,7 +16,9 @@ random.seed(int(os.getenv("SEED"), 16)) from prjxray import util from prjxray import verilog from prjxray.db import Database -from params import boolean_params, hex_params, int_params + +BIN = "BIN" +BOOL = "BOOL" def gen_sites(): @@ -50,35 +52,33 @@ module top(); verilog_attr = "#(" - # Add boolean parameters - for param, _ in boolean_params: - value = random.randint(0, 1) - value_string = "TRUE" if value else "FALSE" + fuz_dir = os.getenv("FUZDIR", None) + assert fuz_dir + with open(os.path.join(fuz_dir, "attrs.json"), "r") as attrs_file: + attrs = json.load(attrs_file) + for param, param_info in attrs.items(): + param_type = param_info["type"] + param_values = param_info["values"] + param_digits = param_info["digits"] + + if param_type == BOOL: + value = random.choice(param_values) + value_str = verilog.quote(value) + elif param_type == BIN: + if type(param_values) is int: + value = param_values + elif type(param_values) is list: + if len(param_values) > 1: + value = random.choice(param_values) + else: + value = random.randint(0, param_values[0]) + value_str = "{digits}'b{value:0{digits}b}".format( + value=value, digits=param_digits) params[param] = value verilog_attr += """ - .{}({}),""".format(param, verilog.quote(value_string)) - - # Add hexadecimal parameters - for param, digits in hex_params: - value = random.randint(0, 2**digits) - - params[param] = value - - verilog_attr += """ - .{}({}),""".format( - param, "{digits}'h{value:08x}".format(value=value, digits=digits)) - - # Add integer parameters - for param, digits in int_params: - value = random.randint(0, 2**digits) - - params[param] = value - - verilog_attr += """ - .{}({}),""".format( - param, "{digits}'d{value:04d}".format(value=value, digits=digits)) + .{}({}),""".format(param, value_str) verilog_attr = verilog_attr.rstrip(",") verilog_attr += "\n)"