Newer
Older
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
\begin{figure}[h]
\centering%
\includegraphics[width=100mm]{img/sdb-synthesis.ps}
\caption{The Synthesis Structure}
\label{fig:FigureSynthesis}
\end{figure}
\begin{center}
\begin{savenotes}
\begin{table}[!ht]\footnotesize
\caption{SDB Synthesis Record (64 bytes, type 0x82)}\label{sdb_synthesis}\centering
\begin{tabular}{| c | c | c | l | c | p{5cm} |} \hline
First & Last & Size & Name & Value & Description \\ \hline
0x00 & 0x0f & 16 & syn\_name & - & Name of this project/synthesis \\ \hline
0x10 & 0x1f & 16 & commit\_id & - & Identifier of the build commit \\ \hline
0x20 & 0x27 & 8 & tool\_name & - & Name of the synthesis tool \\ \hline
0x28 & 0x2b & 4 & tool\_version & - & Version of the synthesis tool \\ \hline
0x2c & 0x2f & 4 & date & - & Date of synthesis \\ \hline
0x30 & 0x3e & 15 & user\_name & - & Name of the user who did the synthesis \\ \hline
0x3f & 0x3f & 1 & record\_type & 0x82 & Type of this record \\ \hline
\end{tabular}
\end{table}
\end{savenotes}
\end{center}
\begin{description}
\item[syn\_name] \hfill \\
This a string, encoded in UTF-8, with trailing spaces and no terminating 0;
it should represent a human-readable name for this synthesis. Like all other
fields in this structures, it is meant to be useful for the designers, to help
tracking what is currently installed in the various systems. Thus, this may
be a generic name of the project or a more specific string, according to local
needs.
\item[commit\_id] \hfill \\
This field represents the binary identifier of the top-level commit used
to build this gateware image. If the identifier is more than 128 bits long
(e.g., \textit{git}), the field includes the leading bits. If the commit ID is numeric
(e.g., SVN), the representation is bit-endian binary. For repositories using
non-binary version numbers, the representation is let to the ingenuity of the
developer, to properly convey the informations. For example, a CVS version
like ``1.20.1.4'' can either be ASCII-encoded or represented as 4 32-bit big-endian
fields. Clearly, the commit\_id field raises a ``chicken-and-egg'' problem: once
you commit the change, your commit identifier changes, maybe in unpredictable
ways. Representing the ``previous'' commit, and then committing and sdb-only
change is a sensible workaround. The filed \textbf{should} be 0 if not used.
\item[tool\_name] \hfill \\
This a string, encoded in UTF-8, with trailing spaces and no terminating 0;
it represents a human-readable name for the synthesis tool used to build this
very binary gateware file.
\item[tool\_version] \hfill \\
The version of the synthesis tool, in a human-readable way. For example,
it can be used as two 16-bit fields, but this really depends on how the specific
tool names its versions.
\item[date] \hfill \\
The date of synthesis. This \textbf{must} be either 0 (unspecified) or a 32-bit hex
format number in the format 0xYYYYMMDD. For example, 0x20130327.
\item[user\_name] \hfill \\
This a string, encoded in UTF-8, with trailing spaces and no terminating 0;
it states who is the user who built the binary gateware. This name is expected
to be unique among the development group, so a Unix username or a nickname are good
choices that fit the allowed space of 15 bytes.
\item[record\_type] \hfill \\
The record type for this structures is 0x82.
\end{description}
\section{Simple Real-World Examples}
This section shows the details of the simplest real-world example of an SDB array,
and an overlook of a more structured device.
\subsection{Simple Binary Data}
The FPGA binary used as the simplest example is the \textit{boot} image to be
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
programmed in the SPEC cards
(\texttt{http://www.ohwr.org/projects/spec}); it only includes the
\textit{syscon} device, which allows generic access to the FMC
mezzanine card.
The following binary dump appears at offset 0x100 of the memory window
that maps to the programmable device:
\footnotesize
\begin{verbatim}
000000 53 44 42 2d 00 02 01 00 00 00 00 00 00 00 00 00 >SDB-............<
000010 00 00 00 00 00 00 01 ff 00 00 00 00 00 00 06 51 >...............Q<
000020 e6 a5 42 c9 00 00 00 02 20 12 05 11 57 42 34 2d >..B..... ...WB4-<
000030 43 72 6f 73 73 62 61 72 2d 47 53 49 20 20 20 00 >Crossbar-GSI .<
000040 00 00 01 01 00 00 00 07 00 00 00 00 00 00 00 00 >................<
000050 00 00 00 00 00 00 00 ff 00 00 00 00 00 00 ce 42 >...............B<
000060 ff 07 fc 47 00 00 00 01 20 12 03 05 57 52 2d 50 >...G.... ...WR-P<
000070 65 72 69 70 68 2d 53 79 73 63 6f 6e 20 20 20 01 >eriph-Syscon .<
\end{verbatim}
\normalsize
\subsection{Parsing the Data}
This is the suggested parsing sequence for the data shown above. The
parsing code is assumed to know where the data structure is expected to live.
\begin{itemize}
\item The parser verifies the magic number 0x5344422D at offset 0.
\item The type byte of 0x00 at offset 0x3f confirms this is an \textit{interconnect} record.
\item The SDB version, at offset 6, confirms this is version 1 and we can parse it.
\item By reading the 16-bit field at position 04-05, we know this is an array of two items.
\item The second item is of type \textit{device} (type 0x01).
\end{itemize}
What follows is the split-out view of the two structures:
\footnotesize
\begin{verbatim}
Interconnect:
0x00: 53 44 42 2d (Magic "SDB-")
0x04: 00 02 (Number of records)
0x06: 01 (SDB version)
0x07: 00 (Bus type: wishbone)
0x08: 00 00 00 00 00 00 00 00 (First address)
0x10: 00 00 00 00 00 00 01 ff (Last address)
0x18: 00 00 00 00 00 00 06 51 (Vendor: GSI)
0x20: e6 a5 42 c9 (Device)
0x24: 00 00 00 02 (Version)
0x28: 20 12 05 11 (Date: 11th May 2012)
0x2c: "WB4-Crossbar-GSI " (Name)
0x3f: 00 (Type: interconnect)
Device:
0x00: 00 00 (ABI class)
0x02: 01 (ABI version major)
0x03: 01 (ABI version minor)
0x04: 00 00 00 07 (Bus-specific: BE, 8,16,32 bits)
0x08: 00 00 00 00 00 00 00 00 (First address)
0x10: 00 00 00 00 00 00 00 ff (Last address)
0x18: 00 00 00 00 00 00 ce 42 (Vendor: CERN)
0x20: ff 07 fc 47 (Device)
0x24: 00 00 00 01 (Version)
0x28: 20 12 03 05 (Date: 5th March 2012)
0x2c: "WR-Periph-Syscon " (Name)
0x3f: 01 (Type: device)
\end{verbatim}
\normalsize
The previous dump shows how the vendor identifiers in this case have
been allocated in the globally-assigned space, while device identifiers
are pseudo-random numbers, in charge of the respective vendor.
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
\subsection{A More Structured Device}
The following is the output of \texttt{eb-ls}, and \textit{Etherbone}
tool, when run over a complex White Rabbit device. This output
comes from scanning the SDB structures:
\footnotesize
\begin{verbatim}
root@scul007:~# eb-ls dev/pcie_wb0
BusPath VendorID Product Base(Hex) Description
1 000000000000ce42:66cfeb52 0 WB4-BlockRAM
2 0000000000000651:eef0b198 100000 WB4-Bridge-GSI
2.1 0000000000000651:35aa6b95 100000 GSI_GPIO_32
2.2 0000000000000651:8752bf44 140000 GSI_ECA_UNIT
2.3 0000000000000651:10051981 180000 GSI_TM_LATCH
3 0000000000000651:eef0b198 200000 WB4-Bridge-GSI
3.1 000000000000ce42:66cfeb52 200000 WB4-BlockRAM
3.2 0000000000000651:eef0b198 220000 WB4-Bridge-GSI
3.2.1 000000000000ce42:ab28633a 220000 WR-Mini-NIC
3.2.2 000000000000ce42:650c2d4f 220100 WR-Endpoint
3.2.3 000000000000ce42:65158dc0 220200 WR-Soft-PLL
3.2.4 000000000000ce42:de0d8ced 220300 WR-PPS-Generator
3.2.5 000000000000ce42:ff07fc47 220400 WR-Periph-Syscon
3.2.6 000000000000ce42:e2d13d04 220500 WR-Periph-UART
3.2.7 000000000000ce42:779c5443 220600 WR-Periph-1Wire
3.2.8 000000000000ce42:779c5443 220700 WR-Periph-1Wire
\end{verbatim}
\normalsize
\subsection{Endianness Problems}
Please note that the host may have some issues reading the binary
dumps. According to how the bridge between the host and FPGA is
designed you may face one of the following situations:
\begin{itemize}
\item The host is big-endian (data is always correct).
\item The host is little-endian and the bridge is byte-oriented.
\item The host is little-endian and the bridge is word-oriented.
\end{itemize}
If the bridge is byte-oriented, i.e. each and every byte can be
independently addressed as such, then the usual endian conversion
rules apply (e.g. you can \textit{memcpy} the records to host memory
and access fields with endian-aware code).
If the bridge is word-oriented, with 32-bit words in this example, the behaviour is stranger, in
a way. After you copied the data to host memory (whether one byte at
a time or not), you'll find that the bytes are swapped within each word.
This happens because the 32-bit word is transferred as a whole: the least significant
bits remain the the least significant, but they come from offset 3 in the data structure
and are stored at offset 0 in the little-endian host. If this is your case, you need to
byte-swap each 32-bit word before using the structure in a
little-endian host. After such swapping, the data fields live at the correct
offsets and must be accessed as big endian.
\subsection{Existing Tools}
As part of the \textit{Etherbone} project, you already find a number
of tools that work with SDB structures (including \texttt{eb-ls} that
printed the table of devices shown above). The project is at
\texttt{http://www.ohwr.org/projects/etherbone-core} .
% LocalWords: metadata FPGA gateware CERN