| There has been much discussion and a great deal of ink devoted to the topic of reuse. This topic is usually covered from the perspective of designing new code for reuse in future designs. Most pundits agree that this is a good idea and vital to fulfilling the systems-on-chip promise. |
However, how many engineers, teams, or corporations actually design for reuse? Not too many. The common alibi is that schedule pressures do not allow for the extra time and effort it takes to create HDL code that can be truly reusable with no alterations. In addition, a level of corporate infrastructure needs to be built so that everyone can access these designs.
So what actually happens? If asked, most will say that new designs use existing blocks of HDL that are altered. Is this true reuse? Purists would say "no" that this is mere recycling. Yet, since designers are not starting from scratch, this "recycling" undoubtedly must offer some value.
Enter practical reuse
In the Portland, Oregon metro area, close to 70% of the population now recycles their waste, implying that about 60% of material collected by garbage companies does not go into the landfill. Similar relatively high numbers are reflected in Silicon Valley and other parts of California too.
This was not always the case. In the recent past, there were so many rules about separating, bundling, and sorting that people did not want to spend the time participating. Worse, if these rules were violated, the garbage truck left your recyclables at the curb. If that happened, people gave up and just threw it all away.
Then, a great thing happened. Recycling became practical as the concept of co-mingling was instituted. A single receptacle was provided for every possible type of recyclable material, and the garbage company handled the sorting. Since then, the recycling percentage has consistently risen year after year.
With due apologies to those designers who may have taken offense, this example is not intended to insinuate that any of the designs out there are junk! Instead, the intention is to drive home a serious fact. It is time to look at reuse from a completely different perspective. Is there a methodology to help you reuse existing HDL code that was not initially designed for reuse?
This is practical reuse a working methodology for getting your next design quickly completed, by reusing code that already exists at your corporation. And, you will likely find that looking at the problem from a completely different angle will actually lead to more and more reuse in your next projects.
Practical reuse is a discovery process performed with or without tools. As shown in figure 1, this process includes:
- Determine design integrity: Is the code complete and do you understand (at a high-level) what the code does?
- Determine code quality: Can the code be easily reused and does it meet any standards you might have?
- Establish design validity: Does the design simulate and function as expected?
- Share knowledge: Does everyone in your company have access to the design?
Figure 1 We need a methodology to help us reuse existing HDL code that was not initially designed for reuse.
Determining design integrity
Design integrity fundamentally means that all the code is complete and ready for simulation. Typically, the first step is to find the top level of the design in order to ascertain which files comprise the RTL description from the root of the design on down. Additionally, you can eliminate any extraneous HDL files from the project. If the design is under version control, you will need to check out the latest version of the RTL and review history notes before starting the discovery process.
You can start with a manual technique, looking for a top-level "readme" or document file that might describe the design file hierarchy. Or, look for a compilation script for clues to design content. Finally, look for a file with an obvious name like "top" or a file that contains many component instances and no logic. As you work with the files, take note of modules containing structure but no logic, as you will have to find or create this logic yourself.
Taking the analysis up a level, if you possess a tool that parses and determines hierarchy as part of the process of specifying code or performing an analysis, that tool can typically figure out the topography of the design and whether anything is missing. Also, parsers provide you with syntax and semantic checks that could reveal problems with the code. Examples of these types of tools are code visualizers, synthesizers, or simulators. Visualization tools also help you understand the design composition and what the design does.
At this point, you are ready to consider the "Practical Factor" for the first time in the process. You can incrementally refine and use this value (equation 1) as an initial checkpoint during the reuse process:
The ultimate goal of course is to reduce the denominator to zero, even though that can never actually happen. As you will see later, it is best to measure time in minutes or to convert hours to minutes. Days, weeks, or months can be interpreted differently between people (for example, does a day have eight hours or 24?).
The TimeScratch variable is the hardest to estimate. You can employ various techniques to make a best guess:
1. Get the total line count and apply a time factor in minutes for each comment (typically a low number) and for each non-commented line of code (typically a higher number).
2. Alternatively, use historical time data from a similar project that you may have recently worked on.
3. If you use generators, the time it takes to create blocks of the design decreases dramatically. For example:
Regardless of the technique, you also need to factor in the time it takes to verify the code. That topic is covered later on in this article.
- High-level graphical tools (like block diagram and FSM editors) generate code for you.
- Platform-based tools allow you to drop in microprocessor cores, their compatible bus structures, and peripheral blocks thus generating even more code for you.
- Electronic system level (ESL) tools allow you to design at a very high level and generate RTL as well.
At this point, the TimeReuse variable represents TimeIntegrity, which comprises the following:
Thus you now arrive at the next checkpoint (equation 2):
- The time it takes to correct any syntax errors (typically quick to fix) and semantic errors (typically longer to fix) that you found. Multiply each syntax error times a minute factor and each semantic error by a higher minute factor.
- Add in the time it will take to create any missing blocks that you found, using one of the previous TimeScratch techniques.
- Add together the time it took you to understand the design and to figure out the top level of the design as well as the design topology.
If the Practical Factor approaches 1, you would obviously stop now, as reusing this design would take as much time as it would take to create it from scratch.
Determining code quality
Assuming that the code passed these checkpoints, quality is the next consideration. A good place to start is with the Quality IP (QIP) matrix and user guide provided by the folks at the Virtual Socket Interface Alliance (VSIA). The QIP is a spreadsheet that lets you leverage collective knowledge about how reusable your code is.
You manually enter answers to questions and a weighted score is produced. If the score is low, it could take a lot of work to reuse this code. At the time of this writing, you had to be a member of VSIA to access the QIP.
To automate code quality assessment, you can use a code checker (sometimes called a linter). Often, a company has a set of reuse rules commonly based on the Reuse Methodology Manual. Separately, companies capture rules that represent collective knowledge about code that can cause design errors.
Activate these rules separately and run the tool to assess reuse and quality. Some checkers also support the RTL QIP checks or allow you to weight and score your own rules. These checkers can also detect empty blocks for you.
At this point, TimeReuse represents TimeIntegrity (from our previous checkpoint) plus TimeQuality:
This brings you to the next checkpoint (equation 3):
- Multiply each reuse violation by a time factor in minutes.
- Multiply each problem violation by a larger time factor in minutes.
- If you found any additional empty modules using the checker, factor in the time to create them back into the TimeIntegrity value.
Is the number getting closer to 1? If not, proceed to the next step.
Establishing design validity
After you determine the code integrity and quality, it is time to decide if the design works as expected. Design verification can be a complex process that uses several techniques and tools.
First, account for validation time in the denominator of the Practical Reuse factor. This value should be significantly less than creating a test environment and running validations from scratch. Taking a simplistic approach, estimate a time value for each of the following:
How you account for the significant time spent addressing the preceding issues is based on your experience. Establish a TimeReuse Validate value by multiplying an estimated time factor to each of the preceding issues. Then add the total value to the denominator of the Practical Factor equation.
- Does a testbench exist? If not, you will have to create or generate one, and that will take time.
- Does the testbench contain many tests? If not, you will have to add testing routines to it to ensure acceptable coverage.
- If you have the ability to run code coverage, does the testbench exercise the entire design? If not, you will have to upgrade the testbench.
- Do the testbench and the RTL contain assertions? If not, debugging time will increase.
- Do you get simulation errors? Each one will take time to debug.
- How much time do you actually spend simulating? You need to account for this time as well.
Next, don't forget to account for the time it would take you to create tests and run the validation from scratch. For a rough estimate, you can use the "70% of the design cycle is spent in verification" claim of lore. Assume that this 70% means creating and running tests as well as correcting problems. That means 30% of your time is spent doing something else.
If you assume that 20% of that "something else" is design creation, then multiply your value for TimeScratch by 3.5 to get a value for TimeScratch Validate. Add this number to your original TimeScratch value to get the "final" TimeScratch estimate (used in equation 4).
Does the Practical Factor indicate that the code is still viable for reuse?
Sharing your knowledge
Even if the design failed to pass the checkpoints, the upside is that it is still good knowledge to share within a team or corporation. Otherwise, someone else might discover the code and spend time trying to reuse it. Also, there could be blocks of code or data that could help a colleague.
A good approach to sharing is to create a high-level website that contains a list of designs available for reuse. At the top level, enter a brief design description and add your comments on the Practical Factor checkpoints so that everyone knows its status. Then create (or use a tool to generate) a web page for each design and collate the following information from your discovery process:
Encourage others to view your website and to contribute to its content. To start off let your colleagues and immediate co-designers (and ultimately remote teams and the corporation) know about the effort so that the top-level web page becomes a useful central reuse repository.
- The RTL source, including the testbench (leaving behind any source that is not part of the design).
- Any notes or drawings that you generated or created by hand during your discovery process.
- Documents and scripts that you found useful.
- Supporting design files (like C files, memory content files, processor software, etc.).
- Your integrity, quality, and validation notes or reports.
Until everyone designs for pure reuse, the need for practical reuse will exist. Establishing your own practical reuse methodology now will encourage a new method for thinking about the problem and will allow you to identify tools you need to automate the process.
As you work with automation techniques and tools, you will gravitate towards a design flow that naturally enables developing code for reuse. Eventually, you will realize that you are actually designing new code for reuse as an effect of employing practical reuse techniques.
Tom Dewey is a technical marketing engineer in the Design Creation and Synthesis Division of Mentor Graphics Corp.