High level synthesizable code with standard VHDL
In this page I write about VHDL coding style which supports incremental design, testing and development of a FPGA solution. This is achieved using standard language features of VHDL to greatly increase abstraction level of the VHDL source code and to promote reuse. In my experience systematic reuse and use of abstractions will increase the expressiveness of the VHDL source code and reduce the number of non reusable lines of code by more than 90% in a project. This can be achieved with the existing tools and compilers using language records, subroutines, packages and libraries, all of which are features of VHDL that are in the VHDL 93 standard. The target for the code is FPGA and all of the code presented in this page is synthesizable and all solutions are tested on at least one hardware platform.
The high level VHDL repositories that have been created while writing this blog have been moved under an open source project called “High Level Synthesizable VHDL” or hVHDL which is found on github. The open source project aims to help developers to use the modules and to make that even easier, there is an example project that has build scripts for most common FPGAs. At the time of writing this page, there are build scripts for Lattice ECP5, Efinix Trion, Intel Cyclone 10lp and Xilinx Spartan 7.
Learning in code
The ideal situation for creating a solution to a problem would be one where any new solution could be pieced together from existing solutions. These existing solutions would be as close to the problem domain as possible and directly usable without modification. Any solution we create could then be part of further solutions and this process could be extended indefinitely. Through this process ever more complex problems can be solved with less and less effort.
What we are describing here is the the accumulation of knowledge and the act of learning through discovery. When applied to code, learning means creating pieces of code and accumulating knowledge means reusing old code as part of new code.
I personally like object oriented design principles for defining these reusable pieces of code. An object in this context is a piece of code that has a collection of related data or registers, some functionality and a collection of functions to access this functionality. Making code into objects makes their purpose and scope easier to understand. A multiplier object multiplies, divider object divides and sincos object performs sine and cosine calculations. All of these are separate objects that have an understandable purpose and scope.
Objects as abstract data types in VHDL
In object oriented languages, an object is commonly implemented in a data type that has both data and functions under one named construct called class. Object is then the instantiation of this class. What this class actually is, is just a form of abstract data type of composite elements and functions that act on this composite data type. In VHDL this abstract data type of composite elements is a record.
Since VHDL93 standard VHDL has supported high level language features like polymorphism via overloading, abstract data types in the form of records and abstract interfaces with procedures using signals of record types on the ports of entities. With the blog posts on this page I hope to show how these concepts can be used with VHDL to create high quality source code that is easy to understand, test, reuse and develop.
Site project under development
The main goal is to have reusable and adaptable code base in the Github available for anyone to use. The code is in the modules own repositories that are included in a project as a submodule. The submodules themselves are separately useable and do not require the entire project to work. All repositories have their own tests that are run using VUnit.
I am developing a bidirectional power supply with all of the control logic, signal processing and communications implemented in FPGA with VHDL. The project acts as a framing device for the blog posts. I have designed the different solutions presented in the blog posts to be useable by themselves with as low amount of coupling as possible. Low coupling and good separation from the project means their use is not bound to the project in which they are developed.
Where to start?
I am writing the blog posts approximately in the order which the system is designed, which also somewhat follows the system architecture. List of all of the blog posts is found under VHDL category. I also have made some videos to show how these ideas are put to work in practice. The most up to date and complete source for the high level code is are the sources that are found on the hVHDL github page. The project also has an example that uses many of the sources and has build scripts for most common FPGA vendors tools. All of the the simulations and tests are run using VUnit thus I recommend installing it to get a feel on how the code functions.