## VeriSnip-Overview

VeriSnip (VS) is a project designed to bring the power of Verilog scripting to the open‑source hardware community. This tool simplifies the generation of Verilog modules or snippets by seamlessly integrating with other programs. The generated files can be easily included in any Verilog project. The motivation behind this work is so that creating hardware modules is a process of creating a template file written in Verilog and letting your programs/scripts generate the hardware. These scripts are included in your Verilog template file using Verilog snippets.

With VeriSnip, the process of calling programs or scripts responsible for generating Verilog files is streamlined. After file generation, VeriSnip neatly organizes all Hardware Description Languages (HDL) and TestBench files under the build directory.

Learn more about how VeriSnip works [here](#how-to-use-verisnip).

### Index

1. [How to use VeriSnip (*vs\_build.py*)](#how-to-use-verisnip)
2. [*vs\_colours.py*](#vtcolors)
3. [MyLibrary](#mylibrary)
4. [Opening Issues](#opening-an-issue)
5. [Contributing](#contributing)
6. [Development Environment](#development-environment)
7. [Credits](#credits)

## How to use VeriSnip (aka, *vs\_build*)

The ***vs\_build*** script serves as the cornerstone of the VeriSnip tool‑chain, encompassing core functions essential for project compilation. This script orchestrates the creation of the build directory, housing Verilog modules and headers crucial for the project's hardware implementation.
The code residing under the `./build` directory represents the compiled output ready for simulation and FPGA synthesis.

### Run *vs\_build.py*

***vs\_build*** must receive at least one argument.
To show the help page:

> Usage: python *vs\_build*.py --help

Create a build directory containing all the compiled hardware:

> Usage: python *vs\_build*.py \<main\_module> --TestBench \<testbench\_name> --Boards \<board\_modules>
> \<main\_module> -> This is the name of the main RTL design.
> \--TestBench \<testbench\_name> (optional) -> by default *vs\_build* looks for a TestBench file with the name \<main\_module>\_tb.
> \--Boards \<board\_modules> (optional) -> by default *vs\_build* looks for NO board RTL design top module. Multiple boards can be passed in a single argument (example, "Board1 Board2 Board3").
> \--quiet (optional) -> suppresses INFO prints.
> \--debug (optional) -> enables DEBUG prints.

Clean the contents generated by *vs\_build*:

> Usage: python *vs\_build*.py --clean all
> all (optional) -> By default "--clean" only removes the "build" directory, with "all" it also removes the "hardware/generated" directory.

Example of calling ***vs\_build***:
`python3 ./*vs_build* top_module --TestBench top_module_tb --Boards "top_module_ecp5"`
or
`./*vs_build* --help`

### Using Verilog Snippets (.vs)

Users need to include the corresponding `.vs` file in their Verilog modules to enable VeriSnip to search for or generate a Verilog Snippet. For example:

```verilog
module example (
  `include "example_ios.vs" // VS_NO_GENERATE
);
  `include "example_contents.vs" /*
    Argument passed to the program/script that generates example_contents.vs
  */
endmodule
```

In the above example, VeriSnip scans for a program or script whose name resembles the Verilog Snippet name (excluding the file extension).  
The statement `include "example_contents.vs"` corresponds to a program or script named either `example.*` or `example_contents.*`, where `*` represents any supported file extension.  

Since `include "example_ios.vs"` is followed by `VS_NO_GENERATE`, VeriSnip will ignore this file and will not attempt to generate it.  
The file can be generated later by another include statement if necessary.

For another example, refer to the [MyReg module](MyLibrary/modules/MyReg.v).  
You can run `vs_build myreg` to execute a small build with VeriSnip.

**Note:** Avoid including a file on the first line of a Verilog source file, as this is not supported.  
Instead, use the beginning of the file to provide a brief introduction or description of its contents.

### Creating a Compatible Program/Script for Verilog Snippet Generation

Users have the flexibility to create custom programs or scripts for generating ".vs" files or Verilog modules, or they can utilize existing ones. It's crucial to note that all scripts responsible for generating Verilog code, whether modules or ".vs" files, are independent of "*vs\_build*." "*vs\_build*" exclusively calls these scripts without importing them into the project.

**Supported File Extensions and Corresponding Languages:**
Currently, VeriSnip supports programs and scripts with the following file extensions:

* ".py" for Python
* ".sh" for Bash
* ".lua" for Lua
* ".scala" for Scala
* ".rb" for Ruby
* ".pl" for Perl
* ".vt" for Verilog Template (a custom extension)

The Verilog Template extension (".vt") is specific to VeriSnip. If you compile a program that generates a Verilog module or snippet, you can use the ".vt" extension to enable VeriSnip to locate it.

When *vs\_build* calls another program ([see example here](*vs_build*.py#L238)), it passes a variable number of arguments. Nevertheless, it always follows the same order. Therefore, take into consideration the following arguments and their order when developing your program or script:

* Path to the program or script being called
* Difference between the ".vs" filename and the program/script name. It corresponds to the suffix of the program/script name
* Comment written after the "\`include"
* File where the include is being called from, therefore the file where the "\`include" is written
* *vs\_build* received arguments (excluding its own name)

### Code structure

***vs\_build*** code is distinctly divided into three stages.

* in **1st stage** the function `find_vs_scripts_and_verilog()` finds all existing verilog modules, headers, snippets and scripts under the current directory.
* the **2nd stage** is where it finds the verilog modules and snippets needed by the core. If a verilog module or a snippet does not exist it will try to generate them. The generated snippets should be stored under the `./rtl/generated` directory. The function called for this stage is `verilog_fetch()`.
* during the **3rd stage** all verilog snippet files included are substituted for its content. Those files are then stored under the `./build` directory.

#### **2nd stage** - details

* When calling scripts to generate ".vs" priority is always given to scripts with the full name of the file. If there is no script corresponding to the ".vs" name look for a script that corresponds only to the initial part of the name. Example:

  * in `include "io_modules.vs"` look for `VTio.py` or `io.py` if `io_modules.py` does not exist.
* When calling scripts that generate modules the script should have the name of the module.
* "*vs\_build*" only calls the scripts if they are newer than the files already existent.
* When there are two or more scripts with the same name a warning should be printed and the script with the closest directory path should be used.
* All files and scripts should only be looked for from the base directory of the project, unless specified otherwise in a custom script.

#### **3rd stage** - details

* all files which are generated should have a copy in the "aux" directory
* "*vs\_build*" substitutes the ".vs" and copies the modules needed to the build directory, after finding or generating all modules and ".vs" files.

## *vs\_colours*

This script defines the colors that should be used when printing error, warning or successful messages.
It defines the `print_coloured()` function and some variables that allow to modify the text printed to the console.

## MyLibrary

The "MyLibrary" directory contains hardware Verilog modules, snippets and scripts that might be commonly reused.

### Scripts

This section of the README contains information about the scripts present under the `./library/scripts` directory.
Read more about each script in the [README.md on the scripts directory](https://github.com/PedroAntunes178/VT-Tool/tree/main/MyLibrary/scripts/README.md).

## Opening an Issue

Welcome to our issue reporting system! We appreciate your contribution to the project by reporting any issues you encounter. Your feedback helps us make this project even better.

### How to Open an Issue

When opening an issue, please follow this format:

> **Issue Title**: A concise and descriptive title for the issue.

> Hello **Tag the developers you think might be able to help**,
>
> ## Issue Description:
>
> Provide a detailed description of the issue you encountered. Include information about your environment, steps to reproduce the issue, and any error messages. The more details you provide, the easier it is for us to understand and address the problem.
>
> ## Solution Reference (Optional):
>
> If you have a solution in mind, you're welcome to present it and provide a detailed explanation of why you believe it will work. If possible, include references to supporting pages or documentation that back your proposed solution. This can help us better understand your perspective and expedite the resolution process.
>
> ## Suggested Changes (Optional):
>
> If you have ideas for changes that might solve the issue, propose them here. Be clear and concise in your suggestions.
>
> ## Additional Question (Optional):
>
> If you have questions directly or indirectly related to the issue, feel free to ask them in this section.

Tag developers by using `@username` to get their attention.

We appreciate your help in improving this project!

## Contributing

All contributions to this project are warmly welcomed.

Contributions in the form of automatically generated Verilog scripts should be placed within the hardware/scripts directory. Additionally, contributors are required to create a corresponding section in the README when adding a script. This section should detail the generated core and provide instructions on the script's usage. It is important that the section structure aligns with the structures of other script sections.

## Development Environment

To utilize *vs\_build*, all that's necessary is Python3 and support for the scripting languages in which your scripts are written.

## Credits

This project idea came to me while I was working at IObundle. IObundle was developing a similar open-source tool called python-setup. The two projects are fundamentally different. Therefore I decided to create this project from 0 instead of contributing the ideas and tools directly to IObundle's python-setup.

Where the two projects are similar is both are being developed to generate automatic verilog.

Where they mainly differ is on the way the verilog is generated. The IObundle python-setup project aims to generate all the verilog core using a python framework. VeriSnip aims to substitute the .vs files present on the verilog code, generating the .vs code as needed. There may also exist scripts that generate .v modules.
