├── test ├── src │ ├── and_port.vhd │ └── test │ │ └── tb_and_port.vhd └── run.py ├── action.yml ├── .github └── workflows │ └── test.yml ├── LICENSE └── README.md /test/src/and_port.vhd: -------------------------------------------------------------------------------- 1 | library IEEE; 2 | use IEEE.STD_LOGIC_1164.ALL; 3 | 4 | entity and_port is 5 | Port ( a: in STD_LOGIC; 6 | b: in STD_LOGIC; 7 | y: out STD_LOGIC); 8 | end and_port; 9 | 10 | architecture arch of and_port is 11 | begin 12 | y <= a and b; 13 | end arch; 14 | -------------------------------------------------------------------------------- /test/run.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from pathlib import Path 4 | from vunit import VUnit 5 | 6 | VU = VUnit.from_argv() 7 | VU.add_osvvm() 8 | VU.add_verification_components() 9 | 10 | SRC_PATH = Path(__file__).parent / "src" 11 | 12 | VU.add_library("lib").add_source_files( 13 | [SRC_PATH / "*.vhd", SRC_PATH / "test" / "*.vhd"] 14 | ) 15 | print([SRC_PATH / "*.vhd", SRC_PATH / "test" / "*.vhd"]) 16 | 17 | VU.main() 18 | -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | name: 'VUnit Action' 2 | description: 'Automatically test your VHDL code with VUnit' 3 | 4 | inputs: 5 | cmd: 6 | description: 'VUnit run script or command (Python)' 7 | default: './run.py' 8 | image: 9 | description: 'Container image to run the script/command on' 10 | default: ghdl/vunit:mcode 11 | 12 | runs: 13 | using: "composite" 14 | steps: 15 | - run: docker run --rm -v $(pwd):/src -w /src ${{ inputs.image }} ${{ inputs.cmd }} 16 | shell: bash 17 | 18 | branding: 19 | icon: cpu 20 | color: blue 21 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: 4 | push: 5 | pull_request: 6 | 7 | jobs: 8 | 9 | action: 10 | runs-on: ubuntu-latest 11 | steps: 12 | 13 | - uses: actions/checkout@v2 14 | 15 | - name: Run VUnit tests 16 | uses: ./ 17 | with: 18 | cmd: test/run.py 19 | 20 | 21 | container-job: 22 | runs-on: ubuntu-latest 23 | container: ghdl/vunit:mcode-master 24 | steps: 25 | 26 | - uses: actions/checkout@v2 27 | 28 | - run: test/run.py 29 | 30 | 31 | container-step: 32 | runs-on: ubuntu-latest 33 | steps: 34 | 35 | - uses: actions/checkout@v2 36 | 37 | - uses: docker://ghdl/vunit:mcode-master 38 | with: 39 | args: test/run.py 40 | -------------------------------------------------------------------------------- /test/src/test/tb_and_port.vhd: -------------------------------------------------------------------------------- 1 | library IEEE; 2 | use IEEE.STD_LOGIC_1164.ALL; 3 | 4 | library vunit_lib; 5 | context vunit_lib.vunit_context; 6 | 7 | entity testbench is 8 | generic (runner_cfg : string); 9 | end testbench; 10 | 11 | architecture arch of testbench is 12 | component and_port 13 | port ( a: in std_logic; 14 | b: in std_logic; 15 | y: out std_logic); 16 | end component; 17 | 18 | -- inputs 19 | signal a : STD_LOGIC := '0'; 20 | signal b : STD_LOGIC := '1'; 21 | signal y : STD_LOGIC; 22 | 23 | begin 24 | 25 | uut: and_port port map ( 26 | a => a, 27 | b => b, 28 | y => y); 29 | 30 | test_runner: process 31 | begin 32 | test_runner_setup(runner, runner_cfg); 33 | 34 | wait for 100 ns; 35 | assert y = '0' report "error 1"; 36 | 37 | wait for 100 ns; 38 | a <= '1'; 39 | 40 | wait for 100 ns; 41 | assert y = '1' report "error 2"; 42 | 43 | test_runner_cleanup(runner); -- Simulation ends here 44 | end process; 45 | 46 | end arch; 47 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Marco Ieni 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 7 | 12 | 17 | 'Test' workflow Status 21 |

22 | 23 | 24 | # VUnit and GitHub Actions 25 | 26 | This repository showcases several approaches for using VUnit in GitHub Actions. Subdir [test](test) contains the sources of an example HDL design, which is tested in the reference workflow: [.github/workflows/test.yml](.github/workflows/test.yml). 27 | 28 | ATTENTION: Currently, execution of tests in OCI containers is supported only. Therefore, designs are tested on GNU/Linux only, because running Windows containers is not supported in GitHub Actions. 29 | 30 | NOTE: Among the simulators supported by VUnit, GHDL is the only one that can be freely used. Therefore, all these solutions use GHDL. However, the syntax is not constrained by that, so any other OCI image with other supported simulators can be used in private repositories and/or with self-hosted runners. 31 | 32 | ## Action 33 | 34 | Using an Action is the most idiomatic and less verbose solution. 35 | 36 | ```yml 37 | runs-on: ubuntu-latest 38 | steps: 39 | 40 | - uses: actions/checkout@v2 41 | 42 | - uses: VUnit/vunit_action@master 43 | with: 44 | cmd: test/run.py 45 | ``` 46 | 47 | ### Options 48 | 49 | - `cmd`: custom command or path to the VUnit top level Python script. Default: `run.py`. 50 | - `image`: OCI image name to run the tests in. Default: `ghdl/vunit:mcode`. 51 | 52 | ## Container Job 53 | 54 | GitHub Actions workflows have built-in support for a job to be executed in a container. This alternative provides a finer grained definition of the steps to be executed in the container, before running the actual test script(s). 55 | 56 | ```yml 57 | runs-on: ubuntu-latest 58 | container: ghdl/vunit:mcode 59 | steps: 60 | 61 | - uses: actions/checkout@v2 62 | 63 | - run: test/run.py 64 | ``` 65 | 66 | ## Container Step 67 | 68 | Running a single step of a workflow inside a container is also supported in GitHub Actions. This solution is similar to the previous one, but allows executing other steps on the host either before or after running the test script(s). 69 | 70 | ```yml 71 | runs-on: ubuntu-latest 72 | steps: 73 | 74 | - uses: actions/checkout@v2 75 | 76 | - uses: docker://ghdl/vunit:mcode 77 | with: 78 | args: test/run.py 79 | ``` 80 | --------------------------------------------------------------------------------