
How Silicon Innovation Could Massively Scale With More Abstraction
Decades of logic gates and wires
The year is 2021, and the bulk of silicon and FPGA designers are still describing designs at the register-transfer-level (RTL) abstraction. Despite two major evolutions in the Verilog design language, the design subset only gained constructs to better generate and organize wires. This is not to say that there aren’t examples of designs being done at higher-levels such as C++ but this is far from ubiquitous (for reasons I will discuss).
How should hardware description languages (HDLs) evolve to raise the aggregate abstraction of design-intent? And more important, why should they?
In this article I will share my thoughts on how I believe we can free designers and verification engineers to focus more on the key semantics of the desired design-intent with more suitable levels of abstractions. I will also discuss how abstraction and Object-Oriented Programming (OOP) concepts in design can lead to significant increases in productivity, quality, and innovation.
In this article, I am discussing the design subset of HDLs (the subset which can be synthesized to hardware). It is well-known that the verification and behavioral modeling subsets of languages such as SystemVerilog have long caught up with features of high-level and dynamic languages such as e and Java. In the verification realm, multi-abstraction and multi-paradigms are available, but
the irony is that verification engineers are still spending much of their time verifying and debugging code even below the design-intent.
Abstraction

Within the HDL domain, the main issue is the lack of abstraction beyond RTL. What does abstraction mean for HDLs in the context of up-leveling design-intent?
Abstraction is a process of presenting something as a maximally simplified view of concepts for the purpose of higher-order thinking.
Design, verification, and debugging are all processes involving expressions of thought. The less we must think about, the more efficient we will be, because we can focus our thinking on the salient design-intent concepts.
Abstraction is not encapsulation. Pause and think about that for a moment (google if necessary).
A Verilog module is not an abstraction. It is an encapsulation of RTL-level abstractions. The interface to a Verilog module is still an RTL abstraction. If you wrapped a bundle of wires, and then again wrapped multiple such bundles into yet another bundle you would still end up with wires at each end.
SystemVerilog for design brought many goodies such as enumerated types, C-style structures, interfaces, and various array-related improvements, but these are merely wire-bundling constructs that need to be unwrapped to use. The level of abstraction never changes except conceptually, in the sense that those concepts cannot be used programmatically.
A Verilog module no matter how hierarchical, does not abstract beyond RTL semantics.
A good way to distinguish abstraction from encapsulation in the context of hardware is to think about how one performs actions on the interface of a module. For the purposes of illustration, let us use the venerable FIFO element. An RTL FIFO likely has wires and groupings of wires that represent the read and write port interfaces. There may also be configuration or status wires that need to be routed to some configuration or status handling module. To use the FIFO, one drives or samples logic signals (RTL semantics).
Below is a Verilog-like pseudo-code snippet that shows how one might use a FIFO if the design subset of the language supported higher abstractions.
// Declare and initialize a Fifo objectFifo fifo=Fifo(depth=128,type=packet_t, errorReporter=errPipe);always @(consumer.popevent) consumer.data = fifo.pop();always @(producer.pushevent)fifo.push(producer.data);
The designer only thinks in concepts of consumer and producer objects, and the FIFO semantics (to which these objects comply). There is no need to think about driving or sampling signals. The Fifo object uses an error/exception signaling layer which is bound to a specific chip-level error-reporting object/module (errPipe). The ErrPipe interface may contain methods and events.
Unnecessary Ambiguity and Translation
As previously described, no matter the amount of hierarchical “bundling” of RTL constructs, the abstraction is always the same, save for some conceptual abstraction which exists in the head of the designer and hopefully in a micro-architectural document as text. Below is a diagram which shows these processes between a designer and verification engineer in an RTL abstraction flow.

