{"id":17557284,"url":"https://github.com/nobodywasishere/vhdlproc","last_synced_at":"2025-04-24T04:51:01.536Z","repository":{"id":49292587,"uuid":"277450744","full_name":"nobodywasishere/VHDLproc","owner":"nobodywasishere","description":"VHDLproc is a VHDL preprocessor","archived":false,"fork":false,"pushed_at":"2022-05-12T17:34:15.000Z","size":486,"stargazers_count":24,"open_issues_count":1,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-18T18:28:31.302Z","etag":null,"topics":["preprocessing","python","vhdl","vhdl-preprocessor"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nobodywasishere.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-07-06T05:30:18.000Z","updated_at":"2024-10-14T14:55:08.000Z","dependencies_parsed_at":"2022-09-06T17:10:36.359Z","dependency_job_id":null,"html_url":"https://github.com/nobodywasishere/VHDLproc","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nobodywasishere%2FVHDLproc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nobodywasishere%2FVHDLproc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nobodywasishere%2FVHDLproc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nobodywasishere%2FVHDLproc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nobodywasishere","download_url":"https://codeload.github.com/nobodywasishere/VHDLproc/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250566445,"owners_count":21451230,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["preprocessing","python","vhdl","vhdl-preprocessor"],"created_at":"2024-10-21T09:05:54.240Z","updated_at":"2025-04-24T04:51:01.516Z","avatar_url":"https://github.com/nobodywasishere.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# VHDLproc\n\nVHDLproc is a simple command line VHDL preprocessor written in Python following the conditional compilation directives outlined in VHDL-2019, with a few extensions.\n\n## Installation\n\nVHDLproc can be installed via pip:\n```\n$ pip install vhdlproc\n$ vhdlproc --help\n```\n\nIt can also be installed from source\n```\n$ git clone https://github.com/nobodywasishere/vhdlproc\n$ cd vhdlproc\n$ python setup.py install --user\n$ vhdlproc --help\n```\n\nIt can also simply be run as a standalone file\n```\n$ git clone https://github.com/nobodywasishere/vhdlproc\n$ cd vhdlproc\n$ ./vhdlproc/vhdlproc.py --help\n```\n\n## Usage\n\n### Command Line\n\n```\nusage: vhdlproc.py [-h] [-D IDENTIFIER=value] [-o DIRECTORY] [-e EXTENSION] [--parse-comments]\n                   [--self-test] [--log-level LEVEL]\n                   [input ...]\n\nVHDLproc v2.3 - VHDL Preprocessor\n\npositional arguments:\n  input                Input files (will skip over files with the output extension)\n\noptions:\n  -h, --help           show this help message and exit\n  -D IDENTIFIER=value  Specify identifiers for conditional compilation, ex. DEBUG_LEVEL=2\n  -o DIRECTORY         Directory to store parsed files\n  -e EXTENSION         Output extension for processed files (defaults to '.proc.vhdl')\n  --parse-comments     Parse commented directives as though they aren't commented, overwrite original\n                       file. Disables skipping based on file extension\n  --self-test          Run a self-test to ensure functionality\n  --log-level LEVEL    Configure the logging level\n```\n\nA 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:\n\n```bash\nvhdlproc *.vhdl              # preprocess all the files\nghdl -a --std=08 *.proc.vhdl # pass processed files to ghdl\nghdl -r --std=08 testbench   # run simulation\n```\n\nAs VHDLproc also outputs each of the processed filenames to STDOUT, this would also work:\n```bash\nghdl -a --std=08 $(vhdlproc *.vhdl)\nghdl -r --std=08 testbench\n```\n\nThe parsed files can also be stored to another directory:\n```bash\nvhdlproc *.vhdl -o build/     # preprocess all the files and store in build/\nghdl -a --std=08 build/*.vhdl # pass processed files in build/ to ghdl\nghdl -r --std=08 testbench    # run simulation\n```\n\nCommented directives can also be parsed in-place, including replacing `include` directives:\n\n```bash\nvhdlproc *.vhdl --parse-comments # parse commented directives and overwrite original file\nghdl -a --std=08 *.vhdl       # same exact files that were passed to ghdl\nghdl -r --std=08 testbench    # run simulation\n```\n\n### Python Library\n\nParse files (will automatically set the include path):\n\n```python\nfrom vhdlproc import VHDLproc\n\nprocessor = VHDLproc()\n\nidentifiers = {\"VHDL_VERSION\": \"2008\"}\n\nparsed_text = processor.parse_file(\"path/to/file.vhdl\", identifiers=identifiers)\n```\n\nParse code directly:\n\n```python\nfrom vhdlproc import VHDLproc\n\nprocessor = VHDLproc()\n\nidentifiers = {\"VHDL_VERSION\": \"2008\"}\n\n# Parse list of lines of text\ncode = [\n    '`warning \"Hello\"',\n    'constant test_var : integer := 100',\n    '`if TOOL_VERSION \u003c \"2.0\" then',\n    '`error \"UNSUPPORTED VHDLPROC VERSION\"',\n    '`end',\n    '`include \"some/file.vhdl\"',\n]\n\nparsed_text = processor.parse(code, identifiers=identifiers, include_path=\"path/to/pull/include/directives/from\")\n\n# Parse string\ncode = '''\n`warning \"Hello\"\nconstant test_var : integer := 100\n`if TOOL_VERSION \u003c \"2.0\" then\n`error \"UNSUPPORTED VHDLPROC VERSION\"\n`end\n`include \"some/file.vhdl\"\n'''\n\nparsed_text = processor.parse(code, identifiers=identifiers, include_path=\"path/to/pull/include/directives/from\")\n```\n\n### Preprocessor Directives (what you put in your VHDL files)\n\n```vhdl\n-- VHDL-2019 directives\n\n`if {CONDITIONAL} then\n\n`elsif {CONDITIONAL} then\n\n`else\n\n`end [if]\n\n`warning \"STRING\"       --   Print STRING to standard error output stream\n\n`error \"STRING\"         --   Print STRING to standard error output stream\n                        --   Will force close VHDLproc without saving\n\n-- Additional extensions not part of VHDL-2019\n\n`define LABEL \"STRING\"  --   Gives LABEL the value of STRING for\n                        --   conditional statements\n\n`include \"FILENAME\"     --   Include another file relative to\n                        --   the location of the source\n\n`end include \"FILENAME\" --   This is a counterpart to `include for parsing commented directives\n                        --   in-place, should not be used directly (added automatically)\n                        --   Sets the bound of where to replace when re-including a file\n```\n\n### Identifiers (or Labels)\n\nBy default, `TOOL_NAME` is set to `VHDLproc` and `TOOL_VERSION` is set to the current version of the code, these cannot be changed.\n\n## Todo\n\n- [ ] Seperate infix definitions, tests, and the main components of VHDLproc into their own files\n- [ ] Prevent a file from including itself (to prevent infinite loops)\n- [ ] Modify text and file operations to work on Windows (if they don't already)\n- [ ] Throw an error if a `` `warning `` or `` `error `` string isn't wrapped in quotes\n- [x] Parse comments / files in-place\n- [x] Fix precedence of operators\n- [x] Add 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)`. \n\n## Examples\n\nMore examples included under `vhdlproc/tests/`.\n\n### Include File\n\nInput:\n\n```vhdl\n`include \"include-to.vhdl\"\n```\n\ninclude-to.vhdl:\n\n```vhdl\ncomponent pll is\n    port (\n        clk_in : in std_logic;\n        clk_out : out std_logic;\n        clk_locked : out std_logic\n    );\nend component;\n```\n\nOutput:\n\n```vhdl\n-- `include \"include-to.vhdl\"\ncomponent pll is\n    port (\n        clk_in : in std_logic;\n        clk_out : out std_logic;\n        clk_locked : out std_logic\n    );\nend component;\n-- `end include \"include-to.vhdl\"\n```\n\n### Define, Repeated If/Elsif\n\nInput:\n```vhdl\n`define a \"a\"\n`define b \"z\"\n\n`if a = \"a\" and b = \"b\" then\na = \"a\" and b = \"b\"\n`elsif a /= \"a\" and b = \"b\" then\na /= \"a\" and b = \"b\"\n`elsif a = \"a\" and b /= \"b\" then\na = \"a\" and b /= \"b\"\n`elsif a /= \"a\" and b /= \"b\" then\na /= \"a\" and b /= \"b\"\n`else\n`warning \"Not supposed to be here\"\n`end\n```\n\nOutput:\n```vhdl\n-- `define a \"a\"\n-- `define b \"z\"\n\n-- `if a = \"a\" and b = \"b\" then\n-- a = \"a\" and b = \"b\"\n-- `elsif a /= \"a\" and b = \"b\" then\n-- a /= \"a\" and b = \"b\"\n-- `elsif a = \"a\" and b /= \"b\" then\na = \"a\" and b /= \"b\"\n-- `elsif a /= \"a\" and b /= \"b\" then\n-- a /= \"a\" and b /= \"b\"\n-- `else\n-- `warning \"Not supposed to be here\"\n-- `end\n```\n\n### Nested If\n\nInput:\n```vhdl\n`define a \"a\"\n`define b \"b\"\n\n`if a = \"a\" then\n`if b = \"b\" then\na = \"a\" and b = \"b\"\n`else\na = \"a\" and b /= \"b\"\n`end\n`end\n```\n\nOutput:\n```vhdl\n-- `define a \"a\"\n-- `define b \"b\"\n\n-- `if a = \"a\" then\n-- `if b = \"b\" then\na = \"a\" and b = \"b\"\n-- `else\n-- a = \"a\" and b /= \"b\"\n-- `end\n-- `end\n```\n\n### VHDL Version\n\nInput:\n```vhdl\n`define VHDL_VERSION \"2019\"\n`if VHDL_VERSION \u003e= \"2008\" then\nconstant enable_features : bool := true\n`else\n`warning \"Certain features disabled!\"\nconstant enable_features : bool := false\n`end\n```\n\nOutput:\n```vhdl\n-- `define VHDL_VERSION \"2019\"\n-- `if VHDL_VERSION \u003e= \"2008\" then\nconstant enable_features : bool := true\n-- `else\n-- `warning \"Certain features disabled!\"\n-- constant enable_features : bool := false\n-- `end\n```\n\n### Parsing Comments\n\nWith the flag `--parse-comments`, directives are executed in-place as if they weren't commented. Code added by an `include` directive is replaced with an updated version, bounded by a corresponding `end include`.\n\nInput:\n```vhdl\n-- `warning \"== Including file ==\"\n-- `define Include_file \"TRUE\"\n\n-- `if INCLUDE_FILE = \"TRUE\" then\n-- `include \"../tests/include-to.vhdl\"\ncomponent OLD_CODE is\n  port(\n\t  a : in unsigned(3 downto 0);\n\t  b : in unsigned(3 downto 0);\n\t  s : in std_logic_vector(1 downto 0);\n\t  y : out unsigned(3 downto 0)\n  );\nend component;\n-- `end include \"../tests/include-to.vhdl\"\n-- `else\n-- `error \"Not including thing\"\n-- `end if\n\n-- `warning \"== Not including file ==\"\n-- `define Include_file \"false\"\n-- `define passed \"\"\n\n-- `if INCLUDE_FILE = \"TRUE\" then\n-- `include \"../tests/include-to.vhdl\"\n-- `else\n-- `end if\n\n-- `if passed /= \"\" then\n-- `Warning \"Failed\"\n-- `else\n-- `Warning \"Passed\"\n-- `end\n```\n\ninclude-to.vhdl:\n\n```vhdl\ncomponent pll is\n    port (\n        clk_in : in std_logic;\n        clk_out : out std_logic;\n        clk_locked : out std_logic\n    );\nend component;\n`if include_file = \"false\" then\n`error \"Failed\"\n`else\n`warning \"Passed\"\n`end\n\n`define passed \"failed\"\n```\n\nOutput:\n```vhdl\n-- `warning \"== Including file ==\"\n-- `define Include_file \"TRUE\"\n\n-- `if INCLUDE_FILE = \"TRUE\" then\n-- `include \"../tests/include-to.vhdl\"\ncomponent pll is\n    port (\n        clk_in : in std_logic;\n        clk_out : out std_logic;\n        clk_locked : out std_logic\n    );\nend component;\n-- `if include_file = \"false\" then\n-- `error \"Failed\"\n-- `else\n-- `warning \"Passed\"\n-- `end\n\n-- `define passed \"failed\"\n-- `end include \"../tests/include-to.vhdl\"\n-- `else\n-- `error \"Not including thing\"\n-- `end if\n\n-- `warning \"== Not including file ==\"\n-- `define Include_file \"false\"\n-- `define passed \"\"\n\n-- `if INCLUDE_FILE = \"TRUE\" then\n-- `include \"../tests/include-to.vhdl\"\n-- `else\n-- `end if\n\n-- `if passed /= \"\" then\n-- `Warning \"Failed\"\n-- `else\n-- `Warning \"Passed\"\n-- `end\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnobodywasishere%2Fvhdlproc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnobodywasishere%2Fvhdlproc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnobodywasishere%2Fvhdlproc/lists"}