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

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

% Hyperrefs
\usepackage[
  colorlinks = true,
  linkcolor  = Mahogany,
  citecolor  = Mahogany,
  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
%------------------------------------------------------------------------------
\thispagestyle{empty}
\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
  04-07-2013 & 0.1 & First draft \\
  26-07-2013 & 0.2 & Second draft \\
  07-08-2013 & 1.02 & Added pulse rejection to \textit{conv\_pulse\_gen} \\
  14-08-2013 & 1.02 & Changed name of \textit{elma\_i2c} to \textit{vbcp\_wb} \\
  20-11-2013 & 1.04 & Added MultiBoot module, gateware release v1.0 \\
  14-02-2014 & 2.00 & Version 2.0 of gateware, with diagnostics support including: unique board ID
                      and temperature readout, input pulse counters, pulse time-tagging and
                      manual pulse triggering. \\
  08-04-2014 & 2.10 & Version 2.1 of gateware, bringing down the max. allowed input pulse frequency,
                      changing the ERR LED behaviour, adding system errors and changing the pulse
                      timetag FIFO for a timetag ring buffer \\
  \hline
  \end{tabular}
}

\pagebreak
\pagenumbering{roman}
\setcounter{page}{1}
\tableofcontents

%------------------------------------------------------------------------------
% List of figs, tables, abbrevs
%------------------------------------------------------------------------------
\listoffigures
\listoftables

\section*{List of Abbreviations}
\begin{tabular}{l l}
DAC    & Digital-to-Analog Converter \\
FPGA   & Field-Programmable Gate Array \\
FF     & Flip-Flop \\
FSM    & Finite-State Machine \\
IC     & Integrated Circuit \\
I$^2$C & Inter-Integrated Circuit (bus) \\
PLL    & Phase-Locked Loop \\
RTM    & Rear-Transition Module \\
RAM    & Random-Access Memory \\
SPI    & Serial Peripheral Interface \\
SysMon & (ELMA) System Montior \\
VCXO   & Voltage-controlled oscillator \\
WRPC   & White-Rabbit PTP Core \\
\end{tabular}

\pagebreak
\pagenumbering{arabic}
\setcounter{page}{1}

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

This document details the HDL implemented on the Spartan-6 FPGA on the CONV-TTL-BLO
board. The HDL (mostly implemented in VHDL) handles the following aspects of
the CONV-TTL-BLO capabilities:
\begin{itemize}
  \item pulse detection (on pulse rising edge)
  \item fixed-width pulse generation with pulse rejection
  \item diagnostics via I$^2$C
  \begin{itemize}
    \item converter board ID
    \item gateware version
    \item unique board ID and temperature readout
    \item state of on-board switches and RTM detection lines
    \item input pulse counters
    \item input pulse time-tagging
    \item manual pulse triggering
  \end{itemize}
  \item remote reprogramming via I$^2$C
\end{itemize}

Figure~\ref{fig:hdl-bd} shows a simplified block diagram of the HDL gateware. The
blocks in this figure implemented as part of the CONV-TTL-BLO gateware are presented
in the sections that follow.

\begin{figure}[h]
  \centerline{\includegraphics[width=.9\textwidth]{fig/hdl-bd}}
  \caption{Block diagram of FPGA gateware}
  \label{fig:hdl-bd}
\end{figure}

%------------------------------------------------------------------------------
% SUBSEC: Additional doc
%------------------------------------------------------------------------------
\subsection*{Additional documentation}

\begin{itemize}
  \item CONV-TTL-BLO User Guide \cite{ctb-ug}
  \item CONV-TTL-BLO Hardware Guide \cite{ctb-hwguide}
\end{itemize}

