%==============================================================================
% Document header
%==============================================================================
\documentclass[a4paper,11pt]{article}

% Color package
\usepackage[usenames,dvipsnames,table]{xcolor}

% Hyperrefs
\usepackage[
  colorlinks = true,
  linkcolor  = black,
  citecolor  = black,
  urlcolor   = blue,
]{hyperref}

% Longtable
\usepackage{longtable}

% Graphics, multirow
\usepackage{graphicx}
\usepackage{multirow}

% Appendix package
\usepackage[toc,page]{appendix}

\usepackage{fancyhdr}
\setlength{\headheight}{15.2pt}
\pagestyle{fancy}
\fancyhead[L]{\nouppercase{\leftmark}}
\fancyhead[R]{}
\renewcommand{\footrulewidth}{0.4pt}

% Row number command
\newcounter{rownr}
\newcommand{\rownumber}{\stepcounter{rownr}\arabic{rownr}}

%==============================================================================
% Start of document
%==============================================================================
\begin{document}

%------------------------------------------------------------------------------
% Title
%------------------------------------------------------------------------------
\include{cern-title}

%------------------------------------------------------------------------------
% Revision history
%------------------------------------------------------------------------------
\pagebreak

\thispagestyle{empty}

\addcontentsline{toc}{section}{Licensing information}
\section*{Licensing information}

