| |
| \chapter{Evaluation of other OSS Verilog Synthesis Tools} |
| \label{chapter:sota} |
| |
| In this appendix\footnote{This appendix is an updated version of an |
| unpublished student research paper. \cite{VerilogFossEval}} |
| the existing FOSS Verilog synthesis tools\footnote{To the |
| author's best knowledge, all relevant tools that existed at the time of this |
| writing are included. But as there is no formal channel through which such |
| tools are published it is hard to give any guarantees in that matter.} are |
| evaluated. Extremely limited or application specific tools (e.g.~pure Verilog |
| Netlist parsers) as well as Verilog simulators are not included. These existing |
| solutions are tested using a set of representative Verilog code snippets. It is |
| shown that no existing FOSS tool implements even close to a sufficient subset |
| of Verilog to be usable as synthesis tool for a wide range existing Verilog code. |
| |
| The packages evaluated are: |
| |
| \begin{itemize} |
| \item Icarus Verilog \citeweblink{Icarus}\footnote{Icarus Verilog is mainly a simulation |
| tool but also supported synthesis up to version 0.8. Therefore version 0.8.7 is used |
| for this evaluation.)} |
| \item Verilog-to-Routing (VTR) / Odin-II \cite{vtr2012}\cite{Odin}\citeweblink{VTR} |
| \item HDL Analyzer and Netlist Architect (HANA) \citeweblink{HANA} |
| \item Verilog front-end to VIS (vl2mv) \cite{Cheng93vl2mv:a}\citeweblink{VIS} |
| \end{itemize} |
| |
| In each of the following sections Verilog modules that test a certain Verilog |
| language feature are presented and the support for these features is tested in all |
| the tools mentioned above. It is evaluated whether the tools under test |
| successfully generate netlists for the Verilog input and whether these netlists |
| match the simulation behavior of the designs using testbenches. |
| |
| All test cases are verified to be synthesizeable using Xilinx XST from the Xilinx |
| WebPACK \citeweblink{XilinxWebPACK} suite. |
| |
| Trivial features such as support for simple structural Verilog are not explicitly tested. |
| |
| Vl2mv and Odin-II generate output in the BLIF (Berkeley Logic Interchange |
| Format) and BLIF-MV (an extended version of BLIF) formats respectively. |
| ABC \citeweblink{ABC} is used to convert this output to Verilog for verification |
| using testbenches. |
| |
| Icarus Verilog generates EDIF (Electronic Design Interchange Format) output |
| utilizing LPM (Library of Parameterized Modules) cells. The EDIF files are |
| converted to Verilog using edif2ngd and netgen from Xilinx WebPACK. A |
| hand-written implementation of the LPM cells utilized by the generated netlists |
| is used for verification. |
| |
| Following these functional tests, a quick analysis of the extensibility of the tools |
| under test is provided in a separate section. |
| |
| The last section of this chapter finally concludes these series of evaluations |
| with a summary of the results. |
| |
| \begin{figure}[t!] |
| \begin{minipage}{7.7cm} |
| \lstinputlisting[numbers=left,frame=single,language=Verilog]{CHAPTER_StateOfTheArt/always01_pub.v} |
| \end{minipage} |
| \hfill |
| \begin{minipage}{7.7cm} |
| \lstinputlisting[frame=single,language=Verilog]{CHAPTER_StateOfTheArt/always02_pub.v} |
| \end{minipage} |
| \caption{1st and 2nd Verilog always examples} |
| \label{fig:StateOfTheArt_always12} |
| \end{figure} |
| |
| \begin{figure}[!] |
| \lstinputlisting[numbers=left,frame=single,language=Verilog]{CHAPTER_StateOfTheArt/always03.v} |
| \caption{3rd Verilog always example} |
| \label{fig:StateOfTheArt_always3} |
| \end{figure} |
| |
| \section{Always blocks and blocking vs.~nonblocking assignments} |
| \label{sec:blocking_nonblocking} |
| |
| The ``always''-block is one of the most fundamental non-trivial Verilog |
| language features. It can be used to model a combinatorial path (with optional |
| registers on the outputs) in a way that mimics a regular programming language. |
| |
| Within an always block, if- and case-statements can be used to model multiplexers. |
| Blocking assignments ($=$) and nonblocking assignments ($<=$) are used to populate the |
| leaf-nodes of these multiplexer trees. Unassigned leaf-nodes default to feedback |
| paths that cause the output register to hold the previous value. More advanced |
| synthesis tools often convert these feedback paths to register enable signals or |
| even generate circuits with clock gating. |
| |
| Registers assigned with nonblocking assignments ($<=$) behave differently from |
| variables in regular programming languages: In a simulation they are not |
| updated immediately after being assigned. Instead the right-hand sides are |
| evaluated and the results stored in temporary memory locations. After all |
| pending updates have been prepared in this way they are executed, thus yielding |
| semi-parallel execution of all nonblocking assignments. |
| |
| For synthesis this means that every occurrence of that register in an expression |
| addresses the output port of the corresponding register regardless of the question whether the register |
| has been assigned a new value in an earlier command in the same always block. |
| Therefore with nonblocking assignments the order of the assignments has no effect |
| on the resulting circuit as long as the left-hand sides of the assignments are |
| unique. |
| |
| The three example codes in Fig.~\ref{fig:StateOfTheArt_always12} and |
| Fig.~\ref{fig:StateOfTheArt_always3} use all these features and can thus be used |
| to test the synthesis tools capabilities to synthesize always blocks correctly. |
| |
| The first example is only using the most fundamental Verilog features. All |
| tools under test were able to successfully synthesize this design. |
| |
| \begin{figure}[b!] |
| \lstinputlisting[numbers=left,frame=single,language=Verilog]{CHAPTER_StateOfTheArt/arrays01.v} |
| \caption{Verilog array example} |
| \label{fig:StateOfTheArt_arrays} |
| \end{figure} |
| |
| The 2nd example is functionally identical to the 1st one but is using an |
| if-statement inside the always block. Odin-II fails to synthesize it and |
| instead produces the following error message: |
| |
| \begin{verbatim} |
| ERROR: (File: always02.v) (Line number: 13) |
| You've defined the driver "count~0" twice |
| \end{verbatim} |
| |
| Vl2mv does not produce an error message but outputs an invalid synthesis result |
| that is not using the reset input at all. |
| |
| Icarus Verilog also doesn't produce an error message but generates an invalid output |
| for this 2nd example. The code generated by Icarus Verilog only implements the reset |
| path for the count register, effectively setting the output to constant 0. |
| |
| So of all tools under test only HANA was able to create correct synthesis results |
| for the 2nd example. |
| |
| The 3rd example is using blocking and nonblocking assignments and many if statements. |
| Odin also fails to synthesize this example: |
| |
| \begin{verbatim} |
| ERROR: (File: always03.v) (Line number: 8) |
| ODIN doesn't handle blocking statements in Sequential blocks |
| \end{verbatim} |
| |
| HANA, Icarus Verilog and vl2mv create invalid synthesis results for the 3rd example. |
| |
| So unfortunately none of the tools under test provide a complete and correct |
| implementation of blocking and nonblocking assignments. |
| |
| \section{Arrays for memory modelling} |
| |
| Verilog arrays are part of the synthesizeable subset of Verilog and are |
| commonly used to model addressable memory. The Verilog code in |
| Fig.~\ref{fig:StateOfTheArt_arrays} demonstrates this by implementing a single |
| port memory. |
| |
| For this design HANA, vl2m and ODIN-II generate error messages indicating that |
| arrays are not supported. |
| |
| \begin{figure}[t!] |
| \lstinputlisting[numbers=left,frame=single,language=Verilog]{CHAPTER_StateOfTheArt/forgen01.v} |
| \caption{Verilog for loop example} |
| \label{fig:StateOfTheArt_for} |
| \end{figure} |
| |
| Icarus Verilog produces an invalid output that is using the address only for |
| reads. Instead of using the address input for writes, the generated design |
| simply loads the data to all memory locations whenever the write-enable input |
| is active, effectively turning the design into a single 4-bit D-Flip-Flop with |
| enable input. |
| |
| As all tools under test already fail this simple test, there is nothing to gain |
| by continuing tests on this aspect of Verilog synthesis such as synthesis of dual port |
| memories, correct handling of write collisions, and so forth. |
| |
| \begin{figure}[t!] |
| \lstinputlisting[numbers=left,frame=single,language=Verilog]{CHAPTER_StateOfTheArt/forgen02.v} |
| \caption{Verilog generate example} |
| \label{fig:StateOfTheArt_gen} |
| \end{figure} |
| |
| \section{For-loops and generate blocks} |
| |
| For-loops and generate blocks are more advanced Verilog features. These features |
| allow the circuit designer to add program code to her design that is evaluated |
| during synthesis to generate (parts of) the circuits description; something that |
| could only be done using a code generator otherwise. |
| |
| For-loops are only allowed in synthesizeable Verilog if they can be completely |
| unrolled. Then they can be a powerful tool to generate array logic or static |
| lookup tables. The code in Fig.~\ref{fig:StateOfTheArt_for} generates a circuit that |
| tests a 5 bit value for being a prime number using a static lookup table. |
| |
| Generate blocks can be used to model array logic in complex parametric designs. The |
| code in Fig.~\ref{fig:StateOfTheArt_gen} implements a ripple-carry adder with |
| parametric width from simple assign-statements and logic operations using a Verilog |
| generate block. |
| |
| All tools under test failed to synthesize both test cases. HANA creates invalid |
| output in both cases. Icarus Verilog creates invalid output for the first |
| test and fails with an error for the second case. The other two tools fail with |
| error messages for both tests. |
| |
| \section{Extensibility} |
| |
| This section briefly discusses the extensibility of the tools under test and |
| their internal data- and control-flow. As all tools under test already failed |
| to synthesize simple Verilog always-blocks correctly, not much resources have |
| been spent on evaluating the extensibility of these tools and therefore only a |
| very brief discussion of the topic is provided here. |
| |
| HANA synthesizes for a built-in library of standard cells using two passes over |
| an AST representation of the Verilog input. This approach executes fast but |
| limits the extensibility as everything happens in only two comparable complex |
| AST walks and there is no universal intermediate representation that is flexible |
| enough to be used in arbitrary optimizations. |
| |
| Odin-II and vl2m are both front ends to existing synthesis flows. As such they |
| only try to quickly convert the Verilog input into the internal representation |
| of their respective flows (BLIF). So extensibility is less of an issue here as |
| potential extensions would likely be implemented in other components of the |
| flow. |
| |
| Icarus Verilog is clearly designed to be a simulation tool rather than a |
| synthesis tool. The synthesis part of Icarus Verilog is an ad-hoc add-on to |
| Icarus Verilog that aims at converting an internal representation that is meant |
| for generation of a virtual machine based simulation code to netlists. |
| |
| \section{Summary and Outlook} |
| |
| Table~\ref{tab:StateOfTheArt_sum} summarizes the tests performed. Clearly none |
| of the tools under test make a serious attempt at providing a feature-complete |
| implementation of Verilog. It can be argued that Odin-II performed best in the |
| test as it never generated incorrect code but instead produced error messages |
| indicating that unsupported Verilog features where used in the Verilog input. |
| |
| In conclusion, to the best knowledge of the author, there is no FOSS Verilog |
| synthesis tool other than Yosys that is anywhere near feature completeness and |
| therefore there is no other candidate for a generic Verilog front end and/or |
| synthesis framework to be used as a basis for custom synthesis tools. |
| |
| Yosys could also replace vl2m and/or Odin-II in their respective flows or |
| function as a pre-compiler that can translate full-featured Verilog code to the |
| simple subset of Verilog that is understood by vl2m and Odin-II. |
| |
| Yosys is designed for extensibility. It can be used as-is to synthesize Verilog |
| code to netlists, but its main purpose is to be used as basis for custom tools. |
| Yosys is structured in a language dependent Verilog front end and language |
| independent synthesis code (which is in itself structured in independent |
| passes). This architecture will simplify implementing additional HDL front |
| ends and/or additional synthesis passes. |
| |
| Chapter~\ref{chapter:eval} contains a more detailed evaluation of Yosys using real-world |
| designs that are far out of reach for any of the other tools discussed in this appendix. |
| |
| \vskip2cm |
| \begin{table}[h] |
| % yosys hana vis icarus odin |
| % always01 ok ok ok ok ok |
| % always02 ok ok failed failed error |
| % always03 ok failed failed missing error |
| % arrays01 ok error error failed error |
| % forgen01 ok failed error failed error |
| % forgen02 ok failed error error error |
| \def\ok{\ding{52}} |
| \def\error{\ding{56}} |
| \def\failed{$\skull$} |
| \def\missing{$\skull$} |
| \rowcolors{2}{gray!25}{white} |
| \centerline{ |
| \begin{tabular}{|l|cccc|c|} |
| \hline |
| & \bf HANA & \bf VIS / vl2m & \bf Icarus Verilog & \bf Odin-II & \bf Yosys \\ |
| \hline |
| \tt always01 & \ok & \ok & \ok & \ok & \ok \\ |
| \tt always02 & \ok & \failed & \failed & \error & \ok \\ |
| \tt always03 & \failed & \failed & \missing & \error & \ok \\ |
| \tt arrays01 & \error & \error & \failed & \error & \ok \\ |
| \tt forgen01 & \failed & \error & \failed & \error & \ok \\ |
| \tt forgen02 & \failed & \error & \error & \error & \ok \\ |
| \hline |
| \end{tabular} |
| } |
| \centerline{ |
| \ding{52} \dots passed \hskip2em |
| \ding{56} \dots produced error \hskip2em |
| $\skull$ \dots incorrect output |
| } |
| \caption{Summary of all test results} |
| \label{tab:StateOfTheArt_sum} |
| \end{table} |
| |