Despite all the great power that verification engineers have at their disposal today with UVM and SystemVerilog, they cannot escape the highlighted processes shown in the diagram above.
The original higher-level design-intent (concepts) is essentially lost in translation when the designer writes the RTL. Typically, such concepts are also generated during the design process and directly translated to RTL. Well written micro-architectural documents, despite being very helpful do not provide any programmatical way to convey the concepts. Each time the RTL is inspected, modified or debugged, it must be re-comprehended into the higher-level intent.
The verification engineer starts with whatever paper specification is available and from there, iterates on connecting the paper-specification concepts to whatever implicit concepts are buried in the RTL.
This can be a tedious process full of vagaries with no common semantic framework to align on.
Also, consider the task of code-coverage. The verification engineer must steer the verification stimulus which may be based on higher-level concepts to try and hit coverage on code for which there does not exist any abstract equivalent. The verification engineer is thus expending effort on verifying things that are truly below the design-intent, which the designer themselves only used because there was no facility to directly codify the intended higher-level abstraction in the first place.
The goal of a higher-level design language is not necessarily to remove the middle layers, but to significantly reduce them. As such, it should be obvious, even intuitively so, how much effort this may save on any silicon or FPGA design project. It should also be intuitively obvious that such low-level code is harder to maintain and extend.
Inheritance and Polymorphism

Abstraction truly shows its power once there is a desire to modify or extend something. We will now switch to Python because I want to be able to show a working example of how modifying or extending a design with a more abstract design-intent might look.
First let us start with an abstraction of a FIFO written in Python. An abstraction can be found here:
https://github.com/sebastian-ahmed/fifo_tools/blob/main/fifo_pkg/Fifo.py
This FIFO is almost a pure abstraction because it does not even support any provision for storing data. The reason is that this is a model for the purposes of architectural simulation where the intent is to simulate the size of the FIFO and the data storage is irrelevant.
For the sake of illustration however, let us assume that this is some sort of FIFO design base class. It provides the basic interface and facilities such as level and error detection and reporting. As a designer, we wish to extend this base class to create a FIFO that is more useful. At the very least we wish to add data-storage capability.
An example extension to the Fifo class is BetterFifo, which can be found here:
https://github.com/sebastian-ahmed/fifo_tools/blob/main/extension.py
Some important things about this design extension:
- This was more than an exercise in abstraction. I also introduced Object-Oriented Programming (OOP) concepts here such as inheritance allowing us to extend an existing design without modifying it and polymorphism by overriding the push() and pop() interface methods and extending semantics with bulk_pop().
- We maintained the semantics of a Fifo, so code which previously used Fifo could use BetterFifo and at the very least get the improved bwratio property which handles the divide-by-zero exception.
- The storage element uses a natively supported Python list which is a sequence type. A higher-level HDL for design should allow direct usage of similar types such as queues. There is no reason why native types such as queues should not be available for the design subset.
- Code-reviews, coverage and testing of BetterFifo only needs to focus on the class extension code. Likely, the test-suite for the Fifo base-class can also be re-used and perhaps itself extended if it was organized in an OOP way
There is no need to re-verify the Fifo design, because we did not change a line of code
C++ and High-Level Synthesis
It is now time to talk about C++. It is well known that there is support and usage of C++ based design-entry (including the synthesizable subset of the SystemC standard). This class of design-intent and tooling is known as “High-Level Synthesis” (HLS for short). After more than 25 years since Verilog was created, why isn’t every silicon designer and FPGA engineer using C++ HLS exclusively?
- Much like C is still alive and strong today (especially in embedded systems and OS kernels), the need for RTL abstraction has not gone away and HLS has not obviated the complete need for it. There will always be a class of circuits that need to reflect low-level design semantics. Examples might be clock circuitry, reset controllers, ultra low-power circuits, power management controllers and efficient general-purpose processor design.
- C++ is not a Domain Specific Language (DSL). As such, even though it provides tremendous benefits in terms of re-using algorithmic models or plugging into a C++ based software virtual platform, the syntax becomes clumsy when trying to describe hardware semantics (such as concurrency, not be confused with pthreads). Many traditional RTL designers face a very steep learning curve to become comfortable with developing in C++.
- Sub-system and chip-level simulations are still grounded in the Verilog HDL simulator. This means that the C++ models cannot be easily modified or debugged in the context of such a simulation. C++ is also not a verification DSL. This means that one must still rely on a Verilog simulator and expertise to perform the serious verification (such as coverage driven random, temporal assertions and formal).
That being said, for teams who know their way around C++ and situations where there are opportunities to directly re-use existing C++ code, there will always be some very good reasons to leverage HLS.
A Practical Path Forward
Getting to a truly ubiquitous multi-abstraction, multi-paradigm high-level design HDL solution needs to follow the approach of the verification subset of SystemVerilog which brought concepts from past verification DSLs such as e and general-purpose OOP dynamic languages such as Java into the existing Verilog language. This provided verification engineers with all the powerful tools they needed to describe verification constructs with higher-level semantics but within a backwards compatible unified language and simulator.
The SystemVerilog for verification experience has proven that maintaining legacy (with all its low-level abstractions) is the method by which a smooth transition and up leveling can occur.
The same must happen with design. A new version of SystemVerilog must address the grossly lacking support for higher-level abstraction and OOP paradigms. This would be in addition to all the existing legacy abstractions down to switch-level constructs. We would see a steady progression of the higher-level abstractions in designs which do not require or benefit from low-level design-intent. All abstractions would co-exist within the same development environment, tools and simulator.
Such a language must continue to be an industry standard (IEEE ratified) and ideally come with reference simulators and synthesis tools. Proprietary extensions and libraries should never be mandatory. Commercial EDA vendors could differentiate with optional libraries and extensions as well as providing the best developer experience for debugging.
How would such a future look?

