Skip to content

Development workflow

Methodology Followed

The project began with a preliminary analysis of vector operations to understand the fundamental components of the future architecture—such as FIFOs, dataflow, and datapath control—for efficient implementation. This initial analysis led to the design of a modular architecture that promotes reusability and facilitates independent testing.

A bottom-up methodology was adopted, starting from basic elements and composing them to form more complex structures. This strategy allowed each module to be modeled, simulated, and verified independently prior to integration.

For module dependency management, the tools Bender and FuseSoC were employed. These tools automate the management of source files across different project phases—simulation, verification, and synthesis for FPGA or ASIC targets. FuseSoC also handles simulation and synthesis commands, allowing for automation through Bash scripts to reduce development time. This setup is described below in environment section.

RTL development was performed using Visual Studio Code with the DVT IDE plugin. This plugin provides an integrated development environment for SystemVerilog, offering real-time code analysis, autocompletion, syntax checking, and refactoring capabilities.

Simulation was conducted using Vivado (xsim) and QuestaSim (vsim). The primary difference between the two is that advanced functional verification is supported only by vsim. For this reason, SystemVerilog Assertions (SVA) were implemented in external modules that are included exclusively during vsim simulations, ensuring a clear separation between RTL code and verification logic.

To diagnose design errors, waveform visualization tools such as GTKWave and QuestaSim were used. These errors were primarily structural in nature; once resolved, the corresponding SVA assertions were added to verify correct behavior.

Finally, the project has been modified to be implemented in a FPGA, specifically the Nexys A7 100T with DSP unit devices. However, this accelerator needs to be implemented alonside a processor that performs all the configuration and initiates the execution.

In summary, the development workflow was based on three main stages: modeling, simulation, and verification of each module. This was executed through an iterative process involving continuous refinement and refactoring to meet the evolving requirements of each development phase.

Project Structure

The table below describes the structure of the project files and directories, all of which are tracked under git version control.

Directory Description
bin Simulation scripts, reports, and utility tools
data Configuration register (hsid_x_ctrl_reg)
hw/src/*/rtl RTL source code for each module
hw/src/*/tb SystemVerilog testbenches
hw/deps Third-party code (external dependencies)
hw/tcl/modelsim-do Tcl scripts for QuestaSim simulation
hw/tcl/vivado-project Tcl scripts for Vivado project generation
hw/waves GTKWave waveform configuration files
hw/xdc Constraint files for synthesis (XDC)
sw Software headers for configuration register access
*.core FuseSoC core configuration files

The following directories are generated by simulation tools, IDEs, or dependency managers such as FuseSoC and Bender. These files are not tracked by git, as they can be safely deleted and regenerated at any time.

Directory Description
reports Verification reports generated by QuestaSim
build Output directory generated by FuseSoC
build/*/sim-xsim Simulation outputs for xsim
build/*/sim-modelsim Simulation outputs for vsim
vivado Vivado projects generated by hsid-vivado-project.sh
.bender Dependency metadata generated by bender
.dvt DVT IDE project configuration files
.vscode Visual Studio Code workspace configuration

Setting the environment

To work with this project, you can configure your Bash environment using the direnv application, which sets all the necessary environment variables when you enter the project directory. You can read more about this tool at direnv – unclutter your .profile | direnv.

By default, the .envrc configuration file is not included in the Git repository, as it depends on your specific setup. Therefore, you should create your own .envrc file using the following template:

layout python3

# Add scripts directory to PATH
export PATH=./bin:$PATH

# Set Vivado settings
export VIVADO_SETTINGS=/opt/vivado/settings64.sh
source $VIVADO_SETTINGS

# Set QuestaSim settings
export QUESTASIM_SETTINGS=/opt/questasim/settings.sh
export LM_LICENSE_FILE=
source $QUESTASIM_SETTINGS

Once you've configured .envrc, allow direnv to execute it by running direnv allow in this directory.

Python libraries

Once the environment is managed with direnv, the project’s Python environment becomes available. The required Python packages are listed in the python-requirements.txt file, which includes FuseSoC, Edalize, and other necessary dependencies. To install these packages, run the following command:

pip install -r requirements.txt
The main packages to be installed from python ecosystem are the following:

  • Hardware build / EDA tooling
    • fusesoc — hardware packaging/build tool used to run simulations and synthesis flows.
    • edalize — EDA backend abstraction used by FuseSoC to target different simulators and tools.
  • Register/format generators & HJSON/JSON handling
    • hjson — parse HJSON files (used for hsid_x_ctrl.hjson).
    • jsonschema2md — generate human-readable docs from JSON schema (used in doc flows).
  • Documentation / site build
    • mkdocs, mkdocs-material — MkDocs static site generator and Material theme used to build the project site.

Bender Installation

Bender is a dependency manager for hardware projects, similar to FuseSoC but with some key differences. One of its main limitations is its reduced flexibility when configuring EDA tools on a per-module basis; however, this functionality is handled by FuseSoC.

The main advantage of Bender is that it enables importing RTL code directly from external git repositories. To do this, the Bender.yml file is configured to declare which repositories to import and their corresponding versions. Furthermore, if the imported projects depend on additional repositories, those dependencies are also fetched automatically.

To download all dependencies, run the following command on the Bash terminal.

bender update

The code from all imported projects will then be copied into the hw/deps directory.