Package: vhdlproc
VHDLprocVHDLproc is a simple command line VHDL preprocessor written in Python following the conditional compilation directives outlined in VHDL-2019, with a few extensions.InstallationVHDLproc can be installed via pip:$ pip install vhdlproc
$ vhdlproc --helpIt can also be installed from source$ git clone https://github.com/nobodywasishere/vhdlproc
$ cd vhdlproc
$ python setup.py install --user
$ vhdlproc --helpIt can also simply be run as a standalone file$ git clone https://github.com/nobodywasishere/vhdlproc
$ cd vhdlproc
$ ./vhdlproc/vhdlproc.py --helpUsageCommand Lineusage: vhdlproc.py [-h] [-D IDENTIFIER=value] [-o DIRECTORY] [-e EXTENSION] [--parse-comments]
                   [--self-test] [--log-level LEVEL]
                   [input ...]

VHDLproc v2.3 - VHDL Preprocessor

positional arguments:
  input                Input files (will skip over files with the output extension)

options:
  -h, --help           show this help message and exit
  -D IDENTIFIER=value  Specify identifiers for conditional compilation, ex. DEBUG_LEVEL=2
  -o DIRECTORY         Directory to store parsed files
  -e EXTENSION         Output extension for processed files (defaults to '.proc.vhdl')
  --parse-comments     Parse commented directives as though they aren't commented, overwrite original
                       file. Disables skipping based on file extension
  --self-test          Run a self-test to ensure functionality
  --log-level LEVEL    Configure the logging levelA basic example, where VHDLproc will parse each input file, output the processed text to a new file with a given extension, and the processed files are then passed to GHDL:vhdlproc*.vhdl# preprocess all the filesghdl-a--std=08*.proc.vhdl# pass processed files to ghdlghdl-r--std=08testbench# run simulationAs VHDLproc also outputs each of the processed filenames to STDOUT, this would also work:ghdl-a--std=08$(vhdlproc*.vhdl)ghdl-r--std=08testbenchThe parsed files can also be stored to another directory:vhdlproc*.vhdl-obuild/# preprocess all the files and store in build/ghdl-a--std=08build/*.vhdl# pass processed files in build/ to ghdlghdl-r--std=08testbench# run simulationCommented directives can also be parsed in-place, including replacingincludedirectives:vhdlproc*.vhdl-e.vhdl--parse-comments# parse commented directives and overwrite original fileghdl-a--std=08*.vhdl# same exact files that were passed to ghdlghdl-r--std=08testbench# run simulationPython LibraryParse files (will automatically set the include path):fromvhdlprocimportVHDLprocprocessor=VHDLproc()identifiers={"VHDL_VERSION":"2008"}parsed_text=processor.parse_file("path/to/file.vhdl",identifiers=identifiers)Parse code directly:fromvhdlprocimportVHDLprocprocessor=VHDLproc()identifiers={"VHDL_VERSION":"2008"}# Parse list of lines of textcode=['`warning "Hello"','constant test_var : integer := 100','`if TOOL_VERSION < "2.0" then','`error "UNSUPPORTED VHDLPROC VERSION"','`end','`include "some/file.vhdl"',]parsed_text=processor.parse(code,identifiers=identifiers,include_path="path/to/pull/include/directives/from")# Parse stringcode='''`warning "Hello"constant test_var : integer := 100`if TOOL_VERSION < "2.0" then`error "UNSUPPORTED VHDLPROC VERSION"`end`include "some/file.vhdl"'''parsed_text=processor.parse(code,identifiers=identifiers,include_path="path/to/pull/include/directives/from")Preprocessor Directives (what you put in your VHDL files)-- VHDL-2019 directives`if{CONDITIONAL}then`elsif{CONDITIONAL}then`else`end[if]`warning"STRING"--PrintSTRINGtostandarderroroutputstream`error"STRING"--PrintSTRINGtostandarderroroutputstream--WillforcecloseVHDLprocwithoutsaving--AdditionalextensionsnotpartofVHDL-2019`defineLABEL"STRING"--GivesLABELthevalueofSTRINGfor--conditionalstatements`include"FILENAME"--Includeanotherfilerelativeto--thelocationofthesource`endinclude"FILENAME"--Thisisacounterpartto`includeforparsingcommenteddirectives--in-place,shouldnotbeuseddirectly(addedautomatically)--Setstheboundofwheretoreplacewhenre-includingafileIdentifiers (or Labels)By default,TOOL_NAMEis set toVHDLprocandTOOL_VERSIONis set to the current version of the code, these cannot be changed.TodoSeperate infix definitions, tests, and the main components of VHDLproc into their own filesPrevent a file from including itself (to prevent infinite loops)Modify text and file operations to work on Windows (if they don't already)Throw an error if a`warningor`errorstring isn't wrapped in quotesParse comments / files in-placeFix precedence of operatorsAdd the option to the CLI to take in a series of file inputs, process them, save the individual results to temporary files (i.e. in/tmp/or a local path), then return all of the filepaths. This would be useful for doing this with GHDL:ghdl -a $(vhdlproc *.vhdl).ExamplesMore examples included undervhdlproc/tests/.Include FileInput:`include"include-to.vhdl"include-to.vhdl:componentpllisport(clk_in:instd_logic;clk_out:outstd_logic;clk_locked:outstd_logic);endcomponent;Output:-- `include "include-to.vhdl"componentpllisport(clk_in:instd_logic;clk_out:outstd_logic;clk_locked:outstd_logic);endcomponent;-- `end include "include-to.vhdl"Define, Repeated If/ElsifInput:`definea"a"`defineb"z"`ifa="a"andb="b"thena="a"andb="b"`elsifa/="a"andb="b"thena/="a"andb="b"`elsifa="a"andb/="b"thena="a"andb/="b"`elsifa/="a"andb/="b"thena/="a"andb/="b"`else`warning"Not supposed to be here"`endOutput:-- `define a "a"-- `define b "z"-- `if a = "a" and b = "b" then-- a = "a" and b = "b"-- `elsif a /= "a" and b = "b" then-- a /= "a" and b = "b"-- `elsif a = "a" and b /= "b" thena="a"andb/="b"-- `elsif a /= "a" and b /= "b" then-- a /= "a" and b /= "b"-- `else-- `warning "Not supposed to be here"-- `endNested IfInput:`definea"a"`defineb"b"`ifa="a"then`ifb="b"thena="a"andb="b"`elsea="a"andb/="b"`end`endOutput:-- `define a "a"-- `define b "b"-- `if a = "a" then-- `if b = "b" thena="a"andb="b"-- `else-- a = "a" and b /= "b"-- `end-- `endVHDL VersionInput:`defineVHDL_VERSION"2019"`ifVHDL_VERSION>="2008"thenconstantenable_features:bool:=true`else`warning"Certain features disabled!"constantenable_features:bool:=false`endOutput:-- `define VHDL_VERSION "2019"-- `if VHDL_VERSION >= "2008" thenconstantenable_features:bool:=true-- `else-- `warning "Certain features disabled!"-- constant enable_features : bool := false-- `endParsing CommentsWith the flag--parse-comments, directives are executed in-place as if they weren't commented. Code added by anincludedirective is replaced with an updated version, bounded by a correspondingend include.Input:-- `warning "== Including file =="-- `define Include_file "TRUE"-- `if INCLUDE_FILE = "TRUE" then-- `include "../tests/include-to.vhdl"componentOLD_CODEisport(a:inunsigned(3downto0);b:inunsigned(3downto0);s:instd_logic_vector(1downto0);y:outunsigned(3downto0));endcomponent;-- `end include "../tests/include-to.vhdl"-- `else-- `error "Not including thing"-- `end if-- `warning "== Not including file =="-- `define Include_file "false"-- `define passed ""-- `if INCLUDE_FILE = "TRUE" then-- `include "../tests/include-to.vhdl"-- `else-- `end if-- `if passed /= "" then-- `Warning "Failed"-- `else-- `Warning "Passed"-- `endinclude-to.vhdl:componentpllisport(clk_in:instd_logic;clk_out:outstd_logic;clk_locked:outstd_logic);endcomponent;`ifinclude_file="false"then`error"Failed"`else`warning"Passed"`end`definepassed"failed"Output:-- `warning "== Including file =="-- `define Include_file "TRUE"-- `if INCLUDE_FILE = "TRUE" then-- `include "../tests/include-to.vhdl"componentpllisport(clk_in:instd_logic;clk_out:outstd_logic;clk_locked:outstd_logic);endcomponent;-- `if include_file = "false" then-- `error "Failed"-- `else-- `warning "Passed"-- `end-- `define passed "failed"-- `end include "../tests/include-to.vhdl"-- `else-- `error "Not including thing"-- `end if-- `warning "== Not including file =="-- `define Include_file "false"-- `define passed ""-- `if INCLUDE_FILE = "TRUE" then-- `include "../tests/include-to.vhdl"-- `else-- `end if-- `if passed /= "" then-- `Warning "Failed"-- `else-- `Warning "Passed"-- `end