File Structure - StanfordVLSI/dragonphy2 GitHub Wiki

DragonPHY file structure

We have adopted some standards for where files are placed to make it easier to manage the project. At the top level of the DragonPHY repo, we have the following directories:

  • build: This folder is not committed to the git repo, but output products from generator scripts go here.
  • config: Put YAML files here representing the system configuration (number of ADCs, format of certain fixed-point numbers, etc.)
  • dragonphy: Put Python code here. Since this project is structured as a Python package, other scripts can access code in the dragonphy folder with import dragonphy.
  • inc: Place Verilog header files here. (In this document, "Verilog" really means "Verilog or SystemVerilog.")
  • tests: Tests that should be automatically run on GitHub commits should be placed here. Since pytest is used to run the tests, each script name should start with test_, and the scripts should define one or more functions whose names start with test_ (each such function will be run as a separate test by pytest). It's fine to have folder hierarchy inside the tests folder.
  • vlog: Put Verilog code here. Subdirectory names like "chip_src" and "fpga_models" are labels for the purpose of the code in those folders. We take advantage of that labeling in the get_deps function that automatically resolves Verilog code dependencies based on label preferences (more on that later).

Verilog source rules

  1. Subdirectories in the vlog folder have labels like chip_src and fpga_models, which are assigned to the Verilog code inside those folders.
  2. Please place Verilog code in the label directories (i.e., not in the top level of vlog). It's perfectly fine to use folder hierarchy inside the label directories.
  3. Verilog code must use an extension .v or .sv.
  4. Only one module definition is allowed per Verilog file, and the name of the file must match the name of the module it defines. So a file that defines the module top, that module definition must be in a file called top.v or top.sv.

get_deps

The point of the Verilog source rules is to make it easier to assemble a list of source files for different purposes, like CPU simulation, FPGA emulation, and synthesis. These source file lists are generated using the get_deps function that can be imported from the dragonphy Python package.

For example, consider this file structure:

vlog
├── chip_src
|   └── top.sv
├── cpu_models
|   └── mod_a.sv
└── fpga_models
    └── mod_a.sv

where vlog/chip_src/top.sv contains:

module top;
    mod_a mod_a_inst ();
endmodule

We can get the file list for FPGA emulation by running the following in Python:

>>> from dragonphy import get_deps
>>> get_deps('top', view_order=['chip_src', 'fpga_models'])
['vlog/fpga_models/mod_a.sv', 'vlog/chip_src/top.sv']

Even though mod_a has an implementation in cpu_models, that implementation is not used because cpu_models is not in the view list. Also note that the source file list structured such that each file is preceded by its dependencies, which means that you can generally pass the dependency list directly to CAD tools.

Here's another example for CPU simulation:

>>> from dragonphy import get_deps
>>> get_deps('top', view_order=['chip_src', 'cpu_models'])
['vlog/cpu_models/mod_a.sv', 'vlog/chip_src/top.sv']

This is similar to the previous result, but the cpu_models implementation of mod_a is preferred.

It is also possible to provide a specific label that should be used for a certain module via the override argument. For example:

>>> from dragonphy import get_deps
>>> get_deps('top', view_order=['chip_src', 'cpu_models'],
...          override={'mod_a': 'fpga_models'})
['vlog/fpga_models/mod_a.sv', 'vlog/chip_src/top.sv']

The view_order is ignored for modules that appear in the override dictionary. (This particular example is a bit contrived, but it is useful to have override as an escape hatch.)

There are also times when it is useful to be able to tell get_deps not to try to descend into a particular module, such as when the module implementation comes from a file outside of the vlog directory. This is possible with the skip argument. For example:

>>> from dragonphy import get_deps
>>> get_deps('top', view_order=['chip_src', 'cpu_models'], skip={'mod_a'})
['vlog/chip_src/top.sv']

As you can see get_deps does not try to find the implementation of mod_a, and it does not try to descend into that module.

Since get_deps parses Verilog files to determine what modules are being defined and instantiated, it is sometimes necessary to provide a search path for `include files or declare `define macros in order for the Verilog file to be syntactically correct. When that is the case, the includes and defines arguments can be provided to get_deps, like this:

>>> from dragonphy import get_deps
>>> get_deps('top', view_order=['chip_src', 'cpu_models'],
...          includes=['dir1', 'dir2'], defines={'def1': 'val1', 'def2': None})
['vlog/cpu_models/mod_a.sv', 'vlog/chip_src/top.sv']

Note that includes should be a list of directories to use in the `include search path, while defines is a dictionary of `define macros. It's OK to use a value of None in the defines dictionary when a macro should be defined but not have a specific value.

Finally, it's worth noting that get_deps actually searches both the vlog and build folders, using exactly the same rules. This means that you can generate models that go into the build folder, and still have them discovered automatically when using get_deps. As an example, consider this file structure:

build
├── fpga_models
|   └── mod_a.sv
vlog
└── chip_src
    └── top.sv

Then we can use get_deps just as before to generate the file list for emulation.

>>> from dragonphy import get_deps
>>> get_deps('top', view_order=['chip_src', 'fpga_models'])
['build/fpga_models/mod_a.sv', 'vlog/chip_src/top.sv']

Even though the arguments to get_deps have not changed, it now discovers that the implementation of mod_a is in the build/fpga_models folder. If mod_a were defined in both build/fpga_models and vlog/fpga_models, get_deps would error out with an Exception.