%==============================================================================
% SEC: Clocks
%==============================================================================
\pagebreak
\section{FPGA 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{Clock domains}
  \label{tbl:clocks}
  \centerline
  {
    \begin{tabular}{c c p{.6\textwidth}}
    \hline
    \textbf{Clock domain} & \textbf{Frequency} & \multicolumn{1}{c}{\textbf{Comments}} \\
    \hline
    \textit{clk\_20\_vcxo\_i} & 20~MHz  & Global clock input to all sequential logic. \\
    \textit{clk\_125}         & 125~MHz & Time-tagging logic and WR reference clock. \\
    \hline
    \end{tabular}
  }
\end{table}

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

This section details the various peripherals mapped on the internal
Wishbone bus. Access to these peripherals is made through the two serial lines
on the VME P1 connector (SERCLK, SERDAT). A protocol based on I$^2$C is used to
access these peripherals. The protocol, as well as the bridge component
translating I$^2$C accesses into Wishbone accesses, are defined in the bridge
component's documentation.

The complete memory map of the gateware can be found in Appendix~\ref{app:memmap}.

%------------------------------------------------------------------------------
% SUBSEC: Bridge
%------------------------------------------------------------------------------
\subsection{I$^2$C to Wishbone bridge}
\label{sec:i2c-bridge}

The \textit{wb\_i2c\_bridge} module implements a bridge to translate I$^2$C accesses
on the VME P1 connector into Wishbone accesses on the FPGA. The module provides
one I$^2$C slave interface for connecting to an ELMA SysMon and one Wishbone
master interface.

Details about the module's implementation can be found in its documentation.

%------------------------------------------------------------------------------
% SUBSEC: conv_regs
%------------------------------------------------------------------------------
\subsection{Converter board registers}
\label{sec:periphs-conv-regs}

A set of registers are implemented as general-purpose registers for converter boards.
These are status and control registers implemented utilizing \textit{wbgen2}~\cite{wbgen2}.
Appendix~\ref{app:conv-regs} presents the converter board registers.

On the status registers side, there is one general status register (SR -- see
Appendix~\ref{app:conv-regs-sr}) that contains details about the gateware version,
the state of the on-board switches and RTM detection lines, as well as the state
of the communication watchdog timer. Then, there are six pulse counter registers
(CHxPCR -- see Appendix~\ref{app:conv-regs}), one per each channel, which are updated
with the current values of the input pulse counters. These are followed by the
time-tagging logic (Section~\ref{sec:timetag}) registers.

The logic also contains one control register (CR -- see Appendix~\ref{app:conv-regs-cr}),
which contains two bits for remotely resetting the FPGA logic and six bits used by the
manual pulse triggering (Section~\ref{sec:man-trig}).


%------------------------------------------------------------------------------
% SUBSEC: MultiBoot
%------------------------------------------------------------------------------
\subsection{MultiBoot control}
\label{sec:periphs-multiboot}

The MultiBoot module offers the remote reprogramming capabilities for the
CONV-TTL-BLO board. It offers a set of registers for controlling writing a bitstream
to the M25P32 flash chip and for issuing the remote reprogramming command.

For information on the module, refer to its documentation. The memory map of the
module is also present in this manual, for quick reference (see
Appendix~\ref{app:multiboot-regs}).

%------------------------------------------------------------------------------
% SUBSEC: Onewire
%------------------------------------------------------------------------------
\subsection{One-wire master}
\label{sec:periphs-onewire}

The one-wire master provides access to the DS18B20 thermometer chip~\cite{ds18b20}
on the CONV-TTL-BLO. It provides two registers for software control of the module.

Note that the FPGA does not control the one-wire thermometer line 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}.

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

\centerline
{
  \begin{tabular}{l l l}
  \hline
  \textbf{Entity}   & \textit{reset\_gen}     & \\
  \textbf{Generics} & \textit{g\_reset\_time} & Reset time in \textit{clk\_i} cycles \\
  \textbf{Ports}    & \textit{clk\_i}         & Clock signal \\
                    & \textit{rst\_i}         & Active-high reset input \\
                    & \textit{rst\_n\_o}      & Active-low reset output \\
  \textbf{Usage}    & Global reset generation & 100~$ms$ reset \\
  \hline
  \end{tabular}
}

\vspace*{11pt}

The reset generator module (\textit{reset\_gen}) implemented inside the FPGA
generates a predefined-width reset signal when power is applied to the FPGA, or
when an external reset is triggered via the \textit{rst\_i} pin.

When a power-on reset occurs on the Xilinx FPGA, a counter inside the \textit{reset\_gen}
module starts counting up. While this counter is counting up, the active-low reset signal
is kept low, resetting synchronous logic inside the FPGA. When the counter reaches the
value of the reset width (specified via the \textit{g\_reset\_time} generic), the reset
signal is de-asserted, the counter is disabled and the \textit{reset\_gen}
module remains inactive.

The module reactivates on the power-on reset, or when a reset is triggered externally, via
the \textit{rst\_i} pin. The \textit{rst\_i} pin is tied in the design to the second bit
in the control register (CR -- see Appendix~\ref{app:conv-regs-cr}), which has to be first
unlocked by writing the RST\_UNLOCK bit. Both these registers are implemented in the
top-level file of the design.