Access to a higher-level HDL by way of a SystemVerilog-for-design evolution, would bring about massive increases in efficiency and a paradigm shift in design re-use leading to better optimized and more innovative designs.
- Both verification and design would benefit from programmatically defined higher-level concepts which could be shared in a common library. For larger and more complex designs, this could represent multi-fold increases in productivity and efficiency. There would be a reduction in the space of verification across the board including code reviews, static code analysis, coverage, assertions, debugging and of course the removal of many translation layers as described earlier.
- Design re-use today is a very monolithic and binary process. It is really an all or nothing deal. If the IP needs to be extended or modified in any way, this changes the nature of the project completely. In the case of commercially licensed IP, you may not even have the rights to modify it (and there are good reasons, such as warranties)
The first point is perhaps the obvious one, the second needs a little more unpacking. As an IP provider (either internal to a chip company or as a commercial IP vendor), you do not want your users/customers to modify the IP because it would require a support model that now incorporates all the IP verification infrastructure.
Consider an IP written in this more evolved SystemVerilog-for-design which supports the standard OOP features such as inheritance and polymorphism. It would now be possible to provide a second use-case for the IP, one which provides a limited modification capability:
- Mandatory configuration options could be implemented via pure virtual functions. These could be behavioral configurations beyond mere parameter or tick-define settings.
- Modifiable implementations can be made available via virtual functions. This allows the IP provider to precisely control what can and can’t be modified.
- Extension would come naturally through inheritance, including use of the public interface to compose new extensions.
- A reduced “interface-only” test-suite would be provided which also has extensible and overridable classes and methods. The extensibility would match the design extensibility interface.
Extensions to an IP would thus never involve touching the base-IP by the user/customer, yet still provide them the freedom to customize, modify and extend the IP in a very controlled way which requires no modification of what is delivered by the provider.
This approach would provide opportunities to innovate even in the context of re-use.
This is a really important point, because in silicon, the binary nature of re-use means that when re-using IP, it is a decision to not innovate on any level within the scope of that IP. This is completely unnecessary and quite limiting for innovation and frankly in stark contrast to how OOP has enabled derivation-based innovation in the software world.
Commercial IP providers could always charge a slightly higher licensing or support-and-maintenance cost for the “extensible” interface even to the point of providing multiple tiers of extensibility via appropriately enabled virtual interfaces.
Summary
After over twenty years of evolution, the industry de-facto HDL, Verilog has only incrementally improved in its design subset facilities. In comparison, the verification and behavioral modeling aspects, adopted modern programming paradigms over a decade ago based on verification domain-specific languages (DSLs) that had been around for over a decade prior.
C++ based high-level synthesis will continue to gain traction in certain applications and when coupled with engineers having the requisite skillset. Ubiquity in use of high-level HDLs however cannot happen until the design subset of SystemVerilog evolves to bring OOP concepts and advanced programming paradigms which can primarily be based on the existing verification subset.
Once SystemVerilog-for-design adds this support, there will be a revolution in the scaling and innovation in silicon design because not only will designers operate at the appropriate level to match design-intent, but because their partner verification teams will no longer be carting around unnecessary abstraction translation layers which are major sources of technical friction.
The surprise benefit and a big opportunity for the silicon industry is how
design re-use may no longer need to be a binary decision of re-use vs innovation.
Both concepts of re-use and innovation will exist concurrently which will provide the conditions to not only expand the innovation surface of chip designs but result in better products for consumers and society.