| find_program(EOG eog) | |
| find_program(INKSCAPE inkscape) | |
| set(IMAGE_GEN_DPI 300 CACHE STRING "DPI to use when generating images from Verilog SVGs") | |
| set(NETLISTSVG ${f4pga-arch-defs_SOURCE_DIR}/third_party/netlistsvg | |
| CACHE STRING "Directory to netlistsvg.") | |
| set(NETLISTSVG_BIN ${NETLISTSVG}/bin/netlistsvg.js) | |
| set(NETLISTSVG_SKIN ${NETLISTSVG}/lib/default.svg) | |
| set(NETLISTSVG_LOCK ${NETLISTSVG}/package-lock.json) | |
| function(setup_netlistsvg) | |
| # Creates target netlistsvg that installs netlistsvg to the local node | |
| # environment. | |
| get_target_property_required(NODE env NODE) | |
| get_target_property_required(NPM env NPM) | |
| add_custom_command( | |
| OUTPUT ${NETLISTSVG_LOCK} | |
| COMMAND ${NODE} ${NPM} install | |
| WORKING_DIRECTORY ${NETLISTSVG} | |
| DEPENDS | |
| ${NODE} | |
| ${NPM} | |
| ${NETLISTSVG}/package.json | |
| ) | |
| add_custom_target( | |
| netlistsvg DEPENDS ${NETLISTSVG_LOCK} | |
| ) | |
| endfunction() | |
| setup_netlistsvg() | |
| function(add_svg_image) | |
| # ~~~ | |
| # ADD_SVG_IMAGE( | |
| # NAME <name> | |
| # FILE <svg filename> | |
| # ) | |
| # ~~~ | |
| # | |
| # ADD_SVG_IMAGE adds two targets, render_<name> and view_<name>. | |
| # | |
| # render_<name> will convert <svg filename> to a png with the name | |
| # <svg filename>.png. SVG will be rendered at IMAGE_GEN_DPI, a CMake cache | |
| # veriable, defaulting to 300. | |
| # | |
| # view_<name> will generated the render PNG and view it using eog. | |
| set(options) | |
| set(oneValueArgs NAME FILE) | |
| set(multiValueArgs) | |
| cmake_parse_arguments( | |
| ADD_SVG_IMAGE | |
| "${options}" | |
| "${oneValueArgs}" | |
| "${multiValueArgs}" | |
| ${ARGN} | |
| ) | |
| set(SRC_SVG ${ADD_SVG_IMAGE_FILE}) | |
| get_filename_component(SRC_BASE ${SRC_SVG} NAME) | |
| set(SRC_PNG ${SRC_BASE}.png) | |
| set(DEPS "") | |
| append_file_dependency(DEPS ${SRC_SVG}) | |
| add_custom_command( | |
| OUTPUT ${SRC_PNG} | |
| COMMAND ${INKSCAPE} --export-png ${SRC_PNG} --export-dpi ${IMAGE_GEN_DPI} ${SRC_SVG} | |
| DEPENDS ${DEPS} ${INKSCAPE} | |
| ) | |
| add_custom_target( | |
| render_${ADD_SVG_IMAGE_NAME} | |
| DEPENDS ${SRC_PNG} ${EOG} | |
| ) | |
| add_custom_target( | |
| view_${ADD_SVG_IMAGE_NAME} | |
| COMMAND ${EOG} ${SRC_PNG} | |
| DEPENDS ${SRC_PNG} ${EOG} | |
| ) | |
| endfunction() | |
| function(add_verilog_image_gen) | |
| # ~~~ | |
| # ADD_VERILOG_IMAGE_GEN( | |
| # FILE <verilog filename> | |
| # ) | |
| # ~~~ | |
| # | |
| # ADD_VERILOG_IMAGE_GEN converts a verilog file into several image outputs. | |
| # | |
| # ADD_VERILOG_IMAGE_GEN always generates output file names by first stripping | |
| # all extensions from the input filename. So ff.sim.v has a basename of ff. | |
| # | |
| # ADD_VERILOG_IMAGE_GEN first generates an SVG, and then uses ADD_SVG_IMAGE | |
| # to render the SVG and view it. | |
| # | |
| # Output SVGs: | |
| # | |
| # * <basename>.bb.yosys.svg - Netlist rendered by yosys, not flattened. | |
| # * <basename>.flat.yosys.svg - Netlist rendered by yosys, flattened. | |
| # * <basename>.bb.svg - Netlist rendered by netlistsvg, not flattened. | |
| # * <basename>.flat.svg - Netlist rendered by yosys, flattened. | |
| # * <basename>.aig.svg - Netlist rendered by yosys, flattened and run | |
| # through yosys's aigmap. | |
| # | |
| # ADD_VERILOG_IMAGE_GEN generates viewing targets with the following | |
| # convention: | |
| # | |
| # view_<relative directory from root, slashes replaced with underscores>_<basename>.<bb|flat|aig>[.yosys] | |
| # | |
| # Example: | |
| # | |
| # view_testarch_primitives_ff_ff.aig | |
| # view_testarch_primitives_ff_ff.bb.yosys | |
| # | |
| set(options) | |
| set(oneValueArgs FILE) | |
| set(multiValueArgs) | |
| cmake_parse_arguments( | |
| ADD_VERILOG_IMAGE_GEN | |
| "${options}" | |
| "${oneValueArgs}" | |
| "${multiValueArgs}" | |
| ${ARGN} | |
| ) | |
| set(SRC ${ADD_VERILOG_IMAGE_GEN_FILE}) | |
| set(DEPS "") | |
| append_file_dependency(DEPS ${SRC}) | |
| get_file_location(SRC_LOCATION ${SRC}) | |
| get_filename_component(SRC_BASE ${SRC} NAME_WE) | |
| string(TOUPPER ${SRC_BASE} SIM_TOP) | |
| get_filename_component(SRC_DIR ${SRC} DIRECTORY) | |
| set(SRC_BB_JSON ${SRC_BASE}.bb.json) | |
| set(SRC_AIG_JSON ${SRC_BASE}.aig.json) | |
| set(SRC_FLAT_JSON ${SRC_BASE}.flat.json) | |
| set(SRC_BB_YOSYS_SVG ${SRC_BASE}.bb.yosys.svg) | |
| set(SRC_FLAT_YOSYS_SVG ${SRC_BASE}.flat.yosys.svg) | |
| set(SVGS ${SRC_BB_YOSYS_SVG} ${SRC_FLAT_YOSYS_SVG}) | |
| get_target_property_required(YOSYS env YOSYS) | |
| get_target_property_required(NODE env NODE) | |
| add_custom_command( | |
| OUTPUT ${SRC_BB_JSON} | |
| COMMAND ${YOSYS} -p "prep -top ${SIM_TOP} $<SEMICOLON> write_json ${SRC_BB_JSON}" ${SRC_LOCATION} | |
| DEPENDS ${DEPS} ${YOSYS} | |
| WORKING_DIRECTORY ${SRC_DIR} | |
| VERBATIM | |
| ) | |
| add_custom_command( | |
| OUTPUT ${SRC_BB_YOSYS_SVG} | |
| COMMAND ${YOSYS} -p "prep -top ${SIM_TOP} $<SEMICOLON> show -format svg -prefix ${SRC_BASE}.bb.yosys ${SIM_TOP}" ${SRC} | |
| DEPENDS ${DEPS} ${YOSYS} | |
| WORKING_DIRECTORY ${SRC_DIR} | |
| VERBATIM | |
| ) | |
| add_custom_command( | |
| OUTPUT ${SRC_AIG_JSON} | |
| COMMAND ${YOSYS} -p "prep -top ${SIM_TOP} -flatten $<SEMICOLON> aigmap $<SEMICOLON> write_json ${SRC_AIG_JSON}" ${SRC} | |
| DEPENDS ${DEPS} ${YOSYS} | |
| WORKING_DIRECTORY ${SRC_DIR} | |
| VERBATIM | |
| ) | |
| add_custom_command( | |
| OUTPUT ${SRC_FLAT_JSON} | |
| COMMAND ${YOSYS} -p "prep -top ${SIM_TOP} -flatten $<SEMICOLON> write_json ${SRC_FLAT_JSON}" ${SRC} | |
| DEPENDS ${DEPS} ${YOSYS} | |
| WORKING_DIRECTORY ${SRC_DIR} | |
| VERBATIM | |
| ) | |
| add_custom_command( | |
| OUTPUT ${SRC_FLAT_YOSYS_SVG} | |
| COMMAND ${YOSYS} -p "prep -top ${SIM_TOP} -flatten $<SEMICOLON> show -format svg -prefix ${SRC_BASE}.flat.yosys ${SIM_TOP}" ${SRC} | |
| DEPENDS ${DEPS} ${YOSYS} | |
| WORKING_DIRECTORY ${SRC_DIR} | |
| VERBATIM | |
| ) | |
| foreach(SRC_JSON ${SRC_BB_JSON} ${SRC_AIG_JSON} ${SRC_FLAT_JSON}) | |
| string(REGEX REPLACE "json$" "svg" | |
| SRC_SVG ${SRC_JSON}) | |
| list(APPEND SVGS ${SRC_SVG}) | |
| add_custom_command( | |
| OUTPUT ${SRC_SVG} | |
| COMMAND ${NODE} ${NETLISTSVG_BIN} ${SRC_JSON} -o ${SRC_SVG} --skin ${NETLISTSVG_SKIN} | |
| DEPENDS ${NODE} ${NETLISTSVG_BIN} ${NETLISTSVG_SKIN} netlistsvg ${SRC_JSON} | |
| ) | |
| endforeach() | |
| foreach(SRC_SVG ${SVGS}) | |
| add_file_target(FILE ${SRC_SVG} GENERATED) | |
| string(REGEX REPLACE "\.svg$" "" | |
| BASENAME ${SRC_SVG}) | |
| set(DIR ${CMAKE_CURRENT_SOURCE_DIR}) | |
| string(REPLACE ${f4pga-arch-defs_SOURCE_DIR}/ "" BASE_FOLDER ${DIR}) | |
| string(REPLACE "/" "_" BASE_FOLDER_UNDERSCORE ${BASE_FOLDER}) | |
| add_svg_image( | |
| NAME ${BASE_FOLDER_UNDERSCORE}_${BASENAME} | |
| FILE ${SRC_SVG} | |
| ) | |
| endforeach() | |
| endfunction() |