Making HDL Code Components More Portable In Digital
Introduction: The Challenge of Verilog HDL Portability
When delving into the fascinating world of digital circuit simulation using tools like Digital, one often encounters challenges that hinder the seamless portability of Hardware Description Language (HDL) code. This article will address a specific issue: the lack of portability when including external Verilog HDL files in Digital. I will break down the problem, the underlying cause, and offer a potential solution to enhance the usability of Digital for Verilog projects. Digital is a fantastic tool for learning and experimenting with digital circuits, but like any software, it has areas that can be improved. One of these areas is the way it handles external Verilog files. The current implementation can make it tricky to move your projects between different computers or share them with others.
The Problem: Hardcoded Paths and Include Files
The core of the issue lies in how Digital handles include files and the paths to your Verilog source files. When you include files or refer to other files within your Verilog code, the simulator needs to know where to find them. Currently, Digital often requires you to hardcode these paths, making your code less flexible and portable. This means if you move your project to a different location, or if someone else tries to open it, the paths might break, and the simulation won't work as expected. The error message typically encountered is along the lines of "Include file ... not found," indicating that the simulator cannot locate the necessary files. This isn't just a minor inconvenience; it's a significant roadblock that can frustrate users and impede the learning process. The current system requires manual configuration of include paths every time a project is moved or shared, which is far from ideal. This limitation is particularly noticeable when working with larger projects that rely heavily on modular design and external files.
The Setup: A Simple Example to Illustrate the Problem
To understand the issue, let's look at a common scenario. Imagine a project with the following file structure:
bug_review/
├── main.dig
├── test.vh
└── verilog_src
└── test.v
Here, main.dig is your Digital project file, test.vh contains parameter definitions, and test.v is a Verilog module. The contents of the files are as follows:
test.v:
module test
(
input [1:0] a,
output [1:0] b
);
`include "../test.vh"
assign b = header_param & a;
endmodule
test.vh:
parameter header_param = 2'b01;
After setting up the files, open main.dig in Digital and add an external Verilog component using test.v. When you try to compile the Verilog code, you'll likely encounter an error because the compiler cannot find test.vh. The error will be something like "Include file ../test.vh not found". This is because Digital is compiling the Verilog files in a temporary directory, and the relative paths are not correctly resolved. The core problem is that Digital doesn't inherently understand the relative paths between your Verilog files and the main project file.
The Root Cause: Working Directory and Include Paths
The issue stems from how Digital handles the compilation process. Specifically, the working directory used by the IVerilog compiler is not the same as the directory containing your source files. Let's delve deeper into the code to understand why this happens.
Digital's Compilation Process
Digital uses the ApplicationIVerilog.start() and ApplicationIVerilog.checkCode() methods (found in de.neemann.digital.core.extern.ApplicationIVerilog.java) to compile Verilog code. These methods are responsible for invoking the IVerilog compiler. When you add an external Verilog component, Digital prepares the code and creates a temporary file in a temporary directory to be compiled by IVerilog. This is where the problem lies: IVerilog compiles the code in the temporary directory, not the directory where the source file resides.
The Role of ProcessStarter and Options
The ProcessStarter.start() method, combined with the Options object, is responsible for running the IVerilog compiler with the appropriate flags. Currently, it only provides the file name and the path of the temporary file to the compiler. It does not provide information about the include paths where the compiler should look for include files or the directories where the source files are located. This is where the include paths need to be specified.
Relative Paths and the Include Directive
In the example above, the test.v file uses the preprocessor directive `include "../test.vh". This directive tells the compiler to include the contents of test.vh into test.v. However, since the compiler runs in a temporary directory, it doesn't know where to find test.vh unless we explicitly tell it. This is why the error occurs.
A Potential Solution: Injecting Include Paths
The key to solving this portability problem is to tell the IVerilog compiler where to find include files and other source files. This can be achieved by injecting the correct include paths before compilation.
Proposed Code Changes
Here's how the ApplicationIVerilog.java code could be modified to improve portability:
ProcessStarter.start(file.getParentFile(), new Options()
.add(iverilog)
.add("-tvvp")
.add("-o")
.add(testOutputName)
// If the user provides header valid, use them first.
.add(attr, Keys.IVERILOG_OPTIONS)
// Before the IVerilog options, we should inject the source path with "-I/path -y/path":
// The /path is the relative path from the working dig file.
// Such as from `main.dig` to `test.v` : `verilog_src/test.v`
.add("-I" + Paths.get(root).resolve(/*/path*/))
.add("-y" + Paths.get(root).resolve(/*/path*/))
.add(file.getName())
.getArray()
)
In this modification, we add the -I and -y options to the IVerilog command. The -I option specifies an include directory, while the -y option specifies a library directory. By adding these options with the correct relative paths, the compiler can find the necessary files. The /path would be a relative path from the .dig file to the directory containing the Verilog source files.
Understanding the -I and -y Options
-I: This option tells IVerilog where to search for include files. In the example, it would point to the directory containingtest.vh. It is necessary to specify the include path to ensure that the preprocessor can find the included files.-y: This option tells IVerilog where to search for modules. It is useful when your project is modular, and you have modules spread across various directories. It is important to set the library path so that the compiler can locate the modules defined in external files.
External Components and Compilation Paths
Even when the component is marked as "External but not File", the options should still be enabled. This is essential because the component may serve as a "compiling work path". This flexibility is required because of the way Digital handles external components. The way the paths are resolved should be consistent across all types of components.
Benefits of Improved Portability
Implementing this solution would provide several benefits:
Enhanced Project Sharing
Your Verilog projects become much easier to share with others. They can open the project in Digital without having to manually configure include paths or source file locations. This greatly improves collaboration and reduces friction when sharing your work.
Simplified Project Organization
You can organize your Verilog files in a more structured and modular way. You are free to use relative paths and include files, knowing that Digital will correctly locate them. This flexibility improves the overall design and maintainability of the projects.
Improved Learning Experience
For students and hobbyists learning Verilog, the portability improvements enhance the learning experience. Projects become more self-contained and easier to set up, allowing users to focus on the core concepts of digital circuit design rather than struggling with configuration issues.
Conclusion: Making Digital a More User-Friendly Tool
The lack of portability in handling external Verilog files is a noticeable issue in Digital. The proposed solution of injecting the correct include paths offers a practical way to improve this. By implementing this change, the Digital simulator can become more user-friendly, making it easier to share, organize, and work with Verilog projects. The key to fixing this lies in providing the compiler with the necessary information about where to find the source and include files, ensuring that projects can be easily moved and shared. This is a relatively small change that could have a big impact on the usability and appeal of Digital for Verilog users.
For more information on Verilog and digital circuit design, consider exploring these resources:
- IEEE Standard for Verilog Hardware Description Language: https://ieeexplore.ieee.org/
- Verilog Tutorials: Search for reputable online tutorials and courses on platforms like YouTube, Coursera, or edX.
This will help you broaden your knowledge and improve your expertise.