Note that the VHDL of this module is Xilinx and XST-specific and porting to a different
FPGA architecture is not guaranteed to provide the same results. The \textit{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: Bicolor LEDs
%==============================================================================
\pagebreak
\section{Bicolor LED controller}
\label{sec:bicolor-led}

\centerline
{
  \begin{tabular}{l l l}
  \hline
  \textbf{Entity}   & \textit{bicolor\_led\_ctrl}      & \\
  \textbf{Generics} & \textit{g\_NB\_COLUMN}           & Number of columns \\
                    & \textit{g\_NB\_LINE}             & Number of lines \\
                    & \textit{g\_CLK\_FREQ}            & Frequency (in Hz) of \textit{clk\_i} signal \\
                    & \textit{g\_REFRESH\_RATE}        & LED refresh rate (in Hz)\\
  \textbf{Ports}    & \textit{rst\_n\_i}               & Active-low reset input \\
                    & \textit{clk\_i}                  & Clock signal input \\
                    & \textit{led\_intensity\_i(6..0)} & 7-bit LED intensity vector \\
                    & \textit{led\_state\_i(..)}       & LED state vector, two bits per LED \\
                    & \textit{column\_o(..)}           & LED column vector, one bit per column \\
                    & \textit{line\_o(..)}             & LED line vector, one bit per line \\
                    & \textit{line\_oen\_o(..)}        & LED line enable vector, one bit per line\\
  \textbf{Usage}    & Light bicolor LEDS               & \\
  \hline
  \end{tabular}
}


\vspace*{11pt}

The \textit{bicolor\_led\_ctrl} block controls the lighting of a bicolor
LED matrix. Based on the refresh rate given via the \textit{g\_REFRESH\_RATE}
generic, the clock frequency (\textit{g\_CLK\_FREQ} generic) and the number of
lines and columns, the module lights each LED in the LED matrix sequentially at
the refresh rate given by the user.

Figure~\ref{fig:bicolor-led} shows an example of controlling a three-line,
two-column red-and-green LED matrix. The FPGA ouputs for the columns~(C) are connected
to buffers and serial resistors and then to the LEDs. The FPGA outputs for lines~(L)
are connected to tri-state buffers and then to the LEDs. The FPGA outputs for line
output enables~(L\_OEN) are connected to the output enable of the tri-state buffers.

\begin{figure}[hbtp]
  \centerline{\includegraphics[width=\textwidth]{fig/bicolor-led}}
  \caption{3x2 bicolor LED matrix control}
  \label{fig:bicolor-led}
\end{figure}

The two-bit \textit{led\_state\_i} vector can be used to control the color of each
LED. Table~\ref{tbl:bicolor-led-state} lists the values that should be input on
\textit{led\_state\_i} to get the needed color, as well as constant definitions
provided in the \textit{bicolor\_led\_ctrl\_pkg.vhd} file for setting the color of the LED
via \textit{led\_state\_i}.

\begin{table}[h]
  \caption{LED state input}
  \label{tbl:bicolor-led-state}
  \centerline
  {
    \rowcolors{2}{white}{gray!25}
    \begin{tabular}{l l c}
    \hline
    \multicolumn{1}{c}{\textbf{State}} & \multicolumn{1}{c}{\textbf{Constant}} & \textbf{Value} \\
    \hline
    Off    & c\_LED\_OFF         & 00 \\
    Green  & c\_LED\_GREEN       & 01 \\
    Red    & c\_LED\_RED         & 10 \\
    Orange & c\_LED\_RED\_ORANGE & 11 \\
    \hline
    \end{tabular}
  }
\end{table}

Each LED's two-bit state is connected to \textit{led\_state\_i} on a column-first,
line-second basis.

%------------------------------------------------------------------------------
% SUBSEC: Board-level
%------------------------------------------------------------------------------
\subsection{Board-level view}
\label{sec:bicolor-led-brdlvl}

There are twelve bicolor LEDs on the CONV-TTL-BLO; they are connected in a two-line,
six-column pattern controlled by a \textit{bicolor\_led\_ctrl} block.
Table~\ref{tbl:bicolor-led-state-conn} shows the \textit{led\_state\_i} connections
for the bicolor status LEDs in the CONV-TTL-BLO gateware.

\begin{table}[h]
  \caption{LED state vector connections in the gateware}
  \label{tbl:bicolor-led-state-conn}
  \centerline
  {
    \rowcolors{2}{white}{gray!25}
    \begin{tabular}{l c l c}
    \hline
    \textbf{Line} & \textbf{Column} & \multicolumn{1}{c}{\textbf{LED}} &  \textbf{LED state bits} \\
    \hline
    1 & 1 & WHITE\_RABBIT\_ADDR & \textit{1..0}   \\
    1 & 2 & WHITE\_RABBIT\_GMT  & \textit{3..2}   \\
    1 & 3 & WHITE\_RABBIT\_LINK & \textit{5..4}   \\
    1 & 4 & WHITE\_RABBIT\_OK   & \textit{7..6}   \\
    1 & 5 & MULTICAST\_ADDR\_1  & \textit{9..8}   \\
    1 & 6 & MULTICAST\_ADDR\_2  & \textit{11..10} \\
    2 & 1 & I2C                 & \textit{13..12} \\
    2 & 2 & TTL                 & \textit{15..14} \\
    2 & 3 & ERR                 & \textit{17..16} \\
    2 & 4 & PW                  & \textit{19..18} \\
    2 & 5 & MULTICAST\_ADDR\_4  & \textit{21..20} \\
    2 & 6 & MULTICAST\_ADDR\_8  & \textit{23..22} \\
    \hline
    \end{tabular}
  }
\end{table}

The states of the used LEDs can be found in Table 1 of the CONV-TTL-BLO User
Guide~\cite{ctb-ug}. They are controlled by combinatorial multiplexers. The
selection signals to these multiplexers are set throughout the logic.

%==============================================================================
% SEC: Pulse gen
%==============================================================================
\pagebreak
\section{Pulse generator}
\label{sec:pulse-gen}

\centerline
{
  \begin{tabular}{l l l}
  \hline
  \textbf{Entity} & \textit{ctblo\_pulse\_gen} & \\
  \textbf{Generics} & \textit{g\_pwidth}           & Width of the output pulse in \textit{clk\_i} cycles \\
                    & \textit{g\_duty\_cycle\_div} & Duty cycle divider ratio \\
  \textbf{Ports} & \textit{clk\_i}           & Clock signal \\
                 & \textit{rst\_n\_i}        & Active-low reset signal \\
                 & \textit{en\_i}            & Pulse generator enable \\
                 & \textit{gf\_en\_n\_i}     & Active-low glitch filter enable \\
                 & \textit{trig\_a\_i}       & Pulse trigger \\
                 & \textit{pulse\_err\_p\_o} & Pulse error \\
                 & \textit{pulse\_o}         & Pulse output \\
  \textbf{Usage} & Output pulse              & 1.2~$\mu$s pulses with min. period of 6~$\mu$s \\
                 &                           & and one-cycle wide glitch filter \\
  \hline
  \end{tabular}
}

\vspace*{11pt}

The \textit{conv\_pulse\_gen} block generates pulses on the rising edge of the
\textit{trig\_a\_i} input. The pulse width is configurable via the \textit{g\_pwidth}
generic. The block also incorporates a glitch filter with a configurable length
(\textit{g\_gf\_len}) that can be used to avoid pulses generated because of
glitches at the \textit{trig\_a\_i} input.

Pulse widths at the output are limited internally to 1/5 duty cycle, to safeguard
the blocking output transformers.

Six \textit{conv\_pulse\_gen} blocks (one per channel) are used for generating blocking and TTL
pulses at the outputs, based on trigger inputs arriving on the channels. The \textit{conv\_pulse\_gen} blocks
are configured for 1.2~${\mu}$s pulses (\textit{g\_pwidth~=~24}, considering the 50~ns clock input).

%------------------------------------------------------------------------------
% SUBSEC: Implem
%------------------------------------------------------------------------------
\subsection{Implementation}
\label{sec:pulse-gen-implem}

Figure~\ref{fig:pulse-gen} shows the implementation of the \textit{conv\_pulse\_gen}
block. It employs a finite-state machine (FSM) that is used to generate
a fixed-width pulse at the output.

An external glitch filter (\textit{gc\_glitch\_filt} from the OHWR general-cores library)
can be enabled by the user by flipping SW1.1. Enabling this external glitch filter will mean
the input trigger is sampled with the 20~MHz clock prior to it being input to the glitch filter
(see Figure~\ref{fig:hdl-bd}).

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

Regardless of whether the glitch filter is enabled or not, the FSM reacts to the
rising edge of one of its two start inputs. A rising edge on an input starts
the internal counter, which counts up to a maximum value in order to assure a
pulse with the length \textit{g\_pwidth}. However, since the glitch filter adds a
delay to the input pules, the behavior of the outputs is different depending on whether
the filter is enabled or not.

With the glitch filter disabled, the input pulse enables the input flip-flop, which starts
pulse generation. The generated pulse signal is then synchronized in the \textit{clk\_20\_vcxo\_i}
domain and input to the synchronous FSM, which extends the pulse to the appropriate pulse width.
The rising edge on \textit{SGF0} triggers the counter, and when the counter reaches the value
corresponding to the selected pulse width, it sets the \textit{OGF0} output, which will reset
the input flip-flop, thus ending the pulse.

The output of the pulse-triggered flip-flop is fed into the synchronizer since this is guaranteed
to be a signal which is longer than two clock cycles, thus being detected by the FSM. Had the
trigger input been fed directly to the synchronization FFs, a shorter-than-one-cycle glitch would
trigger a pulse but not the synchronization FFs, and an output signal can potentially be extended
to a pulse length which is unsafe for the controlling MOSFET on the CONV-TTL-BLO board.

With the glitch filter enabled, the rising edge on \textit{SGF1} sets \textit{OGF1},
and this will be kept high until the counter reaches the value corresponding to the
pulse width. The input trigger signal is synchronized into the 20~MHz clock domain outside
the \textit{conv\_pulse\_gen} block, and is fed directly to the input of the FSM.

Before being fed to the FSM, however, the glitch-filtered signal is passed through a \textit{pulse
inhibit circuit}, which inhibits the first pulse when the board is in TTL-BAR repetition mode.
In this mode, an unconnected channel is always HIGH and until the
\textit{no signal detect} block outside the \textit{conv\_pulse\_gen} block (see the next
subsection) triggers, the continuous HIGH signal will trigger a pulse, due to the reset
state of the rising-edge detector on the FSM input.

After the pulse generation period, the FSM goes into a pulse rejection state,
where the pulse reset is kept high. If any pulses arrive on the input while the FSM
is in this rejection state, they are not replicated at the output. The pulse rejection
phase lasts for \textit{g\_duty\_cycle\_div}*\textit{g\_pwidth}, yielding a maximum duty
cycle of 1/\textit{g\_duty\_cycle\_div} for input pulses.

Should a pulse rising-edge arrive anywhere within the generation or rejection phase
in the FSM, the \textit{pulse\_err\_p\_o} output is set high for one clock cycle. This
signal can be used to, e.g., count the number of pulses that were rejected on a board. In
the actual top-level design, however, missed pulse counting is not implemented, the
\textit{pulse\_err\_p\_o} output simply asserts the SR.PMISSE bit (see
Appendix~\ref{app:conv-regs-sr}).

Note that due to the fact that the counter starts counting up from zero and delays
in the glitch filter when it is enabled, the maximum value of the internal counter is not
\textit{g\_pwidth}. Instead, the counter counts up to a pair of VHDL constants defined
in the code. These constants assure the pulse at the output is kept high for a number of
\textit{g\_pwidth} cycles of the \textit{clk\_i} signal.

%------------------------------------------------------------------------------
% SUBSEC: Board-level
%------------------------------------------------------------------------------
\subsection{Board-level view}
\label{sec:pulse-gen-brdlvl}

Figure~\ref{fig:pulse-brd} shows the pulse replication mechanism on the
CONV-TTL-BLO. Here, the \textit{PG} block is the \textit{conv\_pulse\_gen} block
with the necessary settings. This block can either be triggered via a pulse arriving
on the TTL or blocking channel, or by a manual trigger pulse arriving from the 
\textit{conv\_man\_trig} component (see Section~\ref{sec:man-trig}).

\begin{figure}[h]
  \centerline{\includegraphics[width=.9\textwidth]{fig/pulse-rep}}
  \caption{Board-level view of pulse replication mechanism}
  \label{fig:pulse-brd}
\end{figure}

Since the \textit{conv\_pulse\_gen} block expects a rising edge at its \textit{trig\_a\_i}
input in order to generate a pulse at the output, logic external to the block
caters for the different types of signals that arrive on CONV-TTL-BLO inputs.

Most of this external logic is on the TTL pulse side, where both TTL and TTL-BAR
pulses may arrive. As described in Section 4.3 of the CONV-TTL-BLO User Guide~\cite{ctb-ug},
if a wire is not plugged in when TTL-BAR pulses are input, a continuous logic high level
on the line would inhibit pulses arriving on the blocking side from triggering a pulse
generation. This is why the \textit{no signal detect} block has been implemented.

The block's implementation is shown in Figure~\ref{fig:no-sig-detect}. It is implemented as
a counter which keeps the \textit{en\_o} signal high as long as it does not reach its maximum value.
The counter counts up when the \textit{cnt} input is high. By setting the maximum value
of the counter to 1999, it disables the line to the multiplexer if this stays high
for 100~${\mu}s$, thus allowing for blocking pulses at the input of the OR gate. The line
is re-enabled as soon as it goes back low, i.e., when a wire has been plugged into the
channel.

\begin{figure}[h]
  \centerline{\includegraphics[width=.65\textwidth]{fig/no-sig-detect}}
  \caption{No signal detect block}
  \label{fig:no-sig-detect}
\end{figure}

Both the \textit{no signal detect} block and the glitch filter are generated
for each channel in the top-level VHDL file of the design.

%==============================================================================
% SEC: Pulse counters
%==============================================================================
\pagebreak
\section{Pulse counters}
\label{sec:pulse-cnt}

There are a total of six pulse counters implemented in the logic. Their
implementation is achieved via a single process -- \textit{p\_pulse\_cnt}.

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 through a rising edge detector. When
a rising edge occurs on the pulse, the counter is incremented by one and stored
to the channel pulse counter register (CHxPCR -- see Appendix~\ref{app:conv-regs})
register.

Note that this register is implemented outside of the \textit{conv\_regs} component,
since it is a read-write register. When the register is written by the \textit{conv\_regs}
component, the \textit{load} output is asserted and the register is loaded with
the value received via I$^2$C.

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

%==============================================================================
% SEC: Manual trigger
%==============================================================================
\pagebreak
\section{Manual pulse trigger}
\label{sec:man-trig}

\centerline
{
  \begin{tabular}{l l l}
  \hline
  \textbf{Entity} & \textit{conv\_man\_trig}        & \\
  \textbf{Generics} & \textit{g\_nr\_chan}          & Pulse repeater number of channels \\
                    & \textit{g\_gf\_len}           & Pulse generator glitch filter length \\
  \textbf{Ports} & \textit{clk\_i}                  & Clock signal \\
                 & \textit{rst\_n\_i}               & Active-low reset signal \\
                 & \textit{reg\_ld\_i}              & MPT in the CR written \\
                 & \textit{reg\_i}                  & Value of MPT field in the CR \\
                 & \textit{trig\_o}                 & Trigger output \\
  \textbf{Usage} & Trigger pulse generator & Two clock-cycle pulse output \\
  \hline
  \end{tabular}
}

\vspace*{11pt}

The manual pulse triggering mechanism is achieved via the \textit{conv\_man\_trig}
module. This module generates a pulse that is input to the \textit{conv\_pulse\_gen}
module and that triggers a 1.2~$\mu$s pulse on the TTL and blocking outputs.

Since manual pulse generation is a delicate feature which is only used when a debug
pulse is generated on a channel, a "password" is needed in order to manually trigger
a pulse. This "password" is obtained from the MPT field in the control register
(CR -- see Appendix~\ref{app:conv-regs-cr}), where a magic sequence of
numbers should be written. Once this magic sequence has been input, the next write to
the register should be the channel number. If a valid channel number is written,
a pulse is generated on this channel.

\begin{figure}[h]
  \centerline{\includegraphics[width=.6\textwidth]{fig/man-trig-fsm}}
  \caption{FSM of the \textit{conv\_man\_trig} component}
  \label{fig:man-trig-fsm}
\end{figure}

The \textit{conv\_man\_trig} takes the value of the MPT field in the control register
as an input and via the state-machine shown in Figure~\ref{fig:man-trig-fsm}, it checks
that the values written to the MPT field correspond to the magic sequence (Table~\ref{tbl:man-trig-magic}).
The FSM advances on writes to the MPT field of the CR. Once the magic sequence has been received,
the next write to the MPT field sets the \textit{trig\_o} output, which is input to the \textit{trig\_a\_i}
input of \textit{conv\_pulse\_gen} (see Section~\ref{sec:pulse-gen}) after it is ORed together with the
TTL and blocking inputs as shown in Figure~\ref{fig:pulse-brd}. Should an invalid channel number be
input, no error is reported and no pulse is generated.

\begin{table}[h]
  \caption{Magic sequence to initiate manual pulse triggering}
  \label{tbl:man-trig-magic}
  \centerline
  {
    \begin{tabular}{c c c c}
      \hline
      \textbf{Byte 0} & \textbf{Byte 1} & \textbf{Byte 2} & \textbf{Byte 3} \\
      \hline
      0xde & 0xad & 0xbe & 0xef \\
      \hline
    \end{tabular}
  }
\end{table}

To generate a long enough pulse to be detected by the \textit{conv\_pulse\_gen} component
when its glitch filter is enabled, the \textit{conv\_man\_trig} should have knowledge
of the length of the pulse generator's glitch filter, which can be supplied via the
\textit{g\_gf\_len} generic. With the value of this generic, the \textit{conv\_man\_trig}
component extends the \textit{trig\_o} pulse to the necessary number of cycles for the
\textit{conv\_pulse\_gen} to detect a pulse. This extension is done in the \textit{GEN}
state (Figure~\ref{fig:man-trig-fsm}).

%======================================================================================
% SEC: Pulse timetag
%======================================================================================
\pagebreak
\section{Pulse time-tagging}
\label{sec:timetag}

The time-tagging architecture is shown in Figure~\ref{fig:timetag-arch}. There are two
clock domains in the design. The time-tag controller and the time from the WRPC are both
in the 125~MHz clock domain, while the ring buffer is in both the 20~MHz clock domain and
the 125~MHz clock domain.

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

The timetag controller and ring buffer components are connected at the top-level. The outputs
of the ring buffer are connected directly to the \textit{conv\_regs} component at the top
level also.

%======================================================================================
% SUBSEC: Timetag controller
%======================================================================================
\subsection{Timetag controller}
\label{sec:timetag-ctrl}

The time-tag controller in Figure~\ref{fig:timetag-arch} is the \textit{conv\_pulse\_timetag}
VHDL component. It is designed to be connected directly to the ring buffer as shown above. As opposed
to what the simplified architecture above shows, the time-tag controller also implements the
local time counters.

\begin{figure}[h]
  \centerline{\includegraphics[width=\textwidth]{fig/timetag-core}}
  \caption{Timetag controller logic}
  \label{fig:timetag-core}
\end{figure}

The block's design is presented in Figure~\ref{fig:timetag-core}. This figure shows the functioning
when the \textit{conv\_pulse\_timetag} component is clocked from the 125~MHz clock, as is the case in the
converter board designs. Note however that the component can work with any clock rate by changing
the \textit{g\_clk\_rate} generic.

A free-running counter inside the block counts the ticks of the \textit{clk\_i} signal
to count the seconds. When it reaches the value \textit{g\_clk\_rate-1} (125~mega in
the figure), it resets and sends a "tick" to the TAI seconds counter, which then increments.

As seen in Figure~\ref{fig:hdl-bd}, the pulse inputs are derived from the OR gate which
ORs together the TTL and blocking inputs. Since these pulses can be asynchronous, they
are synchronized in the 125~MHz domain and passed through rising edge detectors. A rising
edge on any pulse channel triggers the \textit{buf\_wr\_req\_p\_o} signal. As the port's
name suggests, the \textit{buf\_wr\_req\_p\_o} signal is a one-cycle pulse that triggers
a write to the ring buffer.

All the output ports are connected externally directly to the ring buffer, therefore when the
\textit{buf\_wr\_req\_p\_o} output pulses, they are written to the ring buffer. As shown in
Figure~\ref{fig:timetag-arch}, the \textit{tm\_wpres\_o} signal is also reflected in the
board status register (SR -- see Appendix~\ref{app:conv-regs-sr}).

Note that due to the synchronization logic, rising edge detector and the latching of the
ORed pulse rising edge detection signal, the \textit{buf\_wr\_req\_p\_o} signal is
set between three and four cycles after the pulse signal actually arrives on the input.

Due to the two clock domains in the design, some synchronization logic is needed. This is
achieved via \textit{gc\_sync\_ffs} components from the \textit{general-cores}
library~\cite{gencores-ohwr} in the case of the WR time valid signals storage to the SR
and in the case of the TAI time value load pulses from the \textit{conv\_regs} to the
\textit{conv\_pulse\_timetag} components.

The TAI time signal is not synchronized before being connected to the \textit{conv\_regs}
component, since its rate of change of once per second is considered too slow to present
any problem of synchronization when read by the user.

%======================================================================================
% SUBSEC: Ring buffer
%======================================================================================
\subsection{Ring buffer}
\label{sec:timetag-ring-buf}

The mechanics of the ring buffer are presented in the \textbf{Ring buffer mechanics}
section of the CONV-TTL-BLO user guide~\cite{ctb-ug}. This section gives a few more details about the
implementation of the ring buffer, which can be found in the \textit{conv\_ring\_buf.vhd} file.

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

A high-level view of the implementation is shown in Figure~\ref{fig:timetag-ring-buf}.
This figure is oriented towards the converter board designs, but the ring buffer is
generic and can be used in other designs by properly instantiating it.

The ring buffer is implemented via a dual-clock, asynchronous FIFO, whose purpose is to
synchronize data between the read and write clock domains, a dual-port RAM clocked
with the read clock, and control logic for the buffer RAM. In the case of the converter
board designs, the write clock is the 125~MHz clock and the read clock is the 20~MHz clock.

The buffer control logic controls when the read and write pointers get incremented and
when the empty and full signals are set. The setting of the empty and full signals are
based on a buffer count signal, which gets incremented when a write is performed and the
buffer is not full, and decremented when a read is performed and the buffer is not empty.

%======================================================================================
% SEC: Folder structure
%======================================================================================
\pagebreak
\section{Folder structure}
\label{sec:fold-struct}

Gateware files are organized on a per type-of-project basis. There are two different types of
projects for CONV-TTL-BLO gateware: the \textit{release project} and \textit{test projects}.
The release project is the latest production gateware version, that goes on the CONV-TTL-BLO
board used in the field. Test projects are meant to be downloaded to a CONV-TTL-BLO for
testing the CONV-TTL-BLO system under long-term test conditions. The projects present in the
repository at the time of writing of this document are presented in Table~\ref{tbl:fold-struct-proj}.

\begin{table}[h]
  \caption{Gateware projects in the repository}
  \label{tbl:fold-struct-proj}
  \centerline
  {
  \rowcolors{2}{white}{gray!25}
  \begin{tabular}{l p{.6\textwidth}}
  \hline
  \multicolumn{1}{c}{\textbf{Project}} & \multicolumn{1}{c}{\textbf{Description}} \\
  \hline
  \textit{conv\_ttl\_blo} & Design-wide release project to be used in the field \\
  \textit{regtest}        & Long-term test for testing the I$^2$C communication by writing
                            to a RAM on the FPGA \\
  \textit{pulsetest}      & Long-term test for testing pulse repetition on the CONV-TTL-BLO \\
  \hline
  \end{tabular}
  }
\end{table}

The folder structure for the project is presented below.

\let \oldlabelitemi=\labelitemi
\let \oldlabelitemii=\labelitemii
\let \oldlabelitemiii=\labelitemiii
\let \oldlabelitemiv=\labelitemiv
\renewcommand{\labelitemi}{$\rightarrow$}
\renewcommand{\labelitemii}{$\rightarrow$}
\renewcommand{\labelitemiii}{$\rightarrow$}
\renewcommand{\labelitemiv}{$\rightarrow$}

\begin{itemize}
  \item conv-ttl-blo-gw/
  \begin{itemize}
    \item doc/
    \begin{itemize}
      \item hdlguide/
    \end{itemize}
    \item ip\_cores/
    \begin{itemize}
      \item general-cores/
    \end{itemize}
    \item modules/
    \begin{itemize}
      \item Release/
      \begin{itemize}
        \item conv\_man\_trig.vhd
        \item conv\_regs.vhd
        \item conv\_regs.wb
        \item conv\_pulse\_timetag.vhd
        \item ctblo\_pulse\_gen.vhd
      \end{itemize}
      \item pulsetest/
      \begin{itemize}
        \item pulse\_gen\_gp.vhd
        \item {[}...{]}
      \end{itemize}
      \item conv\_pulse\_gen.vhd
      \item reset\_gen.vhd
    \end{itemize}
    \item sim/
    \item syn/
    \begin{itemize}
      \item Release/
      \item pulsetest/
      \item regtest/
    \end{itemize}
    \item top/
    \begin{itemize}
      \item Release/
      \begin{itemize}
        \item conv\_ttl\_blo.ucf
        \item conv\_ttl\_blo.vhd
      \end{itemize}
      \item pulsetest/
      \begin{itemize}
        \item pulsetest.ucf
        \item pulsetest.vhd
      \end{itemize}
      \item regtest/
      \begin{itemize}
        \item regtest.ucf
        \item regtest.vhd
      \end{itemize}
    \end{itemize}
  \end{itemize}
\end{itemize}

\renewcommand{\labelitemi}{\oldlabelitemi}
\renewcommand{\labelitemii}{\oldlabelitemii}
\renewcommand{\labelitemiii}{\oldlabelitemiii}
\renewcommand{\labelitemiv}{\oldlabelitemiv}

\begin{table}[h]
  \caption{Folder structure}
  \label{tbl:fold-struct}
  \centerline
  {
    \rowcolors{2}{white}{gray!25}
    \begin{tabular}{l p{.7\textwidth}}
    \hline
    \multicolumn{1}{c}{\textbf{Folder}} & \multicolumn{1}{c}{\textbf{Description}} \\
    \hline
    doc/       & Documentation files \\
    ip\_cores/ & IP cores used in the design \\
    modules/   & Project-specific modules instantiated in the top-level design \newline
                 Organized on a project type basis \\
    sim/       & Module simulation files \\
    syn/       & ISE project file and synthesis output files, including binaries to
                 download to the FPGA \newline
                 Organized on a project type basis \\
    top/       & Top-level .vhd and .ucf files \newline
                 Organized on a project type basis \\
    \hline
    \end{tabular}
  }
\end{table}

As can be seen from the folder structure above, gateware files are organized in the
\textit{modules/}, \textit{syn/} and \textit{top/} folders following this project convention.
Files in these folders (where relevant) are organized in the \textit{Release/}, \textit{pulsetest/}
and \textit{regtest/} folders, where the \textit{Release/} folder of course represents the
release gateware and the other two are test projects, as their names suggest.

One place where the project structure is not necessarily enforced is the \textit{sim/} folder.
This folder is meant to contain files relevant for simulation of various modules within
the design and as such can be composed of folders named after the component to be simulated.

%======================================================================================
% SEC: Getting Around the Code
%======================================================================================
\pagebreak
\section{Getting around the code}
\label{sec:get-around}

Ports and signals usually follow the coding guideline at~\cite{coding-guidelines}. Most of the
top-level ports of the gateware are lower-case versions of their schematics counterparts. The
exceptions from this are due to either net names that could not be syntactically represented in
VHDL, or net names that have been made clearer in VHDL code.

\begin{figure}[h]
  \centerline{\includegraphics[width=.6\textwidth]{fig/arch}}
  \caption{VHDL architecture of the release gateware}
  \label{fig:arch}
\end{figure}

Code in the top-level files is organized in code sections. A code section is a piece of code
pertaining to a certain part of the design, where component instantiations and input and
output port assignments are made. For example, there is a section pertaining to
pulse repetition, where there is a generate block to generate the logic necessary for pulse
repetition on each channel, including the pulse status LEDs.

The VHDL architecture of the top-level file of the release gateware is shown
in Figure~\ref{fig:arch}. Table~\ref{tbl:arch} lists the code sections of the
top-level file.

{
\rowcolors{2}{white}{gray!25}
\begin{longtable}{p{.25\textwidth} p{.65\textwidth}}
  \caption{Code sections in the FPGA gateware}
  \label{tbl:arch} \\

    % FIRST HEADER %
    \hline
    \multicolumn{1}{c}{\textbf{Code section}} & \multicolumn{1}{c}{\textbf{Description}} \\
    \hline
    \endfirsthead

    % OTHER HEADERS %
    \hline
    \multicolumn{1}{c}{\textbf{Code section}} & \multicolumn{1}{c}{\textbf{Description}} \\
    \hline
    \endhead

    % FOOTERS %
    \hline
    \endfoot

    % TABLE CONTENTS %
    Reset logic   & -- \textit{reset\_gen} instantiation \\
    I$^2$C bridge & -- \textit{wb\_i2c\_bridge} instantiation \newline
                    -- logic for blinking the I2C bicolor LED on the front panel \newline
                    -- generate the CWDTO bit register \\
    Converter boards
    registers     & -- \textit{conv\_regs} instantiation \newline
                    -- connect the switch lines to the SR \newline
                    -- connect the RTM detection lines to the SR \newline
                    -- implement the RST, RST\_UNLOCK and WRPRES bit registers \\
    Channel logic & -- connect inputs to internal signals \newline
                    -- instantiation of the pulse time-tagging controller and
                    manual pulse trigger components\newline\newline
                    VHDL \textit{generate} statements then generate the
                    channel logic: \newline
                    -- glitch filters and selection between filtered and non-filtered
                    based on the glitch filter selection switch \newline
                    -- synchronization flip-flops on the input signals \newline
                    -- input pulse counter logic \newline
                    -- no signal detect block (Figure~\ref{fig:no-sig-detect}) \newline
                    -- \textit{conv\_pulse\_gen} instantiation \newline
                    -- pulse output connections \newline
                    -- process to light pulse LEDs on pulse output \\
    MultiBoot logic & -- \textit{wb\_xil\_multiboot} instantiation \\
    Status LEDs     & -- \textit{bicolor\_led\_ctrl} instantiation \newline
                      -- connecting the \textit{led\_state\_i} input of the
                      component to the relevant control signals \\
\end{longtable}
}  % end rowcolors

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

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

Table~\ref{tbl:memmap} shows the complete memory map of the gateware. The
following sections list the memory map of each peripheral.

In order to convert address values to register index values for SNMP access,
the following formula should be used:

\begin{center}
$reg. index = \frac{addr}{4} + 1$
\end{center}

\begin{table}[h]
\caption{CONV-TTL-BLO 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 & 0x020 & Coverter board registers \\
  MultiBoot       & 0x040 & 0x050 & MultiBoot module \\
  Thermometer     & 0x080 & 0x084 & Thermometer chip \\
  \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: 0x080

\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-.

%------------------------------------------------------------------------------
\end{appendices}
%------------------------------------------------------------------------------

%==============================================================================
% Bibliography
%==============================================================================
\pagebreak
\bibliographystyle{ieeetr}
\bibliography{hdlguide-conv-ttl-blo}

\end{document}
