1 2\section{Yosys by example -- Synthesis} 3 4\begin{frame} 5\sectionpage 6\end{frame} 7 8%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9 10\subsection{Typical Phases of a Synthesis Flow} 11 12\begin{frame}{\subsecname} 13\begin{itemize} 14\item Reading and elaborating the design 15\item Higher-level synthesis and optimization 16\begin{itemize} 17\item Converting {\tt always}-blocks to logic and registers 18\item Perform coarse-grain optimizations (resource sharing, const folding, ...) 19\item Handling of memories and other coarse-grain blocks 20\item Extracting and optimizing finite state machines 21\end{itemize} 22\item Convert remaining logic to bit-level logic functions 23\item Perform optimizations on bit-level logic functions 24\item Map bit-level logic gates and registers to cell library 25\item Write results to output file 26\end{itemize} 27\end{frame} 28 29%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 30 31\subsection{Reading the design} 32 33\begin{frame}[fragile]{\subsecname} 34\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] 35read_verilog file1.v 36read_verilog -I include_dir -D enable_foo -D WIDTH=12 file2.v 37read_verilog -lib cell_library.v 38 39verilog_defaults -add -I include_dir 40read_verilog file3.v 41read_verilog file4.v 42verilog_defaults -clear 43 44verilog_defaults -push 45verilog_defaults -add -I include_dir 46read_verilog file5.v 47read_verilog file6.v 48verilog_defaults -pop 49\end{lstlisting} 50\end{frame} 51 52%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 53 54\subsection{Design elaboration} 55 56\begin{frame}[fragile]{\subsecname} 57During design elaboration Yosys figures out how the modules are hierarchically 58connected. It also re-runs the AST parts of the Verilog frontend to create 59all needed variations of parametric modules. 60 61\bigskip 62\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] 63# simplest form. at least this version should be used after reading all input files 64# 65hierarchy 66 67# recommended form. fails if parts of the design hierarchy are missing, removes 68# everything that is unreachable from the top module, and marks the top module. 69# 70hierarchy -check -top top_module 71\end{lstlisting} 72\end{frame} 73 74%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 75 76\subsection{The {\tt proc} command} 77 78\begin{frame}[fragile]{\subsecname} 79The Verilog frontend converts {\tt always}-blocks to RTL netlists for the 80expressions and ``processes'' for the control- and memory elements. 81 82\medskip 83The {\tt proc} command transforms this ``processes'' to netlists of RTL 84multiplexer and register cells. 85 86\medskip 87The {\tt proc} command is actually a macro-command that calls the following 88other commands: 89 90\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] 91proc_clean # remove empty branches and processes 92proc_rmdead # remove unreachable branches 93proc_init # special handling of "initial" blocks 94proc_arst # identify modeling of async resets 95proc_mux # convert decision trees to multiplexer networks 96proc_dff # extract registers from processes 97proc_clean # if all went fine, this should remove all the processes 98\end{lstlisting} 99 100\medskip 101Many commands can not operate on modules with ``processes'' in them. Usually 102a call to {\tt proc} is the first command in the actual synthesis procedure 103after design elaboration. 104\end{frame} 105 106\begin{frame}[fragile]{\subsecname{} -- Example 1/3} 107\begin{columns} 108\column[t]{5cm} 109\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/proc_01.v} 110\column[t]{5cm} 111\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/proc_01.ys} 112\end{columns} 113\hfil\includegraphics[width=8cm,trim=0 0cm 0 0cm]{PRESENTATION_ExSyn/proc_01.pdf} 114\end{frame} 115 116\begin{frame}[t, fragile]{\subsecname{} -- Example 2/3} 117\vbox to 0cm{\includegraphics[width=\linewidth,trim=0cm 0cm 0cm -2.5cm]{PRESENTATION_ExSyn/proc_02.pdf}\vss} 118\vskip-1cm 119\begin{columns} 120\column[t]{5cm} 121\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/proc_02.v} 122\column[t]{5cm} 123\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/proc_02.ys} 124\end{columns} 125\end{frame} 126 127\begin{frame}[t, fragile]{\subsecname{} -- Example 3/3} 128\vbox to 0cm{\includegraphics[width=\linewidth,trim=0cm 0cm 0cm -1.5cm]{PRESENTATION_ExSyn/proc_03.pdf}\vss} 129\vskip-1cm 130\begin{columns} 131\column[t]{5cm} 132\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/proc_03.ys} 133\column[t]{5cm} 134\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/proc_03.v} 135\end{columns} 136\end{frame} 137 138%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 139 140\subsection{The {\tt opt} command} 141 142\begin{frame}[fragile]{\subsecname} 143The {\tt opt} command implements a series of simple optimizations. It also 144is a macro command that calls other commands: 145 146\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] 147opt_expr # const folding and simple expression rewriting 148opt_merge -nomux # merging identical cells 149 150do 151 opt_muxtree # remove never-active branches from multiplexer tree 152 opt_reduce # consolidate trees of boolean ops to reduce functions 153 opt_merge # merging identical cells 154 opt_rmdff # remove/simplify registers with constant inputs 155 opt_clean # remove unused objects (cells, wires) from design 156 opt_expr # const folding and simple expression rewriting 157while [changed design] 158\end{lstlisting} 159 160The command {\tt clean} can be used as alias for {\tt opt\_clean}. And {\tt ;;} 161can be used as shortcut for {\tt clean}. For example: 162 163\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] 164proc; opt; memory; opt_expr;; fsm;; 165\end{lstlisting} 166\end{frame} 167 168\begin{frame}[t, fragile]{\subsecname{} -- Example 1/4} 169\vbox to 0cm{\includegraphics[width=\linewidth,trim=0cm 0cm 0cm -0.5cm]{PRESENTATION_ExSyn/opt_01.pdf}\vss} 170\vskip-1cm 171\begin{columns} 172\column[t]{5cm} 173\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/opt_01.ys} 174\column[t]{5cm} 175\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/opt_01.v} 176\end{columns} 177\end{frame} 178 179\begin{frame}[t, fragile]{\subsecname{} -- Example 2/4} 180\vbox to 0cm{\includegraphics[width=\linewidth,trim=0cm 0cm 0cm 0cm]{PRESENTATION_ExSyn/opt_02.pdf}\vss} 181\vskip-1cm 182\begin{columns} 183\column[t]{5cm} 184\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/opt_02.ys} 185\column[t]{5cm} 186\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/opt_02.v} 187\end{columns} 188\end{frame} 189 190\begin{frame}[t, fragile]{\subsecname{} -- Example 3/4} 191\vbox to 0cm{\includegraphics[width=\linewidth,trim=0cm 0cm 0cm -2cm]{PRESENTATION_ExSyn/opt_03.pdf}\vss} 192\vskip-1cm 193\begin{columns} 194\column[t]{5cm} 195\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/opt_03.ys} 196\column[t]{5cm} 197\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/opt_03.v} 198\end{columns} 199\end{frame} 200 201\begin{frame}[t, fragile]{\subsecname{} -- Example 4/4} 202\vbox to 0cm{\hskip6cm\includegraphics[width=6cm,trim=0cm 0cm 0cm -3cm]{PRESENTATION_ExSyn/opt_04.pdf}\vss} 203\vskip-1cm 204\begin{columns} 205\column[t]{5cm} 206\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/opt_04.v} 207\column[t]{5cm} 208\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/opt_04.ys} 209\end{columns} 210\end{frame} 211 212%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 213 214\subsection{When to use {\tt opt} or {\tt clean}} 215 216\begin{frame}{\subsecname} 217Usually it does not hurt to call {\tt opt} after each regular command in the 218synthesis script. But it increases the synthesis time, so it is favourable 219to only call {\tt opt} when an improvement can be achieved. 220 221\bigskip 222The designs in {\tt yosys-bigsim} are a good playground for experimenting with 223the effects of calling {\tt opt} in various places of the flow. 224 225\bigskip 226It generally is a good idea to call {\tt opt} before inherently expensive 227commands such as {\tt sat} or {\tt freduce}, as the possible gain is much 228higher in this cases as the possible loss. 229 230\bigskip 231The {\tt clean} command on the other hand is very fast and many commands leave 232a mess (dangling signal wires, etc). For example, most commands do not remove 233any wires or cells. They just change the connections and depend on a later 234call to clean to get rid of the now unused objects. So the occasional {\tt ;;} 235is a good idea in every synthesis script. 236\end{frame} 237 238%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 239 240\subsection{The {\tt memory} command} 241 242\begin{frame}[fragile]{\subsecname} 243In the RTL netlist, memory reads and writes are individual cells. This makes 244consolidating the number of ports for a memory easier. The {\tt memory} 245transforms memories to an implementation. Per default that is logic for address 246decoders and registers. It also is a macro command that calls other commands: 247 248\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] 249# this merges registers into the memory read- and write cells. 250memory_dff 251 252# this collects all read and write cells for a memory and transforms them 253# into one multi-port memory cell. 254memory_collect 255 256# this takes the multi-port memory cell and transforms it to address decoder 257# logic and registers. This step is skipped if "memory" is called with -nomap. 258memory_map 259\end{lstlisting} 260 261\bigskip 262Usually it is preferred to use architecture-specific RAM resources for memory. 263For example: 264 265\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] 266memory -nomap; techmap -map my_memory_map.v; memory_map 267\end{lstlisting} 268\end{frame} 269 270\begin{frame}[t, fragile]{\subsecname{} -- Example 1/2} 271\vbox to 0cm{\includegraphics[width=0.7\linewidth,trim=0cm 0cm 0cm -10cm]{PRESENTATION_ExSyn/memory_01.pdf}\vss} 272\vskip-1cm 273\begin{columns} 274\column[t]{5cm} 275\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/memory_01.ys} 276\column[t]{5cm} 277\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/memory_01.v} 278\end{columns} 279\end{frame} 280 281\begin{frame}[t, fragile]{\subsecname{} -- Example 2/2} 282\vbox to 0cm{\hfill\includegraphics[width=7.5cm,trim=0cm 0cm 0cm -5cm]{PRESENTATION_ExSyn/memory_02.pdf}\vss} 283\vskip-1cm 284\begin{columns} 285\column[t]{5cm} 286\lstinputlisting[basicstyle=\ttfamily\fontsize{6pt}{8pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/memory_02.v} 287\column[t]{5cm} 288\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/memory_02.ys} 289\end{columns} 290\end{frame} 291 292%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 293 294\subsection{The {\tt fsm} command} 295 296\begin{frame}[fragile]{\subsecname{}} 297The {\tt fsm} command identifies, extracts, optimizes (re-encodes), and 298re-synthesizes finite state machines. It again is a macro that calls 299a series of other commands: 300 301\begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] 302fsm_detect # unless got option -nodetect 303fsm_extract 304 305fsm_opt 306clean 307fsm_opt 308 309fsm_expand # if got option -expand 310clean # if got option -expand 311fsm_opt # if got option -expand 312 313fsm_recode # unless got option -norecode 314 315fsm_info 316 317fsm_export # if got option -export 318fsm_map # unless got option -nomap 319\end{lstlisting} 320\end{frame} 321 322\begin{frame}{\subsecname{} -- details} 323Some details on the most important commands from the {\tt fsm\_*} group: 324 325\bigskip 326The {\tt fsm\_detect} command identifies FSM state registers and marks them 327with the {\tt (* fsm\_encoding = "auto" *)} attribute, if they do not have the 328{\tt fsm\_encoding} set already. Mark registers with {\tt (* fsm\_encoding = 329"none" *)} to disable FSM optimization for a register. 330 331\bigskip 332The {\tt fsm\_extract} command replaces the entire FSM (logic and state 333registers) with a {\tt \$fsm} cell. 334 335\bigskip 336The commands {\tt fsm\_opt} and {\tt fsm\_recode} can be used to optimize the 337FSM. 338 339\bigskip 340Finally the {\tt fsm\_map} command can be used to convert the (optimized) {\tt 341\$fsm} cell back to logic and registers. 342\end{frame} 343 344%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 345 346\subsection{The {\tt techmap} command} 347 348\begin{frame}[t]{\subsecname} 349\vbox to 0cm{\includegraphics[width=12cm,trim=-15cm 0cm 0cm -20cm]{PRESENTATION_ExSyn/techmap_01.pdf}\vss} 350\vskip-0.8cm 351The {\tt techmap} command replaces cells with implementations given as 352verilog source. For example implementing a 32 bit adder using 16 bit adders: 353 354\vbox to 0cm{ 355\vskip-0.3cm 356\lstinputlisting[basicstyle=\ttfamily\fontsize{6pt}{7pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/techmap_01_map.v} 357}\vbox to 0cm{ 358\vskip-0.5cm 359\lstinputlisting[xleftmargin=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, frame=single, language=verilog]{PRESENTATION_ExSyn/techmap_01.v} 360\lstinputlisting[xleftmargin=5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/techmap_01.ys} 361} 362\end{frame} 363 364\begin{frame}[t]{\subsecname{} -- stdcell mapping} 365When {\tt techmap} is used without a map file, it uses a built-in map file 366to map all RTL cell types to a generic library of built-in logic gates and registers. 367 368\bigskip 369\begin{block}{The built-in logic gate types are:} 370{\tt \$\_NOT\_ \$\_AND\_ \$\_OR\_ \$\_XOR\_ \$\_MUX\_} 371\end{block} 372 373\bigskip 374\begin{block}{The register types are:} 375{\tt \$\_SR\_NN\_ \$\_SR\_NP\_ \$\_SR\_PN\_ \$\_SR\_PP\_ \\ 376\$\_DFF\_N\_ \$\_DFF\_P\_ \\ 377\$\_DFF\_NN0\_ \$\_DFF\_NN1\_ \$\_DFF\_NP0\_ \$\_DFF\_NP1\_ \\ 378\$\_DFF\_PN0\_ \$\_DFF\_PN1\_ \$\_DFF\_PP0\_ \$\_DFF\_PP1\_ \\ 379\$\_DFFSR\_NNN\_ \$\_DFFSR\_NNP\_ \$\_DFFSR\_NPN\_ \$\_DFFSR\_NPP\_ \\ 380\$\_DFFSR\_PNN\_ \$\_DFFSR\_PNP\_ \$\_DFFSR\_PPN\_ \$\_DFFSR\_PPP\_ \\ 381\$\_DLATCH\_N\_ \$\_DLATCH\_P\_} 382\end{block} 383\end{frame} 384 385%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 386 387\subsection{The {\tt abc} command} 388 389\begin{frame}{\subsecname} 390The {\tt abc} command provides an interface to ABC\footnote[frame]{\url{http://www.eecs.berkeley.edu/~alanmi/abc/}}, 391an open source tool for low-level logic synthesis. 392 393\medskip 394The {\tt abc} command processes a netlist of internal gate types and can perform: 395\begin{itemize} 396\item logic minimization (optimization) 397\item mapping of logic to standard cell library (liberty format) 398\item mapping of logic to k-LUTs (for FPGA synthesis) 399\end{itemize} 400 401\medskip 402Optionally {\tt abc} can process registers from one clock domain and perform 403sequential optimization (such as register balancing). 404 405\medskip 406ABC is also controlled using scripts. An ABC script can be specified to use 407more advanced ABC features. It is also possible to write the design with 408{\tt write\_blif} and load the output file into ABC outside of Yosys. 409\end{frame} 410 411\begin{frame}[fragile]{\subsecname{} -- Example} 412\begin{columns} 413\column[t]{5cm} 414\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/abc_01.v} 415\column[t]{5cm} 416\lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/abc_01.ys} 417\end{columns} 418\includegraphics[width=\linewidth,trim=0 0cm 0 0cm]{PRESENTATION_ExSyn/abc_01.pdf} 419\end{frame} 420 421%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 422 423\subsection{Other special-purpose mapping commands} 424 425\begin{frame}{\subsecname} 426\begin{block}{\tt dfflibmap} 427This command maps the internal register cell types to the register types 428described in a liberty file. 429\end{block} 430 431\bigskip 432\begin{block}{\tt hilomap} 433Some architectures require special driver cells for driving a constant hi or lo 434value. This command replaces simple constants with instances of such driver cells. 435\end{block} 436 437\bigskip 438\begin{block}{\tt iopadmap} 439Top-level input/outputs must usually be implemented using special I/O-pad cells. 440This command inserts this cells to the design. 441\end{block} 442\end{frame} 443 444%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 445 446\subsection{Example Synthesis Script} 447 448\begin{frame}[fragile]{\subsecname} 449\begin{columns} 450\column[t]{4cm} 451\begin{lstlisting}[basicstyle=\ttfamily\fontsize{6pt}{7pt}\selectfont, language=ys] 452# read and elaborate design 453read_verilog cpu_top.v cpu_ctrl.v cpu_regs.v 454read_verilog -D WITH_MULT cpu_alu.v 455hierarchy -check -top cpu_top 456 457# high-level synthesis 458proc; opt; fsm;; memory -nomap; opt 459 460# substitute block rams 461techmap -map map_rams.v 462 463# map remaining memories 464memory_map 465 466# low-level synthesis 467techmap; opt; flatten;; abc -lut6 468techmap -map map_xl_cells.v 469 470# add clock buffers 471select -set xl_clocks t:FDRE %x:+FDRE[C] t:FDRE %d 472iopadmap -inpad BUFGP O:I @xl_clocks 473 474# add io buffers 475select -set xl_nonclocks w:* t:BUFGP %x:+BUFGP[I] %d 476iopadmap -outpad OBUF I:O -inpad IBUF O:I @xl_nonclocks 477 478# write synthesis results 479write_edif synth.edif 480\end{lstlisting} 481\column[t]{6cm} 482\vskip1cm 483\begin{block}{Teaser / Outlook} 484\small\parbox{6cm}{ 485The weird {\tt select} expressions at the end of this script are discussed in 486the next part (Section 3, ``Advanced Synthesis'') of this presentation.} 487\end{block} 488\end{columns} 489\end{frame} 490 491%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 492 493\subsection{Summary} 494 495\begin{frame}{\subsecname} 496\begin{itemize} 497\item Yosys provides commands for each phase of the synthesis. 498\item Each command solves a (more or less) simple problem. 499\item Complex commands are often only front-ends to simple commands. 500\item {\tt proc; opt; fsm; opt; memory; opt; techmap; opt; abc;;} 501\end{itemize} 502 503\bigskip 504\bigskip 505\begin{center} 506Questions? 507\end{center} 508 509\bigskip 510\bigskip 511\begin{center} 512\url{https://yosyshq.net/yosys/} 513\end{center} 514\end{frame} 515 516