\section{Yosys by example -- Synthesis} \begin{frame} \sectionpage \end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Typical Phases of a Synthesis Flow} \begin{frame}{\subsecname} \begin{itemize} \item Reading and elaborating the design \item Higher-level synthesis and optimization \begin{itemize} \item Converting {\tt always}-blocks to logic and registers \item Perform coarse-grain optimizations (resource sharing, const folding, ...) \item Handling of memories and other coarse-grain blocks \item Extracting and optimizing finite state machines \end{itemize} \item Convert remaining logic to bit-level logic functions \item Perform optimizations on bit-level logic functions \item Map bit-level logic gates and registers to cell library \item Write results to output file \end{itemize} \end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Reading the design} \begin{frame}[fragile]{\subsecname} \begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] read_verilog file1.v read_verilog -I include_dir -D enable_foo -D WIDTH=12 file2.v read_verilog -lib cell_library.v verilog_defaults -add -I include_dir read_verilog file3.v read_verilog file4.v verilog_defaults -clear verilog_defaults -push verilog_defaults -add -I include_dir read_verilog file5.v read_verilog file6.v verilog_defaults -pop \end{lstlisting} \end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Design elaboration} \begin{frame}[fragile]{\subsecname} During design elaboration Yosys figures out how the modules are hierarchically connected. It also re-runs the AST parts of the Verilog frontend to create all needed variations of parametric modules. \bigskip \begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] # simplest form. at least this version should be used after reading all input files # hierarchy # recommended form. fails if parts of the design hierarchy are missing, removes # everything that is unreachable from the top module, and marks the top module. # hierarchy -check -top top_module \end{lstlisting} \end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{The {\tt proc} command} \begin{frame}[fragile]{\subsecname} The Verilog frontend converts {\tt always}-blocks to RTL netlists for the expressions and ``processes'' for the control- and memory elements. \medskip The {\tt proc} command transforms this ``processes'' to netlists of RTL multiplexer and register cells. \medskip The {\tt proc} command is actually a macro-command that calls the following other commands: \begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] proc_clean # remove empty branches and processes proc_rmdead # remove unreachable branches proc_init # special handling of "initial" blocks proc_arst # identify modeling of async resets proc_mux # convert decision trees to multiplexer networks proc_dff # extract registers from processes proc_clean # if all went fine, this should remove all the processes \end{lstlisting} \medskip Many commands can not operate on modules with ``processes'' in them. Usually a call to {\tt proc} is the first command in the actual synthesis procedure after design elaboration. \end{frame} \begin{frame}[fragile]{\subsecname{} -- Example 1/3} \begin{columns} \column[t]{5cm} \lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/proc_01.v} \column[t]{5cm} \lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/proc_01.ys} \end{columns} \hfil\includegraphics[width=8cm,trim=0 0cm 0 0cm]{PRESENTATION_ExSyn/proc_01.pdf} \end{frame} \begin{frame}[t, fragile]{\subsecname{} -- Example 2/3} \vbox to 0cm{\includegraphics[width=\linewidth,trim=0cm 0cm 0cm -2.5cm]{PRESENTATION_ExSyn/proc_02.pdf}\vss} \vskip-1cm \begin{columns} \column[t]{5cm} \lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/proc_02.v} \column[t]{5cm} \lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/proc_02.ys} \end{columns} \end{frame} \begin{frame}[t, fragile]{\subsecname{} -- Example 3/3} \vbox to 0cm{\includegraphics[width=\linewidth,trim=0cm 0cm 0cm -1.5cm]{PRESENTATION_ExSyn/proc_03.pdf}\vss} \vskip-1cm \begin{columns} \column[t]{5cm} \lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/proc_03.ys} \column[t]{5cm} \lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/proc_03.v} \end{columns} \end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{The {\tt opt} command} \begin{frame}[fragile]{\subsecname} The {\tt opt} command implements a series of simple optimizations. It also is a macro command that calls other commands: \begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] opt_expr # const folding and simple expression rewriting opt_merge -nomux # merging identical cells do opt_muxtree # remove never-active branches from multiplexer tree opt_reduce # consolidate trees of boolean ops to reduce functions opt_merge # merging identical cells opt_rmdff # remove/simplify registers with constant inputs opt_clean # remove unused objects (cells, wires) from design opt_expr # const folding and simple expression rewriting while [changed design] \end{lstlisting} The command {\tt clean} can be used as alias for {\tt opt\_clean}. And {\tt ;;} can be used as shortcut for {\tt clean}. For example: \begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] proc; opt; memory; opt_expr;; fsm;; \end{lstlisting} \end{frame} \begin{frame}[t, fragile]{\subsecname{} -- Example 1/4} \vbox to 0cm{\includegraphics[width=\linewidth,trim=0cm 0cm 0cm -0.5cm]{PRESENTATION_ExSyn/opt_01.pdf}\vss} \vskip-1cm \begin{columns} \column[t]{5cm} \lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/opt_01.ys} \column[t]{5cm} \lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/opt_01.v} \end{columns} \end{frame} \begin{frame}[t, fragile]{\subsecname{} -- Example 2/4} \vbox to 0cm{\includegraphics[width=\linewidth,trim=0cm 0cm 0cm 0cm]{PRESENTATION_ExSyn/opt_02.pdf}\vss} \vskip-1cm \begin{columns} \column[t]{5cm} \lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/opt_02.ys} \column[t]{5cm} \lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/opt_02.v} \end{columns} \end{frame} \begin{frame}[t, fragile]{\subsecname{} -- Example 3/4} \vbox to 0cm{\includegraphics[width=\linewidth,trim=0cm 0cm 0cm -2cm]{PRESENTATION_ExSyn/opt_03.pdf}\vss} \vskip-1cm \begin{columns} \column[t]{5cm} \lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/opt_03.ys} \column[t]{5cm} \lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/opt_03.v} \end{columns} \end{frame} \begin{frame}[t, fragile]{\subsecname{} -- Example 4/4} \vbox to 0cm{\hskip6cm\includegraphics[width=6cm,trim=0cm 0cm 0cm -3cm]{PRESENTATION_ExSyn/opt_04.pdf}\vss} \vskip-1cm \begin{columns} \column[t]{5cm} \lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/opt_04.v} \column[t]{5cm} \lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/opt_04.ys} \end{columns} \end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{When to use {\tt opt} or {\tt clean}} \begin{frame}{\subsecname} Usually it does not hurt to call {\tt opt} after each regular command in the synthesis script. But it increases the synthesis time, so it is favourable to only call {\tt opt} when an improvement can be achieved. \bigskip The designs in {\tt yosys-bigsim} are a good playground for experimenting with the effects of calling {\tt opt} in various places of the flow. \bigskip It generally is a good idea to call {\tt opt} before inherently expensive commands such as {\tt sat} or {\tt freduce}, as the possible gain is much higher in this cases as the possible loss. \bigskip The {\tt clean} command on the other hand is very fast and many commands leave a mess (dangling signal wires, etc). For example, most commands do not remove any wires or cells. They just change the connections and depend on a later call to clean to get rid of the now unused objects. So the occasional {\tt ;;} is a good idea in every synthesis script. \end{frame} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{The {\tt memory} command} \begin{frame}[fragile]{\subsecname} In the RTL netlist, memory reads and writes are individual cells. This makes consolidating the number of ports for a memory easier. The {\tt memory} transforms memories to an implementation. Per default that is logic for address decoders and registers. It also is a macro command that calls other commands: \begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] # this merges registers into the memory read- and write cells. memory_dff # this collects all read and write cells for a memory and transforms them # into one multi-port memory cell. memory_collect # this takes the multi-port memory cell and transforms it to address decoder # logic and registers. This step is skipped if "memory" is called with -nomap. memory_map \end{lstlisting} \bigskip Usually it is preferred to use architecture-specific RAM resources for memory. For example: \begin{lstlisting}[xleftmargin=0.5cm, basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys] memory -nomap; techmap -map my_memory_map.v; memory_map \end{lstlisting} \end{frame} \begin{frame}[t, fragile]{\subsecname{} -- Example 1/2} \vbox to 0cm{\includegraphics[width=0.7\linewidth,trim=0cm 0cm 0cm -10cm]{PRESENTATION_ExSyn/memory_01.pdf}\vss} \vskip-1cm \begin{columns} \column[t]{5cm} \lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=ys, frame=single]{PRESENTATION_ExSyn/memory_01.ys} \column[t]{5cm} \lstinputlisting[basicstyle=\ttfamily\fontsize{8pt}{10pt}\selectfont, language=verilog]{PRESENTATION_ExSyn/memory_01.v} \end{columns} \end{frame} \begin{frame}[t, fragile]{\subsecname{} -- Example 2/2} \vbox to 0cm{\hfill\includegraphics[width=7.5cm,trim=0cm 0cm 0cm -5cm]{PRESENTATION_ExSyn/memory_02
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
2011 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS/RT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file chdebug.h
* @brief Debug macros and structures.
*
* @addtogroup debug
* @{
*/
#ifndef _CHDEBUG_H_
#define _CHDEBUG_H_
#if CH_DBG_ENABLE_ASSERTS || CH_DBG_ENABLE_CHECKS || \
CH_DBG_ENABLE_STACK_CHECK || CH_DBG_SYSTEM_STATE_CHECK
#define CH_DBG_ENABLED TRUE
#else
#define CH_DBG_ENABLED FALSE
#endif
#define __QUOTE_THIS(p) #p
/*===========================================================================*/
/**
* @name Debug related settings
* @{
*/
/*===========================================================================*/
/**
* @brief Trace buffer entries.
*/
#ifndef CH_TRACE_BUFFER_SIZE
#define CH_TRACE_BUFFER_SIZE 64
#endif
/**
* @brief Fill value for thread stack area in debug mode.
*/
#ifndef CH_STACK_FILL_VALUE
#define CH_STACK_FILL_VALUE 0x55
#endif
/**
* @brief Fill value for thread area in debug mode.
* @note The chosen default value is 0xFF in order to make evident which
* thread fields were not initialized when inspecting the memory with
* a debugger. A uninitialized field is not an error in itself but it
* better to know it.
*/
#ifndef CH_THREAD_FILL_VALUE
#define CH_THREAD_FILL_VALUE 0xFF
#endif
/** @} */
/*===========================================================================*/
/* System state checker related code and variables. */
/*===========================================================================*/
#if !CH_DBG_SYSTEM_STATE_CHECK
#define dbg_check_disable()
#define dbg_check_suspend()
#define dbg_check_enable()
#define dbg_check_lock()
#define dbg_check_unlock()
#define dbg_check_lock_from_isr()
#define dbg_check_unlock_from_isr()
#define dbg_check_enter_isr()
#define dbg_check_leave_isr()
#define chDbgCheckClassI();
#define chDbgCheckClassS();
#endif
/*===========================================================================*/
/* Trace related structures and macros. */
/*===========================================================================*/
#if CH_DBG_ENABLE_TRACE || defined(__DOXYGEN__)
/**
* @brief Trace buffer record.
*/
typedef struct {
systime_t se_time; /**< @brief Time of the switch event. */
Thread *se_tp; /**< @brief Switched in thread. */
void *se_wtobjp; /**< @brief Object where going to sleep.*/
uint8_t se_state; /**< @brief Switched out thread state. */
} ch_swc_event_t;
/**
* @brief Trace buffer header.
*/
typedef struct {
unsigned tb_size; /**< @brief Trace buffer size (entries).*/
ch_swc_event_t *tb_ptr; /**< @brief Pointer to the buffer front.*/
/** @brief Ring buffer.*/
ch_swc_event_t tb_buffer[CH_TRACE_BUFFER_SIZE];
} ch_trace_buffer_t;
#if !defined(__DOXYGEN__)
extern ch_trace_buffer_t dbg_trace_buffer;
#endif
#endif /* CH_DBG_ENABLE_TRACE */
#if !CH_DBG_ENABLE_TRACE
/* When the trace feature is disabled this function is replaced by an empty
macro.*/
#define dbg_trace(otp)
#endif
/*===========================================================================*/
/* Parameters checking related macros. */
/*===========================================================================*/
#if CH_DBG_ENABLE_CHECKS || defined(__DOXYGEN__)
/**
* @name Macro Functions
* @{
*/
/**
* @brief Function parameter check.
* @details If the condition check fails then the kernel panics and halts.
* @note The condition is tested only if the @p CH_DBG_ENABLE_CHECKS switch
* is specified in @p chconf.h else the macro does nothing.
*
* @param[in] c the condition to be verified to be true
* @param[in] func the undecorated function name
*
* @api
*/
#if !defined(chDbgCheck)
#define chDbgCheck(c, func) { \
if (!(c)) \
chDbgPanic(__QUOTE_THIS(func)"()"); \
}
#endif /* !defined(chDbgCheck) */
/** @} */
#else /* !CH_DBG_ENABLE_CHECKS */
#define chDbgCheck(c, func) { \
(void)(c), (void)__QUOTE_THIS(func)"()"; \
}
#endif /* !CH_DBG_ENABLE_CHECKS */
/*===========================================================================*/
/* Assertions related macros. */
/*===========================================================================*/
#if CH_DBG_ENABLE_ASSERTS || defined(__DOXYGEN__)
/**
* @name Macro Functions
* @{
*/
/**
* @brief Condition assertion.
* @details If the condition check fails then the kernel panics with the
* specified message and halts.
* @note The condition is tested only if the @p CH_DBG_ENABLE_ASSERTS switch
* is specified in @p chconf.h else the macro does nothing.
* @note The convention for the message is the following:<br>
* @<function_name@>(), #@<assert_number@>
* @note The remark string is not currently used except for putting a
* comment in the code about the assertion.
*
* @param[in] c the condition to be verified to be true
* @param[in] m the text message
* @param[in] r a remark string
*
* @api
*/
#if !defined(chDbgAssert)
#define chDbgAssert(c, m, r) { \
if (!(c)) \
chDbgPanic(m); \
}
#endif /* !defined(chDbgAssert) */
/** @} */
#else /* !CH_DBG_ENABLE_ASSERTS */
#define chDbgAssert(c, m, r) {(void)(c);}
#endif /* !CH_DBG_ENABLE_ASSERTS */
extern char *dbg_panic_msg;
/*===========================================================================*/
/* Panic related macros. */
/*===========================================================================*/
#if !CH_DBG_ENABLED
/* When the debug features are disabled this function is replaced by an empty
macro.*/
#define chDbgPanic(msg) {}
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if CH_DBG_SYSTEM_STATE_CHECK
void dbg_check_disable(void);
void dbg_check_suspend(void);
void dbg_check_enable(void);
void dbg_check_lock(void);
void dbg_check_unlock(void);
void dbg_check_lock_from_isr(void);
void dbg_check_unlock_from_isr(void);
void dbg_check_enter_isr(void);
void dbg_check_leave_isr(void);
void chDbgCheckClassI(void);
void chDbgCheckClassS(void);
#endif
#if CH_DBG_ENABLE_TRACE || defined(__DOXYGEN__)
void _trace_init(void);
void dbg_trace(Thread *otp);
#endif
#if CH_DBG_ENABLED
void chDbgPanic(char *msg);
#endif
#ifdef __cplusplus
}
#endif
#endif /* _CHDEBUG_H_ */
/** @} */