| macro(RUN CMD) | 
 |   message(STATUS "Running \"${CMD}\"") | 
 |   separate_arguments(CMD_LIST NATIVE_COMMAND ${CMD}) | 
 |   execute_process( | 
 |     COMMAND | 
 |       ${CMAKE_COMMAND} -E env | 
 |       ${CMD_LIST} | 
 |     RESULT_VARIABLE | 
 |       CMD_RESULT | 
 |   ) | 
 |   if(CMD_RESULT) | 
 |     message(FATAL_ERROR "Command \"${CMD}\" failed!") | 
 |   endif() | 
 | endmacro() | 
 |  | 
 | # Remove the build directory | 
 | file(REMOVE_RECURSE ${BUILD_DIR}) | 
 |  | 
 | # Run the toolchain | 
 | set(TOOLCHAIN_COMMAND "PATH=${INSTALLATION_DIR}/bin:$ENV{PATH} ${TOOLCHAIN_COMMAND}") | 
 | run(${TOOLCHAIN_COMMAND} "") | 
 |  | 
 | # Verify that all required output files are generated | 
 | message(STATUS "Checking output files...") | 
 |  | 
 | string(REPLACE "," ";" ASSERT_EXISTS "${ASSERT_EXISTS}") | 
 | set(MISSING_FILES FALSE) | 
 |  | 
 | foreach(FILE ${ASSERT_EXISTS}) | 
 |   file(RELATIVE_PATH FNAME ${BUILD_DIR} ${FILE}) | 
 |   if(NOT EXISTS "${FILE}") | 
 |     message(STATUS "[X] '${FNAME}'") | 
 |     set(MISSING_FILES TRUE) | 
 |   else() | 
 |     message(STATUS "[V] '${FNAME}'") | 
 |   endif() | 
 | endforeach() | 
 |  | 
 | if(MISSING_FILES) | 
 |   message(FATAL_ERROR "Some output files are missing!") | 
 | endif() | 
 |  | 
 | # Assert usage and timing if any | 
 | set(PYTHONPATH ${SYMBIFLOW_DIR}/utils) | 
 | set(USAGE_UTIL  ${PYTHONPATH}/report_block_usage.py) | 
 | set(TIMING_UTIL ${PYTHONPATH}/report_timing.py) | 
 |  | 
 | set(BLOCK_USAGE  ${BUILD_DIR}/block_usage.json) | 
 | set(TIMING_SUMMARY ${BUILD_DIR}/timing_summary.json) | 
 |  | 
 | if (NOT "${ASSERT_BLOCK_TYPES_ARE_USED}" STREQUAL "") | 
 |     run("PYTHONPATH=${PYTHONPATH} python3 ${USAGE_UTIL} ${BLOCK_USAGE} --assert_usage ${ASSERT_BLOCK_TYPES_ARE_USED}") | 
 | endif () | 
 |  | 
 | if (NOT "${ASSERT_TIMING}" STREQUAL "") | 
 |     run("PYTHONPATH=${PYTHONPATH} python3 ${TIMING_UTIL} ${TIMING_SUMMARY} --assert ${ASSERT_TIMING}") | 
 | endif () | 
 |  | 
 | # Check if IO constraints has been correctly applied. This is done by verifying | 
 | # the original PCF file agains the one produced by fasm2bels. For this to work | 
 | # "post_verilog" dump option must be enabled for a test (i.e. provided within | 
 | # EXTRA_ARGS). | 
 | set(PCF_UTIL ${PYTHONPATH}/pcf_compare.py) | 
 | set(OUT_PCF  ${BUILD_DIR}/top.bit.v.pcf) | 
 |  | 
 | if (NOT "${REF_PCF}" STREQUAL "") | 
 |     run("PYTHONPATH=${PYTHONPATH} python3 ${PCF_UTIL} ${REF_PCF} ${OUT_PCF}") | 
 | endif() | 
 |  | 
 | # Check if post synthesis verilog has correct format | 
 | # We look for verilog escaped identifiers in ports definitions ending with | 
 | # array indexing, e.g. [0] | 
 | # MERGED_POST_VERILOG shouldn't contain such identifiers | 
 | set(MERGED_POST_VERILOG ${BUILD_DIR}/top_merged_post_implementation.v) | 
 |  | 
 | if (EXISTS "${MERGED_POST_VERILOG}") | 
 |     SET(GREP_ARGS "(input|output)\\s+\\\\\\S*\\[[0-9]*\\]\\s,?" "${MERGED_POST_VERILOG}") | 
 |     message(STATUS "${GREP_ARGS}") | 
 |     EXECUTE_PROCESS( | 
 |         COMMAND | 
 |         grep ${GREP_ARGS} | 
 |         OUTPUT_VARIABLE MERGED_VAL_OUT | 
 |         RESULT_VARIABLE MERGED_VAL_RES) | 
 |  | 
 |     if (${MERGED_VAL_RES} EQUAL 0 AND NOT "${MERGED_VAL_OUT}" STREQUAL "") | 
 |         MESSAGE(FATAL_ERROR "Found illegal escaped identifiers in ${MERGED_POST_VERILOG}: ${MERGED_VAL_OUT}") | 
 |     endif() | 
 | endif() |