\noindent
This document is licensed under a Creative Commons Attribution-ShareAlike 4.0
International License. If you have not received a copy of the license along with this
work, see \\
\url{http://creativecommons.org/licenses/by-sa/4.0/}

\section*{Revision history}
\addcontentsline{toc}{section}{Revision history}

\centerline
{
  \rowcolors{2}{white}{gray!25}
  \begin{tabular}{l c p{.6\textwidth}}
  \hline
  \multicolumn{1}{c}{\textbf{Date}} & \multicolumn{1}{c}{\textbf{Version}} & \multicolumn{1}{c}{\textbf{Change}} \\
  \hline 
  05-08-2014 & 0.1 & First draft \\
  12-08-2014 & 1.0 & First release \\
  29-08-2014 & 2.0 & Added sections for input pulse counters, time-tagging,
                     manual pulse triggering, one-wire thermometer module, the switches
                     on the converter boards, and changed and corrected some wording \\
  26-01-2014 & 2.1 & Added licensing information, Table~\ref{tbl:timetag-rd-seq} and information
                     on which generics enable synthesis of certain modules. \\
  \hline
  \end{tabular}
}

%------------------------------------------------------------------------------
% List of figs, tables
%------------------------------------------------------------------------------
\pagebreak
\pdfbookmark[1]{\contentsname}{toc}
\tableofcontents

\pagebreak
\listoffigures
\listoftables

%------------------------------------------------------------------------------
% List of abbreviations
%------------------------------------------------------------------------------
\pagebreak
\section*{List of Abbreviations}
\begin{tabular}{l l}
CR   & Control Register \\
FPGA & Field-Programmable Gate Array \\
LSR  & Line Status Register \\
MSWR & Multicast Switch Register \\
SR   & Status Register \\
WRPC & White Rabbit PTP Core \\
\end{tabular}
\addcontentsline{toc}{section}{List of abbreviations}

%==============================================================================
% SEC: Intro
%==============================================================================
\pagebreak
\section{Introduction}
\label{sec:intro}

This document presents the common gateware for converter board projects~\cite{level-conversion}.
This gateware, mainly written in VHDL, is a grouping of modules common to all converter board projects.
A synthesized version thereof is intended to be downloaded to the FPGA on the converter board.
No specific FPGA is assumed for the converter boards, therefore the VHDL code is as generic as possible.
However, some details about the way that the boards are designed in the Hardware \& Timing section at CERN
are assumed, and these details are described throughout the document.

The document will start with a summary of the VHDL entity's ports, continue with presenting
a top-level diagram of the gateware, followed by a high-level description of each module in the gateware.
More involved details can be obtained by consulting the code itself, which can be freely obtained (including
the \textit{general-cores}) submodule from the \textit{git} repository~\cite{conv-common-gw-git} using the
following commands:

\begin{small}
\begin{verbatim}
git clone git://ohwr.org/level-conversion/conv-common-gw.git
git submodule update --init --recursive
\end{verbatim}
\end{small}

%==============================================================================
% SEC: Instantiation
%==============================================================================
\pagebreak
\section{Instantiation}
\label{sec:instantiation}

To use the common gateware, the designer should instantiate the module \textit{conv\_common\_gw},
which is part of the repository and contains all sub-modules required to implement
the pulse repetition functionality.

A corresponding VHDL component declaration can be found in the associated package file
(\textit{conv\_common\_gw\_pkg.vhd}), which needs to be imported into the file of the
instantiating module.

Port names follow the OHWR coding style guide~\cite{coding-guidelines}. Except for few cases,
the module uses active-high ports, any adaptations to active-low logic must be made in external logic.

Since there are a lot of ports in the component, listing them all here would be a waste of space.
The reader is referred to the package file or the source file directly, where each port declaration
is commented. Projects where this gateware is already used can also be a good source of
reference (see the \textit{conv-common-gw} project Wiki page~\cite{conv-common-gw-wiki}).

%==============================================================================
% SEC: Top-level diagram
%==============================================================================
\pagebreak
\section{Overview}
\label{sec:overview}

The common gateware comprises various modules, as shown in Figure~\ref{fig:block-diagram}.
The channel logic, presented in Section~\ref{sec:chan-logic}, is multiplied \textit{g\_nr\_chans} times.
Its status and select functionality can be controlled via the controller board
registers (Section~\ref{subsec:conv-regs}), which are part of a Wishbone memory-mapped
peripheral. This peripheral, along with the rest of the memory-mapped peripherals on converter boards,
is accessible through an I$^2$C interface, and an I$^2$C to Wishbone bridge performs
the conversion between the two interfaces.

\begin{figure}[h]
  \centerline{\includegraphics[width=1.1\textwidth]{fig/block-diagram}}
  \caption{\label{fig:block-diagram} Block diagram of common gateware}
\end{figure}

%------------------------------------------------------------------------------
% SUBSEC: Switches
%------------------------------------------------------------------------------
\subsection{Switches on converter boards}

Various converter boards may use various switches, so a convention should be made
about switch names and locations.

The CONV-TTL-BLO~\cite{conv-ttl-blo-ohwr}, which is the first converter project using
an FPGA, had eight switches which we called \textit{general-purpose switches}. These
appear on the CONV-TTL-RS485~\cite{conv-ttl-rs485-ohwr} as well. It is recommended to add
general-purpose switches on all converter boards in a similar manner to the two projects
mentioned above.

Additionally, the RS-485 pulse repeater adds four other switches, which are called MultiCast switches
and despite their seemingly dedicated name, they are also general-purpose switches at the
time of writing of this document. Therefore, they are considered as \textit{other switches},
due to the fact they do not appear on the CONV-TTL-BLO.
The state of the general-purpose switches can be read from the status register
(SR -- see Appendix~\ref{app:conv-regs-SR}), and the state of the MultiCast
switches can be read from the other switches register (OSWR -- see Appendix~\ref{app:conv-regs-OSWR}).

A total of 32 dedicated switches can be implemented on converter boards and mapped to the OSWR, should
they be required. This number-of-32 constraint is imposed by the number of bits in the OSWR.

Table~\ref{tbl:switches} summarizes the switches on converter boards.

\begin{table}[ht]
  \caption{\label{tbl:switches} Switches on converter boards}
  \rowcolors{2}{white}{gray!25}
  \centerline {
    \begin{tabular}{l p{.7\textwidth}}
      \hline
      \multicolumn{1}{c}{\textbf{Name}} & \multicolumn{1}{c}{\textbf{Comments}} \\
      \hline
      General-purpose & Eight switches that \textit{should} be implemented on all converter boards.
                        Read their state from the SR.SWITCHES field (see Appendix~\ref{app:conv-regs-SR}) \\
      Other & Dedicated switches for specific converter boards.
        y      Read their state from the OSWR register
              (see Appendix~\ref{app:conv-regs-OSWR}) \\
      \hline
    \end{tabular}
  }
\end{table}

%==============================================================================
% SEC: Clocking
%==============================================================================
\pagebreak
\section{Clocks}
\label{sec:clocks}

There are two clock signals input to the FPGA (Figure~\ref{fig:clocks}).
The first is a 20~MHz signal from a VCXO. The second clock signal with a frequency
of 125~MHz is generated on-board via a Texas Instruments PLL IC from a 25~MHz VCXO.

Two DACs are provided on-board for controlling the two VCXOs. The DACs can be
controlled via SPI, and if White Rabbit is available, the White Rabbit PTP Core (WRPC)
can control these DACs to discipline these clocks.

Table~\ref{tbl:clocks} lists the clock domains used in the gateware.

\begin{figure}[h]
  \centerline{\includegraphics[width=\textwidth]{fig/clocks}}
  \caption{FPGA clock inputs}
  \label{fig:clocks}
\end{figure}

\begin{table}[h]
  \caption{\label{tbl:clocks} Clock domains}
  \rowcolors{2}{white}{gray!25}
  \centerline
  {
    \begin{tabular}{c c p{.6\textwidth}}
    \hline
    \textbf{Clock domain} & \textbf{Frequency} & \multicolumn{1}{c}{\textbf{Comments}} \\
    \hline
    \textit{clk\_20\_i} & 20~MHz  & Clock input to most of the sequential logic \\
    \textit{clk\_125}   & 125~MHz & Time-tagging logic and WR reference clock \\
    \hline
    \end{tabular}
  }
\end{table}

%==============================================================================
% SEC: Reset
%==============================================================================
\pagebreak
\section{Reset}
\label{sec:reset}

An internal reset generator (\textit{conv\_reset\_gen}) is used to supply a reset pulse to the sequential
modules of the \textit{conv\_common\_gw}, so that they start up in a known state.

This reset pulse occurs either when the FPGA finishes configuration and goes into user mode, or when
an external reset is received. The external reset can come from one of two sources:
\begin{itemize}
  \item the VME system reset pin
  \item a write to the CR.RST bit, after having been previously unlocked by a write to the
  CR.RST\_UNLOCK bit (see Appendix~\ref{app:conv-regs-CR})
\end{itemize}

The \textit{conv\_reset\_gen} component is clocked from \textit{clk\_20\_i}, so the reset
it generates is in the 20~MHz clock domain. This is also the reset that is present at the
\textit{rst\_n\_o} pin. A reset synchronized to the 125~MHz clock domain is generated
inside \textit{conv\_common\_gw}, but this is not provided at the output.

Note that the VHDL of this module is Xilinx and XST-specific and porting to a different
FPGA architecture or synthesis tool is not guaranteed to provide the same results.
The \textit{conv\_reset\_gen} module has an initial value set for the counter signal after
power-up, which is guaranteed by XST to be set after the FPGA's GSR signal is de-asserted.

By default, the reset time is set to 100~ms.


%==============================================================================
% SEC: Channel logic
%==============================================================================
\pagebreak
\section{Channel logic}
\label{sec:chan-logic}

The channel logic is presented in Figure~\ref{fig:chan-logic}. The central part
thereof is a pulse generator followed by a burst mode controller. The former can be configured for pass-through mode, or
fixed-width pulse generation with subsequent pulse rejection after a pulse has
been generated. The latter (the burst controller) allows high frequency bursts to be repeated for a limited period of time, as defined by some internal parameters, see Section~\ref{subsec:burst-ctrl}. The generator itself can be triggered in two ways:

\begin{itemize}
  \item by the pulse input, which can be fed directly to the generator's input,
  or optionally glitch filtered (the selection is done by means of a general-purpose
  switch)
  \item manually, through commands sent by a user via the I$^2$C and ultimately Wishbone bus
\end{itemize}

The output of this pulse generator triggers lighting a pulse LED,
apart from driving the pulse output of the module. Input pulses also trigger
the incrementing of a pulse counter, as well as the storage of a timestamp to a dedicated
FIFO memory.

Note that the channel logic can be selectively synthesized by means of the
top-level component generics. Table~\ref{tbl:chan-logic-generics} shows which
generics enable channel logic shown in Figure~\ref{fig:chan-logic}.

\begin{figure}[h]
  \centerline{\includegraphics[width=1.1\textwidth]{fig/chan-logic}}
  \caption{\label{fig:chan-logic} Channel logic diagram}
\end{figure}

\begin{table}[h]
  \rowcolors{2}{white}{gray!25}
  \caption{\label{tbl:chan-logic-generics} Generics to enable components in the channel logic}
  \centerline{
  \begin{tabular}{l l}
  \hline
  \multicolumn{1}{c}{\textbf{Component}} & \multicolumn{1}{c}{\textbf{Generic}} \\
  \hline
  Pulse counters & \textit{g\_with\_pulse\_cnt $=>$ true} \\
  Timetag logic & \textit{g\_with\_pulse\_timetag $=>$ true} \\
  Manual trigger & \textit{g\_with\_man\_trig $=>$ true} \\
  \hline
  \end{tabular}
  }
\end{table}

%------------------------------------------------------------------------------
\subsection{Output enable}
\label{subsec:oen}
%------------------------------------------------------------------------------

Converter board outputs have to be enabled prior to being used. Within the
\textit{conv\_common\_gw}, there are four output enables. Apart from the global
channel output enable, there are dedicated output enables for potential front
and rear panel connections (see the converter board's specific user guide for information
on front and rear panels).

To make sure that pulses are output only when the FPGA can handle them, the global
output enable is set only after the reset period is finished. The rest of the
output enables are set one clock cycle later. This in combination with the
rest of the circuitry outside the FPGA makes sure no glitches or erroneous pulses
are output during the internal reset period.

An example connection of the output enable signals on the CONV-TTL-RS485~\cite{conv-ttl-rs485-ohwr}
is shown in Figure~\ref{fig:outp-enable}.

\begin{figure}
  \centerline{\includegraphics[width=\textwidth]{fig/outp-enable}}
  \caption{\label{fig:outp-enable} Output enable example}
\end{figure}

%------------------------------------------------------------------------------
\subsection{Glitch filter}
\label{subsec:glitch-filt}
%------------------------------------------------------------------------------

The glitch filter input (\textit{gf\_en\_n\_i}) is intended to be enabled via one
of the general-purpose switches on the converter board when the environment where
the board is placed is hazardous and can potentially create harmful glitches on the
line. It is active-low, therefore a '0' on the pin enables the glitch filter.

The length of the glitch filter can be selected at top-level via the generic
\textit{g\_pgen\_glitch\_filt\_len}, which is in measures of \textit{clk\_20\_i} cycles.

For information on the module's implementation, consult its documentation in the
\textit{ip\_cores/general-cores/doc/} folder.

%------------------------------------------------------------------------------
\subsection{Pulse counter}
\label{subsec:pulse-cnt}
%------------------------------------------------------------------------------

\begin{tabular}{p{.96\textwidth}}
\hline
\large \hspace*{22pt} Synthesized when \textit{g\_with\_pulse\_cnt $=>$ true}. \\
\hline
\end{tabular}

\vspace*{11pt}

Figure~\ref{fig:pulse-cnt} presents the implementation of the pulse counters.
When a pulse arrives on either the TTL or blocking side, it is resynchronized
in the 20~MHz clock domain and passed to a \textit{fast counter} module. Indeed, at high frequencies it was found that internal counters need to be able to cope with high frequency triggers however short.

A so-callod \textit{Flancter}-based counter is therefore used~\cite{bib:doulos-counter}. When
a rising edge occurs on the pulse, the result of the counter is stored
to the channel pulse counter register. On v4 release of the gateware\footnotemark\footnotetext{On preceding releases, there was a single counter per channel, aggregating both types of pulses.}, there are two counters implemented separately for TTL 
and BLO outputs of each channel (CHxTTLPCR and CHxBLOPCR -- see Appendix~\ref{app:conv-regs}).

Figure~\ref{fig:pulse-cnt} presents the implementation for the TTL case only, the same is duplicated for the 
blocking counter.

The pulse counter register can be written via the \textit{conv\_regs} component as a
result of an I$^2$C write access to the register's address. At this point, the fastcounter module needs to be reset by the external load command, otherwise, it will keep its old value.

\begin{figure}[h]
  \centerline{\includegraphics[width=\textwidth]{fig/pulse-cnt}}
  \caption{Pulse counter implementation}
  \label{fig:pulse-cnt}
\end{figure}

The pulse counter register can be written via the \textit{conv\_regs} component as a
result of an I$^2$C write access to the register's address.

%------------------------------------------------------------------------------
\subsection{Time-tagging mechanism}
\label{subsec:pulse-timetag}
%------------------------------------------------------------------------------

\begin{tabular}{p{.96\textwidth}}
\hline
\large \hspace*{22pt} Synthesized when \textit{g\_with\_pulse\_timetag $=>$ true}. \\
\hline
\end{tabular}

\vspace*{11pt}

The architecture of the pulse time-tagging mechanism is shown in Figure~\ref{fig:timetag-arch}.
The time-tagging mechanism is clocked from the 125~MHz clock domain. Input pulses trigger the storage
to a ring buffer of either internally-generated timestamps, or precise timestamps from the White
Rabbit network. Four tag buffer (TB*) registers point to the latest sample in the buffer and
allow for reading the buffer entirely. Since the ring buffer is shared between the channels, the latest timestamp
for a specific channel is available in the latest timestamp registers for the channel.
Finally, the current value of TAI time can be read from dedicated registers.

\begin{figure}[h]
  \centerline{\includegraphics[width=1\textwidth]{fig/timetag-arch}}
  \caption{\label{fig:timetag-arch} Pulse time-tagging architecture}
\end{figure}

%------------------------------------------------------------------------------
\pagebreak
\subsubsection{Time-tagging controller}
\label{subsec:pulse-timetag-ctrl}
%------------------------------------------------------------------------------

The architecture of the time-tag controller is shown in Figure~\ref{fig:timetag-core}.
The time-tag controller contains two counters used for counting time
as well as logic for multiplexing between internally and externally generated timestamps.
The two counters implemented are:

\begin{itemize}
  \item \textit{cycles counter} -- count the number of clock cycles to one second
  \item \textit{TAI counter} -- count full seconds
\end{itemize}

The TAI counter can be loaded with a new value by writing the TVLR and TVHR registers
(see Appendix~\ref{app:conv-regs-TVLR} and~\ref{app:conv-regs-TVHR}). A load of either
of these registers will reset the internal cycles counter.

Note that due to the synchronization logic, rising edge detector and the latching of the
ORed pulse rising edge detection signal, a timestamp is stored to the time-tag buffer
two to three cycles after its actual arrival on the input (Figure~\ref{fig:timetag-delay}).
The same delay applies to the latest timestamp registers.

\begin{figure}[h]
  \centerline{\includegraphics[width=\textwidth]{fig/timetag-core}}
  \caption{\label{fig:timetag-core} Time-tagging controller architecture}
\end{figure}
  
\begin{figure}
  \centerline{\includegraphics[width=\textwidth]{fig/timetag-delay}}
  \caption{\label{fig:timetag-delay} Timestamp storage delay}
\end{figure}

%------------------------------------------------------------------------------
\subsubsection{Ring buffer}
\label{subsec:pulse-timetag-buf}
%------------------------------------------------------------------------------

The implementation of the ring buffer is shown in Figure~\ref{fig:timetag-ring-buf}.
A dual-clock asynchronous FIFO synchronizes data between the read and write clock domains.
Data from the FIFO is stored to the RAM clocked from the read clock domain.

\begin{figure}
  \centerline{\includegraphics[width=\textwidth]{fig/timetag-ring-buf}}
  \caption{Ring buffer implementation}
  \label{fig:timetag-ring-buf}
\end{figure}

Figure~\ref{fig:timetag-buf-mech} shows the mechanics of the ring buffer, and helps
better understand the control logic. Note that by listing the converter board registers to
access, the figure is oriented towards converter board designs, but the ring buffer
component is usable in other designs as well.

In few words, the buffer read and write pointers
advance on read or write requests from the buffer. While a read can not be performed if the
buffer is empty, a write to a full buffer will start overwriting old timestamps.

For converter board designs, a caution should be put in place. Because the TBMR
register (see Appendix~\ref{app:conv-regs-TBMR}) causes the read pointer to advance,
it should be the last register read in a readout cycle. Otherwise, the values of the
other tag buffer registers will return the next sample in the tag buffer.

\begin{figure}
  \centerline{\includegraphics[width=.97\textwidth]{fig/timetag-buf-mech}}
  \caption{\label{fig:timetag-buf-mech} Ring buffer mechanics}
\end{figure}

\setcounter{rownr}{0}

\begin{table}[h]
  \caption{Timetag read sequence}
  \label{tbl:timetag-rd-seq}
  \centerline {
    \rowcolors{2}{white}{gray!25}
    \begin{tabular}{c p{.8\textwidth}}
    \hline
    \textbf{Step} & \multicolumn{1}{c}{\textbf{Action}} \\
    \hline
    \rownumber & \textbf{Read the TBCSR} and make sure that the EMPTY bit is not '1' \\
    \rownumber & \textbf{Read the TBCYR} to obtain the 8~ns cycles counter value \\
    \rownumber & \textbf{Read the TBTLR} to obtain the lower part of the TAI seconds counter \\
    \rownumber & \textbf{Read the TBTHR} to obtain the upper part of the TAI seconds counter \\
    \rownumber & \textbf{Read the TBTMR} to obtain the meta data about the timetag sample and advance
                 the buffer read pointer \\
    \hline
    \end{tabular}
  }
\end{table}

%------------------------------------------------------------------------------
\subsubsection{Synchronization issues}
\label{subsec:pulse-timetag-sync}
%------------------------------------------------------------------------------

Apart from the data coming from the faster clock domain into the slower clock domain, where
synchronization is handled by the FIFO insde the ring buffer component (see Figure~\ref{fig:timetag-ring-buf}),
there are three other places where synchronization may be a concern. These places are
shown in Figure~\ref{fig:timetag-sync}, along with the solution to the concern.

Note that although the TAI time signal is generated in the 125~MHz
clock domain, it is not synchronized before connection to the \textit{conv\_regs}.
This is because its rate of change of once per second is considered too slow to present
any problem of synchronization when read by the user.

\begin{figure}[h]
  \centerline{\includegraphics[width=\textwidth]{fig/timetag-sync}}
  \caption{\label{fig:timetag-sync} Synchronization in the time-tagging logic}
\end{figure}

%------------------------------------------------------------------------------
\subsection{Manual pulse triggering}
\label{subsec:man-trig}
%------------------------------------------------------------------------------

\begin{tabular}{p{.96\textwidth}}
\hline
\large \hspace*{22pt} Synthesized when \textit{g\_with\_man\_trig $=>$ true}. \\
\hline
\end{tabular}

\vspace*{11pt}

The manual pulse trigger module (\textit{conv\_man\_trig}) is implemented in the form
of a simple state machine, which is shown in Figure~\ref{fig:man-trig}. The module
is directly connected to the register load output of the \textit{conv\_regs} module,
and a register load signal from the latter triggers the FSM. If the value sent via
the register to the module are part of the expected value in the password, the FSM
advances. Otherwise, the FSM returns to the IDLE state and the sequence must be re-commenced.
The FSM waits in each state indefinitely for a value to be input.

\begin{figure}[h]
  \centerline{\includegraphics[width=.55\textwidth]{fig/man-trig-fsm}}
  \caption{\label{fig:man-trig} FSM of the manual pulse trigger module}
\end{figure}

%------------------------------------------------------------------------------
\subsection{Pulse generation and dynamic burst control}

For hardware v4 of the CONV-TTL-BLO in particular (CONV-TTL-RS485 boards outputs are not sensitive to repetition frequency), release 4 of the gateware includes a \textit{burst mode} capability. Pulses output from the (\textit{conv\_pulse\_gen}) block, Sec~\ref{subsec:pulse-gen}, are fed onto to the \textit{conv\_dyn\_burst\_ctrl}, Sec~\ref{subsec:burst-ctrl}, where frequencies are limited over time and not on a pulse by pulse basis.

Moreover, v4 boards, give the possibility to select pulse width at the output via a \textit{general-purpose switch}. In addition to that, and for backwards compatibility with v3 boards and earlier, a fixed width, fixed frequency output is also available on the output for legacy boards\footnotemark.\footnotetext{These boards cannot handle high frequencies purely because of their hardware design and in that case \textit{burst mode} is disabled.}

Figure~\ref{fig:pulse-out-sel} shows how the output is selected depending on whether \textit{burst\_en\_n\_i} is activated or not, and also on which pulse width is selected (options are for \textit{SHORT} and \textit{LONG} pulses).

\begin{figure}[h]
  \centerline{\includegraphics[width=\textwidth]{fig/pulse-out-select}}
  \caption{\label{fig:pulse-out-sel} Pulse repetition output selection}
\end{figure}

\subsubsection{Pulse generator}
\label{subsec:pulse-gen}
%------------------------------------------------------------------------------

Figure~\ref{fig:pulse-gen} shows the implementation of the pulse generator (\textit{conv\_pulse\_gen})
block. When \textit{g\_pgen\_fixed\_width} is \textit{false},
the pulse generator is a simple pass-through. This is usable in converter boards
such as the CONV-TTL-RS485~\cite{conv-ttl-rs485-ohwr}, where the RS-485 outputs are not sensitive to the
duty cycle of the outputs pulses, and which can also be used to distribute
timing information.

When an output stage is sensitive to the pulse duty cycle, such as in the TTL to
blocking converter (CONV-TTL-BLO~\cite{conv-ttl-blo-ohwr}), the \textit{g\_pgen\_fixed\_width}
generic can be set to \textit{true} and this will synthesize a pulse generator
which outputs a pulse with a fixed width (\textit{g\_pgen\_pwidth}) and fixed
period (\textit{g\_pgen\_pperiod}).

\begin{figure}[h]
  \centerline{\includegraphics[width=\textwidth]{fig/pulse-gen}}
  \caption{\label{fig:pulse-gen} Pulse generator block}
\end{figure}

In this latter case, a finite-state machine (FSM) handles pulse generation and rejection.
Its general operation is shown in Figure~\ref{fig:pulse-gen-operation}.
The operation of the pulse generator is agnostic of whether the signal is de-glitched or not\footnotemark\footnotetext{This module has seen a complete redesign in comparison with the one used in release v3.0. This is because it had different signal paths for the asynchronous external trigger and the de-glitched version. This has made for a more complex logic, which the new module tries to simplify by using the same logic whether the signal is glitch-filtered or not} and 
so is independent of whether it is synchronous (de-glitched) or asynchronous to the system clock. 
After the pulse width has been reached, the FSM 
resets the input flip-flop and goes into the rejection state.

If any pulses arrive either during the generation state, or the rejection state, the error output
is set high for one clock cycle. This type of error is identified as a \textit{flim\_err\_p}. It is the result of the maximum allowed frequency being reached.

\begin{figure}
  \centerline{\includegraphics[width=\textwidth]{fig/pulse-gen-operation}}
  \caption{\label{fig:pulse-gen-operation} Pulse generator operation with \textit{g\_pgen\_fixed\_width = true}}
\end{figure}

\subsubsection{Dynamic burst controller}
\label{subsec:burst-ctrl}
The dynamic burst control block emulates temperature rise when new pulses arrive, when the 
temperature counter reaches a pre-set maximum value (corresponding to maximum temperature), the 
burst controller starts missing 
pulses. This means that the board needs to \textit{cool off} between pulses and therefore 
implements rejection only as long as the temperature is above the maximum. As soon as recovery is 
achieved (temperature is again below maximum) the board starts repeating again. 

The time at which the rejection starts depends on the frequency of the pulses coming out of the 
\textit{Pulse Generator} block. For high frequencies, temperature will rise quickly and pulses 
are rejected earlier. The lower the frequency the longer are repetition times.

The information relating repetition frequency and repetition times is embedded inside the FPGA and is generated in pre-processing and fed as a generic to the entity. The values used for a given thermal model is an array of constant values input as the \textit{g\_temp\_decre\_step} generic.
%They differ for the SHORT and LONG pulse implementations. Appendix~\ref{app:} shows how these values can be generated in pre-processing.


In terms of gateware implementation, see Fig.\ref{fig:burst_ctrl}, the \textit{conv\_dyn\_burst\_ctrl}, module uses a finite 
state machine (FSM) to handle transitions between pulse repetition and pulse rejection depending 
on the \textit{temp\_rise} counter value. 

The FSM is triggered by pulse signals \textit{pulse\_r\_edge\_p\_i} and \textit{pulse\_f\_edge\_p\_i} 
that had been generated as a result of synchronisation inside the \textit{Pulse Generator} block. The 
FSM outputs a \textit{burst\_ctrl\_rst} signal as a select signal to a multiplexer. The block's output replicates the input or clears it depending on the status of the \textit{burst\_ctrl\_rst} signal.

An error pulse is generated every time a pulse is missed. This is the \textit{frequency watchdog error}, \textit{fwdg\_err\_p}, which signifies that the board has started to miss pulses in order to limit temperature rise.

\begin{figure}[h]
  \centerline{\includegraphics[width=\textwidth]{fig/burst-ctrl}}
  \caption{\label{fig:burst_ctrl} Dynamic burst controller block}
\end{figure}

%------------------------------------------------------------------------------
\subsection{Pulse LED control}
\label{subsec:pulse-led}
%------------------------------------------------------------------------------

A rising edge on the \textit{pulse\_o} signal from the \textit{conv\_pulse\_gen}
block generates a 26-ms active-high pulse signal on the \textit{led\_pulse\_o} port of
\textit{conv\_common\_gw}. This port should be connected to the channel's pulse LED output. The same logic is used to drive LEDs on the inverting channels.

%==============================================================================
% SEC: Memory-mapped peripherals
%==============================================================================
\pagebreak
\section{Memory-mapped peripherals}
\label{sec:memmapped-periphs}

Various memory-mapped peripherals are implemented within \textit{conv\_common\_gw},
as seen below. They are interfaced to a Wishbone interconnect, which is SDB-enabled~\cite{sdb},
granted to the \textit{xwb\_sdb\_crossbar} module used to connect the slaves to the
master.

%==============================================================================
\subsection{I$^2$C to Wishbone bridge}
\label{subsec:i2c-bridge}
%==============================================================================

The Wishbone master in the interconnect is an I$^2$C to Wishbone bridge (\textit{wb\_i2c\_bridge} from
the \textit{general-cores} library~\cite{gencores-ohwr}), which implements the protocol
defined together with ELMA for communication via the serial lines on the VME P1 connector.

Details about this protocol, as well as implementation details for \textit{wb\_i2c\_bridge} can be
found in the module's documentation under the \textit{general-cores/doc/} folder.

Upon instantiating the \textit{wb\_i2c\_bridge} inside \textit{conv\_common\_gw}, the
module's watchdog timeout generic (\textit{g\_fsm\_wdt}) is set such that the watchdog
times out in 24~ms. This value is explained in comments inside the code, as well as
in the appendix to the \textit{wb\_i2c\_bridge} module's documentation.

When an I$^2$C transfer takes place according to the defined protocol, the \textit{led\_i2c\_o}
output strobes four times. This output should be connected to a bicolor LED of choice
for signaling communication.

%==============================================================================
\subsection{Converter board registers}
\label{subsec:conv-regs}
%==============================================================================

The \textit{conv\_regs} module contains various Wishbone-addressable registers that contain status information,
as well as select control functionality. The module was generated using \textit{wbgen2}~\cite{wbgen2}, but has
been adapted to allow for generating the read request to the tag buffer. It is the module which constrains
\textit{conv\_common\_gw} to a maximum of six pulse repetition channels, due to need of relative compatibility
to previously-released implementations of the \textit{conv\_regs} memory map.

Some of the bits in the converter board registers are set from inside the \textit{conv\_common\_gw}
module, but some are status bits that should be connected to external logic. Most of the bits implemented
as part of \textit{conv\_regs} are intended to be active-high logic, so adaptations for this should be made
in logic external to the \textit{conv\_common\_gw} when an external connection is needed.

The inputs that connect to bits in the status register are shown in Table~\ref{tbl:conv-regs-ext-inputs}.
Should some of these inputs not be used, such as for example the rear-panel failsafe lines in the case of
CONV-TTL-BLO~\cite{conv-ttl-blo-ohwr}, the corresponding lines should be connected to all-zeroes.

The \textit{g\_board\_id} and \textit{g\_gwvers} generics connect to registers in
\textit{conv\_regs} as shown in Figure~\ref{fig:bidr-gwvers}.

\begin{table}[h]
  \caption{\label{tbl:conv-regs-ext-inputs} Active-high inputs to converter board registers from external logic}
  \rowcolors{2}{white}{gray!25}
  \centerline {
    \begin{tabular}{l l p{.5\textwidth}}
      \hline
      \multicolumn{1}{c}{\textbf{Input port}} & \multicolumn{1}{c}{\textbf{Register}} & \multicolumn{1}{c}{\textbf{Description}} \\
      \hline
      sw\_gp\_i & SR.SWITCHES & General-purpose switch state \\
      rtmm\_i   & SR.RTM[2:0] & RTM Motherboard detection lines \\
      rtmp\_i   & SR.RTM[5:3] & RTM Piggyback detection lines \\
      line\_front\_i & LSR.FRONT & State of front-panel channel lines at FPGA input \\
      line\_inv\_i & LSR.FRONTINV & State of front-panel general-purpose inverter channels at FPGA input \\
      line\_rear\_i & LSR.REAR & State of rear-panel channel lines at FPGA input \\
      line\_front\_fs\_i & LSR.FRONTFS & State of front-panel channel failsafe lines at FPGA input \\
      line\_inv\_fs\_i & LSR.FRONTINVFS & State of front-panel general-purpose inverter failsafe lines at FPGA input \\
      line\_rear\_fs\_i & LSR.REARFS & State of rear-panel input failsafe lines (whether a cable is plugged in or not) \\
      sw\_other\_i & OSWR & State of other on-board switches \\
      \hline
    \end{tabular}
  }
\end{table}

\begin{figure}[h]
  \centerline{\includegraphics[width=.7\textwidth]{fig/bidr-gwvers}}
  \caption{\label{fig:bidr-gwvers} BIDR and SR.GWVERS connections}
\end{figure}

Some bits or fields inside \textit{conv\_regs} are generated based on the settings of
\textit{g\_with\_*} generics. Should such a generic set to \textit{false}, the corresponding
bits or fields in \textit{conv\_regs} are set to a 'safe' value of '0'. Consult the code
for details on how this is done and which are the fields concerned.

Note that the logic allows less than 6 pulse repetition channels, but not more.
If \textit{g\_nr\_chans $<$ 6}, then the rest of the bits are automatically set to '0',
as in the case a \textit{g\_with\_*} generic is \textit{false}. If \textit{g\_nr\_chans $>$ 6}
a synthesis error will be thrown.

\subsubsection{Fail-safe lines in the line status register}

The CONV-TTL-RS485~\cite{conv-ttl-rs485-ohwr} board has a an extra RS-485 transceiver per each
channel input and output line, dedicated to detecting whether a line is in a fault state, or whether
a cable is not plugged in.

This in RS-485 parlance is called the fail-safe state and half the bits in the
line status register (LSR -- see Appendix~\ref{app:conv-regs-lsr}) take their name after it. Designers of
future converter boards would implement similar features for all the inputs might want to implement a 
similar feature on future converter boards. For this, bits are provided in the LSR as shown in Table~\ref{tbl:conv-regs-ext-inputs}.
If no such feature exists, or if the feature is only implemented for one of the two panels (front or rear),
the non-used lines in Table~\ref{tbl:conv-regs-ext-inputs} can simply be connected to all-zeroes.

Note that the register limits the user to six pulse repetition channels and four general-purpose inverter
channels. Should more be needed, another \textit{conv\_common\_gw} module should be used, as shown in
Appendix~\ref{app:more-than-six-chans}.

%==============================================================================
\subsection{MultiBoot}
\label{subsec:multiboot}
%==============================================================================

The \textit{xwb\_xil\_multiboot} module from the \textit{general-cores} library~\cite{gencores-ohwr}
is used to provide MultiBoot functionality via I$^2$C. To find out more about the
module and how to use it, consult its documentation under the \textit{general-cores/doc/} folder.

%%==============================================================================
\subsection{One-wire temperature}
\label{subsec:onewire}
%%==============================================================================
The \textit{conv\_common\_gw} used a one-wire interface module (\textit{gc\_ds182x\_interface}) to the one-wire ds182x thermometer chip present on the board.  
The module requires the thermometer input \textit{thermometer\_b}, directly from the board plus a pps (pulse-per-second) signal (generated by \textit{wf\_decr\_counter} component). This interface outputs the chip unique ID as a 64-bit value, and the board temperature as a 16-bit value. These 2 values result in 3 memory mapped registers, 2, 32-bit registers for the chip ID, and 1 for the temperature. 
.
%%==============================================================================
%\subsection{One-wire master}
%\label{subsec:onewire}
%%==============================================================================
%
%Converter boards are expected to contain a DS18B20 thermometer chip~\cite{ds18b20},
%which can be used for monitoring the temperature of, and obtaining a unique
%identifier for the board.
%
%The one-wire master module provides two registers for software control of the module.
%Note that the FPGA does not control the one-wire thermometer lines in any way.
%Accessing the thermometer is done through software only.
%
%More details about how to access the one-wire master module can be found in its
%documentation~\cite{onewire-core}.

%==============================================================================
% Appendices
%==============================================================================
\pagebreak
\begin{appendices}

%==============================================================================
% APP: Memmap
%==============================================================================
\section{Memory map}
\label{app:memmap}

Table~\ref{tbl:memmap} shows the maximum memory map obtainable with the \textit{conv\_common\_gw}
module. This is obtained when the \textit{g\_nr\_chans} generic is set to the maximum value of
\textit{6}. Should less channels be desired, the higher-numbered registers for the channels
(e.g., CH5PCR and CH6PCR for \textit{g\_nr\_chans = 4}) can be considered as \textit{Reserved}
(read out as 0).

The following sections list the memory map of each peripheral.

\begin{table}[h]
\caption{\textit{conv\_common\_gw} memory map}
\label{tbl:memmap}
\centerline
{
  \rowcolors{2}{white}{gray!25}
  \begin{tabular}{l l l p{.4\textwidth}}
  \hline
  \multicolumn{1}{c}{\textbf{Peripheral}} & \multicolumn{2}{c}{\textbf{Address range}} & \multicolumn{1}{c}{\textbf{Description}} \\
  \hline
  Board registers & 0x000 & 0x0ff & Coverter board registers \\
  MultiBoot       & 0x100 & 0x11f & MultiBoot module \\
  %One-wire master & 0x200 & 0x2ff & One-wire master for DS18B20 thermometer module \\
  SDB descriptor  & 0xf00 & 0xfff & SDB descriptor (see~\cite{sdb}) \\
  \hline
  \end{tabular}
}
\end{table}

%%------------------------------------------------------------------------------
%% SUBSEC: conv-regs
%%------------------------------------------------------------------------------
\include{conv-regs}

%------------------------------------------------------------------------------
% SUBSEC: MultiBoot
%------------------------------------------------------------------------------
\include{multiboot-regs}

%------------------------------------------------------------------------------
% SUBSEC: Thermo
%------------------------------------------------------------------------------
%\subsection{Thermometer module}
%\label{app:memmap-thermo}
%
%\indent Base address: 0x200
%
%\vspace*{11pt}
%
%\centerline
%{
  %\rowcolors{2}{white}{gray!25}
  %\begin{tabular}{l l l p{.5\textwidth}}
  %\hline
  %\textbf{Offset} & \textbf{Default} & \textbf{Name} & \textbf{Description} \\
  %\hline
  %0x00            & 0x00000000       & OWCSR         & One-Wire Control and Status Register \\
  %0x04            & 0x00000004       & OWCDR         & One-Wire Clock Divider Registers \\
  %\hline
  %\end{tabular}
%}
%
%\vspace*{11pt}
%
%For details on the bits of the thermometer module access registers, see the
%OneWire Master module's documentation~\cite{onewire-core}.
%
%Note that the OWCDR should be set accordingly for proper functioning of the
%one-wire timings. The value for the current version of the gateware is
%\verb-OWCDR = 0x00130063-.

%==============================================================================
% APP: Changing the code for more than six pulse repetition channels
%==============================================================================
\pagebreak
\section{Gateware for pulse converters with more than six conversion channels}
\label{app:more-than-six-chans}

This appendix offers guidelines on how to use or change \textit{conv\_common\_gw}
should a pulse repeater with more than six channels be eventually implemented.
Note that the guidelines here have \textbf{not} been tested, since no board exists
with more than six channels at the time of writing of this document.

The first option is obviously instantiating more than one \textit{conv\_common\_gw}
component, each with its appropriate \textit{g\_nr\_chans} and making the appropriate connections
to the FPGA outputs. Note that each \textit{conv\_common\_gw} will
come with its own \textit{conv\_regs}, MultiBoot and one-wire master peripherals.
In this case, since it is expected that there is only one flash and thermometer
chip on-board, connect only the outputs of one of the \textit{conv\_common\_gw} modules
to the top-level module outputs, as shown in Figure~\ref{fig:more-than-six-chans}.
The synthesis tool should be smart enough to optimize away the unused modules.

\begin{figure}[h]
  \centerline{\includegraphics[width=\textwidth]{fig/more-than-six-chans}}
  \caption{\label{fig:more-than-six-chans} Connections to flash and thermometer with more than one \textit{conv\_common\_gw} modules}
\end{figure}

\pagebreak
The second, non-encouraged option, is to change the \textit{conv\_common\_gw} code.
Note that this will:

\begin{enumerate}
  \item Involve changing the memory map and \textit{conv\_regs} component,
  which will
  \item Make the \textit{conv\_common\_gw} module incompatible with the
  version described in this document
\end{enumerate}

If this option is chosen, the reader should start by changing the
\textit{c\_max\_nr\_chans} generic in the package file (\textit{conv\_common\_gw\_pkg.vhd}).
Then, a new memory map should be chosen and the \textit{conv\_regs} component
adapted as appropriate.

%==============================================================================
\end{appendices}
%==============================================================================

%==============================================================================
% Bibliography
%==============================================================================
\pagebreak
\bibliographystyle{ieeetr}
\bibliography{conv-common-gw}
\addcontentsline{toc}{section}{References}

\end{document}
