Maintaining a good structure for a Project helps bring together the various aspects of Technology IP, the Design Flow tools and all their interactions, files the generate, etc. Investing time in Project Structure can simplify design activity and ease maintenance later on, especially in a collaborative environment.
This involves thinking about a few key factors:
- How can multiple people work collaboratively on the shared project?
- How can you navigate your project intuitively?
- How can use reduce design duplication?
- Only have one copy of each file in your project
- How easily can you deliver your project to others and allow them to use it without lots of fiddling around?
- How can you segregate your design files from others provided by 3rd parties?
- How can you automate routine tasks that need to be performed?
Version Control systems such as Git can be incredibly useful tools and help provide structure to answer a lot of the questions above. Having a single or multiple repositories for your design files enables:
- Collaboration with people able to work on different features of a project independently using branches which can then be merged, making it easy to track and visualise changes as well as see who is contributing to specific parts of a project
- Delivery to others by download and use your code by cloning the repositories
Here we use a case study of our current work to examine using a git repository to show some recommendations for building a design hierarchy to give a good collaborative project structure. It is based on creating a custom accelerator for the NanoSoC reference design.
The proposed structure allows people to create a fork of the Project repository which contains all the necessary elements to instantiate a project. In this case our Project is a SoC to support independent accelerator design. We want a structure that allows clear segregation of design files so the accelerator design can be provided independently of IP from 3rd parties (the Arm IP, NanoSoC, etc.). We also want to support a variety of target platforms. These design constraints lead us to structure the project into multiple sub-modules, the core SoC infrastructure ('NanoSoC'), the interface to any accelerators ('Wrapper IP'), the target technology libraries ( for FPGA and ASIC),the Project's accelerator engine repository (which can can be set up as the Project team wish), other SoCLabs IP (RTL Primitives) and some flow repositories to allow for simulation and code generation.
The Project repository has 4 main tasks:
- Automatically set up your environment – a simple script which you source within your terminal will set up all the environment variables for each directory. Many of the tools in the Design Flow stages depend on environment variables to operate effectively so ensuring these are establish is important.
- Make it easier to control your dependencies – the top-level repository can dictate which version (commit) of the submodules is being used and can be used to freeze a design. It also makes it easier to re-clone an environment or deliver it to others to work on and use.
- Increase ease of wiring and reduce likelihood of wiring errors – template files are provided for simplified modification instead of writing from scratch.
- Reduce modification in provided IP files – the majority (if not all) of the changes being made should be made in the top-level repository instead of the NanoSoC and wrapper IP repositories. Once people become familiar with the Project Structure it allows them to focus their time on the core design tasks.
The NanoSoC Tech IP repository contains the core SoC structural IP but not the IP provided via the Arm Academic Access Program (or from other IP licensing routes). The Arm IP should be downloaded and stored in a isolated location. They should not be checked into a Git repository which is visible to the public. A structure for IP containment is provided later in this flow. The Nanosoc repository contains the overall layout of an AHB-lite based SoC with SoCLabs and Arm IP instantiations such as a Bus Matrix, Arm Cortex-M0 Microprocessor, DMA Controller and ACII Debug *Port*. It also contains simulation scripts and test programs to run on the System. A more detailed breakdown of the NanoSoC System is available here.
The wrapper repository contains SoCLabs IP which can be used to convert AHB-lite and APB transactions to interfaces on accelerator engines. These are pieces of IP and VIP which can be used to make sure you can pass data in and out of the accelerator over the system interconnects. A detailed understanding of the behaviour of the wrapper hardware is documented here.
The FPGA and ASIC libraries contain references to IP libraries provided by FPGA vendors and by Semiconductor foundries which are stored off Git and need to be downloaded from the IP vendor. These can be used in the top-level synthesis to synthesise for a specific target/process node.
SoCTools Repository is a toolbox of scripts and tools we hope will be useful in SoC development. One of these is SoCSim which allows simulation scripts to be searched from within a project. By creating simple shell scripts which call simulators, other scripts or makefiles, the command "socsim example_script.sh" can be used to run the simulation and dump simulation files at the project simulation directory. "socsim clean all" can be used to remove simulation artifacts for all simulations. There is also an html generation tool to produce html webpages based off of your RTL you have provided - this doesn't fully support system verilog at this time but give a good output of hierarchy of designs. This can help you understand and navigate your Project.
The Filelist directory point to the related filelists for Licensed and custom IP files. Each list points to the RTL source file required for compilation.
The Environment directory contains a script which sets up environment variables for each of the sub-reposiories in a project. This will need to be modified to add custom accelerator IP.
The flow directory is a location for custom project scripts to be stored.
The simulation directory has two purposes. The sim subdirectory contains the simulation files generated by simulators. The socsim subdirectory contains scripts which can be detected by the socsim command.
The wrapper directory contains the project wrappers for accelerator IP. This repository contains source design files, verification and testbench files and stimulus files. The design files should instantiate accelerator IP along with IP provided by SoCLabs in the accelerator wrapper technology repository.
The system directory contains custom system design file, stimulus files and CPU test codes to run on the NanoSoC System. The main file in src is called nanosoc_exp.v which is a region of the nanosoc address map which can be mapped however the designer wishes. Usually this involves instantiating an AHB default slave and the Wrapped Accelerator.
Branches are a very useful tool when working within a Git repository. It allows one or many people to work on different parts of a project with the same code base and then allows the changes to be merged back into the code base which everyone else can then pull.
Our SoCLabs example has multiple branches. A stable branch 'Main' allows researchers to get updates of the development branch with a level of design changes that are stable for 3rd party integration. Additional feature branches can be used for targeted development of specific aspects of design or flow. These get merged into a development branch for system verification before then being merged into Main.
This may be a good example for you to be able to use branches within your own code. There are lots of different ways of doing it but having at least one known good branch can be a very useful tool in case code ends up breaking and makes your project unstable.
3rd Party Licensed IP
One way to store this IP is to store it locally on your working machine or a shared server. For the NanoSoC system, where proprietary CPU, DMA and other IP is used, the NanoSoC repository points to a location in the development environment which contains the IP and doesn't actually contain the IP itself. This is the case for not only the Arm IP as part of the Arm Academic Access program, but also the physical IP libraries provided by Semiconductor foundries.
Leading on from the last section, using environment variables within your project instead of relative (and most certainly absolute) paths can be a more adoptable method of referencing files. It means that the environment variables can be set no matter where you have located your project on your local machine or which operating system you are running on. Having variables set up for the root of your design area can be very helpful, along with variables set up for your EDA tools, IP files and at the top of each repository cloned.
As well as developing a working knowledge of design source languages you will build up knowledge of the various scripting languages that tool providers use to configure and automate their design environment flow steps. Scripts, such as Makefiles, help automate much of the design environment. Understanding how these, along with organising the layout of files in your file system will make working on your project more efficient.
There are many ways which you can structure your project and the points given above are only some ways you can go about it. It is best to take some time to find out what works well with your project collaborators, your computing systems and your institution.
There are definitely things not covered in this write up so if there are considerations or tips you think would be helpful for others, please comment them below.