OpenCores
URL https://opencores.org/ocsvn/lxp32/lxp32/trunk

Subversion Repositories lxp32

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /lxp32/trunk
    from Rev 2 to Rev 6
    Reverse comparison

Rev 2 → Rev 6

/.gitattributes
1,2 → 1,5
# Convert line endings for text files on Windows
* text=auto
 
# Prevent the GitHub parser from ignoring the "tools" directory contents
/tools/* linguist-vendored=false
/LICENSE.md
1,4 → 1,4
Copyright (c) 2016 by Alex I. Kuznetsov
Copyright (c) 2016-2019 by Alex I. Kuznetsov
 
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
 
/doc/lxp32-trm.pdf Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
/doc/src/trm/frontmatter.tex
15,7 → 15,7
\Large a lightweight open source 32-bit CPU core\par
\LARGE \textbf{Technical Reference Manual}\par
\vspace{1.2\onelineskip}
\large Version 1.0\par
\large Version 1.1\par
\vspace*{4\onelineskip}
\end{center}
\vspace*{\fill}
34,7 → 34,7
 
\vspace*{\fill}
 
Copyright \textcopyright{} 2016 by Alex I. Kuznetsov.
Copyright \textcopyright{} 2016--2019 by Alex I. Kuznetsov.
 
The entire \lxp{} IP core package, including the synthesizable RTL description, verification environment, documentation and software tools, is distributed under the terms of the MIT license reproduced below:
 
46,8 → 46,6
 
\vspace{4\baselineskip}
 
Altera and Cyclone are trademarks of Altera Corporation and registered in the U.S. Patent and Trademark Office and in other countries.
 
Mentor Graphics and ModelSim are trademarks of Mentor Graphics Corporation.
 
Microsemi and IGLOO are trademarks of Microsemi Corporation.
/doc/src/trm/lxp32-trm.tex
16,26 → 16,18
\lxp{} (\emph{Lightweight eXecution Pipeline}) is a small 32-bit CPU IP core optimized for FPGA implementation. Its key features include:
 
\begin{itemize}
\item described in portable VHDL-93, not tied to any particular vendor;
\item 3-stage pipeline;
\item portability (described in behavioral VHDL-93, not tied to any particular vendor);
\item 3-stage hazard-free pipeline;
\item 256 registers implemented as a RAM block;
\item simple instruction set with less than 30 distinct opcodes;
\item a simple instruction set with only 30 distinct opcodes;
\item separate instruction and data buses, optional instruction cache;
\item WISHBONE compatible;
\item WISHBONE compatibility;
\item 8 interrupts with hardwired priorities;
\item optional divider.
\end{itemize}
 
Being a lightweight IP core, \lxp{} also has certain limitations:
As a lightweight CPU core, \lxp{} lacks some features of more advanced processors, such as nested interrupt handling, debugging support, floating-point and memory management units. \lxp{} is based on an original ISA (Instruction Set Architecture) which does not currently have a C compiler. It can be programmed in the assembly language covered by Appendix \ref{app:assemblylanguage}.
 
\begin{itemize}
\item no branch prediction;
\item no floating-point unit;
\item no memory management unit;
\item no nested interrupt handling;
\item no debugging facilities.
\end{itemize}
 
Two major hardware versions of the CPU are provided: \lxp{}U which does not include an instruction cache and uses the Low Latency Interface (Section \ref{sec:lli}) to fetch instructions, and \lxp{}C which fetches instructions over a cached WISHBONE bus protocol. These versions are otherwise identical and have the same instruction set architecture.
 
\section{Implementation estimates}
58,33 → 50,23
\toprule
Resource & Compact & Full \\
\midrule
\multicolumn{3}{c}{Altera\textregistered{} Cyclone\textregistered{} V 5CEBA2F23C8} \\
\midrule
Logic Array Blocks (LABs) & 79 & 119 \\
\hspace*{1em}ALMs & 630 & 972 \\
\hspace*{2em}ALUTs & 982 & 1531 \\
\hspace*{2em}Flip-flops & 537 & 942 \\
DSP blocks & 3 & 3 \\
RAM blocks (M10K) & 2 & 3 \\
Clock frequency & 103.9 MHz & 98.8 MHz \\
\midrule
\multicolumn{3}{c}{Microsemi\textregistered{} IGLOO\textregistered{}2 M2GL005-FG484} \\
\midrule
Logic elements (LUT+DFF) & 1529 & 2226 \\
\hspace*{1em}LUTs & 1471 & 2157 \\
\hspace*{1em}Flip-flops & 718 & 1181 \\
Logic elements (LUT+DFF) & 1457 & 2086 \\
\hspace*{1em}LUTs & 1421 & 1999 \\
\hspace*{1em}Flip-flops & 706 & 1110 \\
Mathblocks (MACC) & 3 & 3 \\
RAM blocks (RAM1K18) & 2 & 3 \\
Clock frequency & 111.7 MHz & 107.8 MHz \\
Clock frequency & 107.7 MHz & 109.2 MHz \\
\midrule
\multicolumn{3}{c}{Xilinx\textregistered{} Artix\textregistered{}-7 xc7a15tfgg484-1} \\
\midrule
Slices & 264 & 381 \\
\hspace*{1em}LUTs & 809 & 1151 \\
\hspace*{1em}Flip-flops & 527 & 923 \\
Slices & 235 & 365 \\
\hspace*{1em}LUTs & 666 & 1011 \\
\hspace*{1em}Flip-flops & 528 & 883 \\
DSP blocks (DSP48E1) & 4 & 4 \\
RAM blocks (RAMB18E1) & 2 & 3 \\
Clock frequency & 113.6 MHz & 109.3 MHz \\
Clock frequency & 111.9 MHz & 120.2 MHz \\
\bottomrule
\end{tabularx}
\end{table}
93,9 → 75,9
 
General description of the \lxp{} operation from a software developer's point of view can be found in Chapter \ref{ch:isa}, \styledtitleref{ch:isa}. Future versions of the \lxp{} CPU are intended to be at least backwards compatible with this architecture.
 
Topics related to hardware, such as synthesis, implementation and interfacing other IP cores, are covered in Chapter \ref{ch:integration}, \styledtitleref{ch:integration}. The \lxp{} IP core package also includes testbenches which can be used to simulate the design as described in Chapter \ref{ch:simulation}, \styledtitleref{ch:simulation}.
Topics related to hardware, such as synthesis, implementation and interfacing other IP cores, are covered in Chapter \ref{ch:integration}, \styledtitleref{ch:integration}. A brief description of the \lxp{} pipelined architecture is provided in Chapter \ref{ch:pipeline}, \styledtitleref{ch:pipeline}. The \lxp{} IP core package includes a verification environment (self-checking testbench) which can be used to simulate the design as described in Chapter \ref{ch:simulation}, \styledtitleref{ch:simulation}.
 
Tools shipped as parts of the \lxp{} IP core package (assembler/linker, disassembler and interconnect generator) are documented in Chapter \ref{ch:developmenttools}, \styledtitleref{ch:developmenttools}.
Documentation for tools shipped with the \lxp{} IP core package (assembler/linker, disassembler and interconnect generator) is provided in Chapter \ref{ch:developmenttools}, \styledtitleref{ch:developmenttools}.
 
Appendices include a detailed description of the \lxp{} instruction set, instruction cycle counts and \lxp{} assembly language definition. WISHBONE datasheet required by the WISHBONE specification is also provided.
 
207,15 → 189,16
\section{Calling procedures}
\label{sec:callingprocedures}
 
\lxp{} provides a \instr{call} instruction which stores the address of the next instruction in the \code{rp} register and transfers execution to the procedure pointed by \instr{call} operand. Return from a procedure is performed by \code{\instr{jmp} rp} instruction which also has \instr{ret} alias.
\lxp{} provides a \instr{call} instruction which saves the address of the next instruction in the \code{rp} register and transfers execution to the address stored in the register operand. Return from a procedure is performed by the \code{\instr{jmp} rp} instruction which also has a \instr{ret} alias.
 
If a procedure must in turn call some procedure itself, the return pointer in the \code{rp} register will be overwritten by the \instr{call} instruction. Hence the procedure must save its value somewhere; the most general solution is to use the stack:
If a procedure must in turn call a nested procedure itself, the return address in the \code{rp} register will be overwritten by the \instr{call} instruction. Hence, unless it is a tail call (see below), the procedure must save the \code{rp} value somewhere; the most general solution is to use the stack:
 
\begin{codepar}
\instr{sub} sp, sp, 4
\instr{sw} sp, rp
...
\instr{call} r1
\instr{lc} r0, Nested_proc
\instr{call} r0
...
\instr{lw} rp, sp
\instr{add} sp, sp, 4
222,16 → 205,25
\instr{ret}
\end{codepar}
 
Procedures that don't use the \instr{call} instruction (sometimes called \emph{leaf} procedures) don't need to save the \code{rp} value.
Procedures that don't use the \instr{call} instruction (sometimes called \emph{leaf procedures}) don't need to save the \code{rp} value.
 
Since \instr{ret} is just an alias for \code{\instr{jmp} rp}, one can also use \instrname{Compare and Jump} instructions (\instr{cjmp\emph{xxx}}) to perform a conditional procedure return.
Since \instr{ret} is just an alias for \code{\instr{jmp} rp}, one can also use \instrname{Compare and Jump} instructions (\instr{cjmp\emph{xxx}}) to perform a conditional procedure return. For example, consider the following procedure which calculates the absolute value of \code{r1}:
 
\begin{codepar}
Abs_proc:
\instr{cjmpsge} rp, r1, 0 \emph{// return immediately if r1>=0}
\instr{neg} r1, r1 \emph{// otherwise, negate r1}
\instr{ret} \emph{// jmp rp}
\end{codepar}
 
A \emph{tail call} is a special type of procedure call where the calling procedure calls a nested procedure as the last action before return. In such cases the \instr{call} instruction can be replaced with \instr{jmp}, so that when the nested procedure executes \instr{ret}, it returns directly to the caller's parent procedure.
 
Although the \lxp{} architecture doesn't mandate any particular calling convention, some general recommendations are presented below:
 
\begin{enumerate}
\item Pass arguments through the \code{r1}--\code{r31} registers.
\item Return value through the \code{r0} register.
\item Designate \code{r0}--\code{r31} registers as \emph{caller-saved}, that is, they are not guaranteed to be preserved during procedure calls and must be saved by the caller if needed. The procedure can use them for any purpose, regardless of whether they are used to pass arguments and/or return values. For obvious reasons, this rule does not apply to interrupt handlers.
\item Pass arguments and return values through the \code{r1}--\code{r31} registers (a procedure can have multiple return values).
\item If necessary, the \code{r0} register can be used to load the procedure address.
\item Designate \code{r0}--\code{r31} registers as \emph{caller-saved}, that is, they are not guaranteed to be preserved during procedure calls and must be saved by the caller if needed. The procedure can use them for any purpose, regardless of whether they are used to pass arguments and/or return values.
\end{enumerate}
 
\section{Interrupt handling}
269,21 → 261,24
 
Interrupt handlers are invoked by the CPU similarly to procedures (Section \ref{sec:callingprocedures}), the difference being that in this case return address is stored in the \code{irp} register (as opposed to \code{rp}), and the least significant bit of the register (\code{IRF} -- \emph{Interrupt Return Flag}) is set.
 
An interrupt handler returns using the \code{\instr{jmp} irp} instruction which also has \instr{iret} alias. Until the interrupt handler returns, the CPU will defer further interrupt processing (although incoming interrupt requests will still be registered). This also means that \code{irp} register value will not be unexpectedly overwritten. When executing the \code{\instr{jmp} irp} instruction, the CPU will recognize the \code{IRF} flag and resume interrupt processing as usual. This behavior can be exploited to perform a conditional return from the interrupt handler, similarly to the technique described in Section \ref{sec:callingprocedures} for conditional procedure returns.
An interrupt handler returns using the \code{\instr{jmp} irp} instruction which also has an \instr{iret} alias. Until the interrupt handler returns, the CPU will defer further interrupt processing (although incoming interrupt requests will still be registered). This also means that the \code{irp} register value will not be unexpectedly overwritten. When executing the \code{\instr{jmp} irp} instruction, the CPU will recognize the \code{IRF} flag and resume interrupt processing as usual. It is also possible to perform a conditional return from the interrupt handler, similarly to the technique described in Section \ref{sec:callingprocedures} for conditional procedure returns.
 
Another technique can be useful when waiting for a single event, such as a coprocessor finishing its job: the interrupt handler can be set up to return to a designated address instead of the address stored in the \code{irp} register. This designated address must have the \code{IRF} flag set, otherwise all further interrupt processing will be disabled:
\subsection{Non-returnable interrupts}
 
\begin{codepar}
\instr{lc} r0, continue@1 \emph{// IRF flag}
\instr{lc} iv0, handler
... \emph{// issue coprocessor command}
\instr{hlt} \emph{// wait for an interrupt}
continue:
... \emph{// the execution will continue here}
handler:
\instr{jmp} r0
\end{codepar}
If an interrupt vector has the least significant bit (\code{IRF}) set, the CPU will resume interrupt processing immediately. One should not try to invoke \instr{iret} from such a handler since the \code{irp} register could have been overwritten by another interrupt. This technique can be useful when the CPU's only task is to process external events:
 
\begin{codeparbreakable}
\emph{// Set the IRF to mark the interrupt as non-returnable}
\instr{lc} iv0, main\_loop@1
\instr{mov} cr, 1 \emph{// enable the interrupt}
\instr{hlt} \emph{// wait for an interrupt request}
main\_loop:
\emph{// Process the event...}
\instr{hlt} \emph{// wait for the next interrupt request}
\end{codeparbreakable}
 
Note that \instr{iret} is never called in this example.
 
\chapter{Integration}
\label{ch:integration}
 
314,13 → 309,13
\label{fig:symbols}
\end{figure}
 
\lxp{}U uses the Low Latency Interface (Section \ref{sec:lli}) to fetch instructions. This interface is designed to interact with low latency on-chip peripherals such as RAM blocks or similar devices that are generally expected to return data word after one cycle since the instruction address has been set. It can be also connected to a custom (external) instruction cache.
\lxp{}U uses the Low Latency Interface (LLI) described in Section \ref{sec:lli} to fetch instructions. This interface is designed to interact with low latency on-chip peripherals such as RAM blocks. It works best with slaves that can return the instruction on the next cycle after its address has been set, although the slave can still introduce wait states if needed. Low Latency Interface can be also connected to a custom (external) instruction cache.
 
To achieve the least possible latency, some LLI signals are not registered. For this reason the LLI is not suitable for interaction with off-chip peripherals.
To achieve the least possible latency, some LLI outputs are not registered. For this reason the LLI is not suitable for interaction with off-chip peripherals.
 
\lxp{}C fetches instructions over the WISHBONE instruction bus. To maximize throughput, it supports the WISHBONE registered feedback signals [CTI\_O()] and [BTE\_O()]. All outputs on this bus are registered. This version is recommended for use with high latency memory devices such as SDRAM chips, as well as for situations where LLI combinatorial delays are unacceptable.
\lxp{}C is designed to work with high latency memory controllers and uses a simple instruction cache based on a ring buffer. The instructions are fetched over the WISHBONE instruction bus. To maximize throughput, the CPU makes use of the WISHBONE registered feedback signals [CTI\_O()] and [BTE\_O()]. All outputs on this bus are registered. This version is also recommended for use in situations where LLI combinatorial delays are unacceptable.
 
Both \lxp{}U and \lxp{}C use WISHBONE protocol for the data bus.
Both \lxp{}U and \lxp{}C use the WISHBONE protocol for the data bus.
 
\section{Ports}
 
376,11 → 371,11
 
By default, \lxp{} uses the \signal{dbus\_sel\_o} (byte enable) port to perform byte-granular write transactions initiated by the \instr{sb} (\instrname{Store Byte}) instruction. If this option is set to \code{true}, \signal{dbus\_sel\_o} is always tied to \code{"1111"}, and byte-granular write access is performed using the RMW (read-modify-write) cycle. The latter method is slower, but can work with slaves that do not have the [SEL\_I()] port.
 
This feature requires data bus transactions to be idempotent, that is, repeating a transaction must not alter the slave state. Care should be taken with non-memory slaves to ensure that this condition is satisfied.
This feature is designed with the assumption that read and write transactions do not cause side effects, thus it can be unsuitable for some slaves.
 
\subsection{DIVIDER\_EN}
 
\lxp{} includes a divider unit which occupies a considerable amount of resources. It can be excluded by setting this option to \code{false}.
\lxp{} includes a divider unit which has quite a low performance but occupies a considerable amount of resources. It can be disabled by setting this option to \code{false}.
 
\subsection{IBUS\_BURST\_SIZE}
 
406,7 → 401,7
 
\subsection{START\_ADDR}
 
Address of the first instruction to be executed after CPU reset. Default value is \code{0}. Note that it is a 30-bit value as it is used to address 32-bit words, not bytes.
Address of the first instruction to be executed after CPU reset. Default value is \code{0}. The two least significant bits are ignored as instructions are always word-aligned.
 
\section{Clock and reset}
\label{sec:clockreset}
429,10 → 424,8
\section{Low Latency Interface}
\label{sec:lli}
 
Low Latency Interface is a simple pipelined synchronous protocol with a typical latency of 1 cycle used by \lxp{}U to fetch instructions. Its timing diagram is shown on Figure \ref{fig:llitiming}. The request is considered valid when \signal{lli\_re\_o} is high and \signal{lli\_busy\_i} is low on the same clock cycle. On the next cycle after the request is valid the slave must either produce data on \signal{lmi\_dat\_i} or assert \signal{lli\_busy\_i} to indicate that data are not ready. Note that the values of \signal{lli\_re\_o} and \signal{lli\_adr\_o} are not guaranteed to be preserved by the CPU while the slave is busy.
Low Latency Interface (LLI) is a simple pipelined synchronous protocol with a typical latency of 1 cycle used by \lxp{}U to fetch instructions. It was designed to allow simple connection of the CPU to on-chip program RAM or cache. The timing diagram of the LLI is shown on Figure \ref{fig:llitiming}.
 
The simplest, ``always ready'' slaves such as on-chip RAM blocks can be trivially connected to the LLI by connecting address, data and read enable ports and tying the \signal{lli\_busy\_i} signal to a logical \code{0}. Slaves are also allowed to introduce wait states, which makes it possible to implement external caching.
 
\begin{figure}[htbp]
\centering
\includegraphics[scale=1]{images/llitiming.pdf}
440,15 → 433,23
\label{fig:llitiming}
\end{figure}
 
To request a word, the master produces its address on \signal{lli\_adr\_o} and asserts \signal{lli\_re\_o}. The request is considered valid when \signal{lli\_re\_o} is high and \signal{lli\_busy\_i} is low on the same clock cycle. On the next cycle after a valid request, the slave must either produce data on \signal{lli\_dat\_i} or assert \signal{lli\_busy\_i} to indicate that data are not ready. \signal{lli\_busy\_i} must be held high until the valid data are present on the \signal{lli\_dat\_i} port.
 
The data provided by the slave are only required to be valid on the next cycle after a valid request (if \signal{lli\_busy\_i} is not asserted) or on the cycle when \signal{lli\_busy\_i} is deasserted after being held high. Otherwise \signal{lli\_dat\_i} is undefined.
 
The values of \signal{lli\_re\_o} and \signal{lli\_adr\_o} are not guaranteed to be preserved by the master while the slave is busy.
 
The simplest slaves such as on-chip RAM blocks which are never busy can be trivially connected to the LLI by connecting address, data and read enable ports and tying the \signal{lli\_busy\_i} signal to a logical \code{0} (you can even ignore \signal{lli\_re\_o} in this case, although doing so can theoretically increase power consumption).
 
Note that the \signal{lli\_adr\_o} signal has a width of 30 bits since it addresses words, not bytes (instructions are always word-aligned).
 
Since this interface is not registered, it is not suitable for interaction with off-chip peripherals. Also, care should be taken to avoid introducing too much additional combinatorial delay on its outputs.
Since the \signal{lli\_re\_o} output signal is not registered, this interface is not suitable for interaction with off-chip peripherals. Also, care should be taken to avoid introducing too much additional combinatorial delay on its outputs.
 
\section{WISHBONE instruction bus}
 
The \lxp{}C CPU fetches instructions over the WISHBONE bus. Its parameters are defined in the WISHBONE datasheet (Appendix \ref{app:wishbonedatasheet}). For a detailed description of the bus protocol refer to the WISHBONE specification, revision B3.
 
With classic WISHBONE handshake decent throughput can be only achieved when the slave is able to terminate cycles asynchronously. It is usually possible only for the simplest slaves, which should probably be using the Low Latency Interface in the first place. To maximize throughput for complex, high latency slaves, \lxp{}C instruction bus uses optional WISHBONE address tags [CTI\_O()] (Cycle Type Identifier) and [BTE\_O()] (Burst Type Extension). These signals are hints allowing the slave to predict the address that will be set by the master in the next cycle and prepare data in advance. The slave can ignore these hints, processing requests as classic WISHBONE cycles, although performance would almost certainly suffer in this case.
With classic WISHBONE handshake decent throughput can be only achieved when the slave is able to terminate cycles asynchronously. It is usually possible only for the simplest slaves which should probably be using the Low Latency Interface instead. To maximize throughput for complex, high latency slaves, \lxp{}C instruction bus uses optional WISHBONE address tags [CTI\_O()] (Cycle Type Identifier) and [BTE\_O()] (Burst Type Extension). These signals are hints allowing the slave to predict the address that will be set by the master in the next cycle and prepare data in advance. The slave can ignore these hints, processing requests as classic WISHBONE cycles, although performance would almost certainly suffer in this case.
 
A typical \lxp{}C instruction bus burst timing diagram is shown on Figure \ref{fig:ibustiming}.
 
494,6 → 495,8
 
These design units contain behavioral description of respective hardware that is recognizable by FPGA synthesis tools. Usually no adjustments are needed as the synthesizer will automatically infer an appropriate primitive from its behavioral description. If automatic inference produces unsatisfactory results, these design units can be replaced with library element wrappers. The same is true for ASIC logic synthesis software which is unlikely to infer complex primitives.
 
\lxp{} implements its own bypass logic dealing with situations when RAM read and write addresses collide. It does not depend on the read/write conflict resolution behavior of the underlying primitive.
 
\subsection{General optimization guidelines}
 
This subsection contains general advice on achieving satisfactory synthesis results regardless of the optimization goal. Some of these suggestions are also mentioned in other parts of this manual.
504,12 → 507,14
\item Ensure that the instruction bus has adequate throughput. For \lxp{}C, check that the slave supports the WISHBONE registered feedback signals [CTI\_I()] and [BTE\_I()].
\item Multiplexing instruction and data buses, or connecting them to the same interconnect that allows only one master at a time to be active (i.e. \emph{shared bus} interconnect topology) is not recommended. If you absolutely must do so, assign a higher priority level to the data bus, otherwise instruction prefetches will massively slow down data transactions.
\item For small programs, consider mapping code and data memory to the beginning or end of the address space (i.e. \code{0x00000000}--\code{0x000FFFFF} or \code{0xFFF00000}--\code{0xFFFFFFFF}) to be able to load pointers with the \instr{lcs} instruction which saves both memory and CPU cycles as compared to \instr{lc}.
\end{enumerate}
 
\subsection{Optimizing for timing}
 
\begin{enumerate}
\item Set up reasonable timing constraints. Do not overconstrain the design by more that 10--15~\%.
\item Set up reasonable timing constraints. Do not overconstrain the design by more than 10--15~\%.
\item Analyze the worst path. The natural \lxp{} timing bottleneck usually goes from the scratchpad (register file) output through the ALU (in the Execute stage) to the scratchpad input. If timing analysis lists other critical paths, the problem can lie elsewhere. If the \signal{rst\_i} signal becomes a bottleneck, promote it to a global network or, with SRAM-based FPGAs, consider operating without reset (see Section \ref{sec:clockreset}). Critical paths affecting the WISHBONE state machines could indicate problems with interconnect performance.
521,7 → 526,7
\subsection{Optimizing for area}
 
\begin{enumerate}
\item Consider excluding the divider if not using it (see Section \ref{sec:generics}).
\item Consider disabling the divider if not using it (see Section \ref{sec:generics}).
\item Relaxing timing constraints can sometimes allow the synthesizer to produce a more area-efficient circuit.
528,6 → 533,64
\item Increase the fanout limit in the synthesizer settings to reduce buffer replication.
\end{enumerate}
 
\chapter{Hardware architecture}
\label{ch:pipeline}
 
The \lxp{} CPU is based on a 3-stage hazard-free pipelined architecture and uses a large RAM-based register file (scratchpad) with two read ports and one write port. The pipeline includes the following stages:
 
\begin{itemize}
\item\emph{Fetch} -- fetches instructions from the program memory.
\item\emph{Decode} -- decodes instructions and reads register operand values from the scratchpad.
\item\emph{Execute} -- executes instructions and writes the results (if any) to the scratchpad.
\end{itemize}
 
\lxp{} instructions are encoded in such a way that operand register numbers can be known without decoding the instruction (Section \ref{sec:instructionformat}). When the \emph{Fetch} stage produces an instruction, scratchpad input addresses are set immediately, before the instruction itself is decoded. If the instruction does not use one or both of the register operands, the corresponding data read from the scratchpad are discarded. Collision bypass logic in the scratchpad detects situations where the \emph{Decode} stage tries to read a register which is currently being written by the \emph{Execute} stage and forwards its value, bypassing the RAM block and avoiding Read After Write (RAW) pipeline hazards. Other types of data hazards are also impossible with this architecture.
 
As an example, consider the following simple code chunk:
 
\begin{codepar}
\instr{mov} r0, 10 \emph{// alias for add r0, 10, 0}
\instr{mov} r1, 20 \emph{// alias for add r1, 20, 0}
\instr{add} r2, r0, r1
\end{codepar}
 
Table \ref{tab:examplepipeline} illustrates how this chunk is processed by the \lxp{} pipeline. Note that on the fourth cycle the \emph{Decode} stage requests the \code{r1} register value while the \emph{Execute} stage writes to the same register. Collision bypass logic in the scratchpad ensures that the \emph{Decode} stage reads the correct (new) value of \code{r1} without stalling the pipeline.
 
\begin{table}[htbp]
\caption{Example of the \lxp{} pipeline operation}
\small
\label{tab:examplepipeline}
\begin{tabularx}{\textwidth}{lllL}
\toprule
Cycle & Fetch & Decode & Execute \\
\midrule
1 & \code{\instr{add} r0, 10, 0} & & \\
\midrule
2 & \code{\instr{add} r1, 20, 0} & \code{\instr{add} r0, 10, 0} & \\
& & Request \code{r10} (discarded) & \\
& & Request \code{r0} (discarded) & \\
& & Pass 10 and 0 as operands & \\
\midrule
3 & \code{\instr{add} r2, r0, r1} & \code{\instr{add} r1, 20, 0} & Perform the addition \\
& & Request \code{r20} (discarded) & Write 10 to \code{r0} \\
& & Request \code{r0} (discarded) & \\
& & Pass 20 and 0 as operands & \\
\midrule
4 & & \code{\instr{add} r2, r0, r1} & Perform the addition \\
& & Request \code{r0} & Write 20 to \code{r1} \\
& & Request \code{r1} (bypass) & \\
& & Pass 10 and 20 as operands & \\
\midrule
5 & & & Perform the addition \\
& & & Write 30 to \code{r2} \\
\bottomrule
\end{tabularx}
\end{table}
 
When an instruction takes more than one cycle to execute, the \emph{Execute} stage simply stalls the pipeline.
 
Branch hazards are impossible in \lxp{} as well since the pipeline is flushed whenever an execution transfer occurs.
 
\chapter{Simulation}
\label{ch:simulation}
 
590,6 → 653,7
Produced \shellcmd{*.ram} files must be placed to the simulator's working directory.
\item Compile the \lxp{} RTL description (\shellcmd{rtl} directory).
\item Compile the common package (\shellcmd{verify/common\_pkg}).
\item Compile the test platform (\shellcmd{verify/lxp32/src/platform} directory).
\item Compile the testbench itself (\shellcmd{verify/lxp32/src/tb} directory).
\item Simulate the \shellcmd{tb} design unit defined in the \shellcmd{tb.vhd} file.
600,6 → 664,8
Simulation parameters can be configured by overriding generics defined by the \shellcmd{tb} design unit:
 
\begin{itemize}
\item \code{CPU\_DBUS\_RMW} -- \code{DBUS\_RMW} CPU generic value (see Section \ref{sec:generics}).
\item \code{CPU\_MUL\_ARCH} -- \code{MUL\_ARCH} CPU generic value (see Section \ref{sec:generics}).
\item \code{MODEL\_LXP32C} -- simulate the \lxp{}C version. By default, this option is set to \code{true}. If set to \code{false}, \lxp{}U is simulated instead.
\item \code{TEST\_CASE} -- if set to a non-empty string, specifies the file name of a test case to run. If set to an empty string (default), all tests are executed.
\item \code{THROTTLE\_DBUS} -- perform pseudo-random data bus throttling. By default, this option is set to \code{true}.
630,39 → 696,50
In the simplest case there is only one input source file which doesn't contain external symbol references. If there are multiple input files, one of them must define the \code{entry} symbol at the beginning of the code.
 
\subsection{Command line syntax}
\label{subsec:assemblercmdline}
 
\begin{codepar}
lxp32asm [ \emph{options} | \emph{input files} ]
\end{codepar}
 
Options supported by \shellcmd{lxp32asm} are listed below:
\subsubsection{General options}
 
\begin{itemize}
\item \shellcmd{-a \emph{align}} -- section alignment. Must be a multiple of 4, default value is 4. Ignored in compile-only mode.
\item \shellcmd{-b \emph{addr}} -- Base address, that is, address in memory where the executable image will be located. Must be a multiple of section alignment. Default value is 0. Ignored in compile-only mode.
\item \shellcmd{-c} -- compile only (skip the Link stage).
\item \shellcmd{-f \emph{fmt}} -- select executable image format (see below for the list of supported formats). Ignored in compile-only mode.
\item \shellcmd{-h}, \shellcmd{--help} -- display a short help message and exit.
\item \shellcmd{-o \emph{file}} -- output file name.
\item \shellcmd{--} -- do not interpret the subsequent command line arguments as options. Can be used if there are input file names starting with a dash.
\end{itemize}
 
\subsubsection{Compiler options}
 
\begin{itemize}
\item \shellcmd{-i \emph{dir}} -- add \emph{dir} to the list of directories used to search for included files. Multiple directories can be specified with multiple \shellcmd{-i} arguments.
\end{itemize}
 
\subsubsection{Linker options (ignored in compile-only mode)}
 
\begin{itemize}
\item \shellcmd{-a \emph{align}} -- object alignment. Must be a power of 2 and can't be less than 4. Default value is 4.
\item \shellcmd{-o \emph{file}} -- output file name.
\item \shellcmd{-b \emph{addr}} -- base address, that is, the address in memory where the executable image will be located. Must be a multiple of object alignment. Default value is 0.
\item \shellcmd{-s \emph{size}} -- size of the executable image. Must be a multiple of 4. If total code size is less than the specified value, the executable image is padded with zeros. By default, image is not padded. This option is ignored in compile-only mode.
\item \shellcmd{-f \emph{fmt}} -- executable image format. See below for the list of supported formats.
\item \shellcmd{--} -- do not interpret subsequent command line arguments as options. Can be used if there are input file names starting with dash.
\item \shellcmd{-m \emph{file}} -- generate a map file. A map file is a human-readable list of all object and symbol addresses in the executable image.
\item \shellcmd{-s \emph{size}} -- size of the executable image. Must be a multiple of 4. If total code size is less than the specified value, the executable image is padded with zeros. By default, the image is not padded.
\end{itemize}
 
\subsection{Output formats}
 
The following output formats are supported by \shellcmd{lxp32asm}:
Output formats that can be specified with the \shellcmd{-f} command line option are listed below.
 
\begin{itemize}
\item \shellcmd{bin} -- raw binary image. This is the default format.
\item \shellcmd{bin} -- raw binary image (little-endian). This is the default format.
\item \shellcmd{textio} -- text format representing binary data as a sequence of zeros and ones. This format can be directly read from VHDL (using the \code{std.textio} package) or Verilog\textregistered{} (using the \code{\$readmemb} function).
\item \shellcmd{dec} -- text format representing each word as a decimal number.
\item \shellcmd{hex} -- text format representing each word as a hexadecimal number.
687,6 → 764,8
\item \shellcmd{-h}, \shellcmd{--help} -- display a short help message and exit.
\item \shellcmd{-na} -- do not use instruction aliases (such as \instr{mov}, \instr{ret}, \instr{not}) and register aliases (such as \code{sp}, \code{rp}).
\item \shellcmd{-o \emph{file}} -- output file name. By default, the standard output stream is used.
\item \shellcmd{--} -- do not interpret subsequent command line arguments as options.
694,7 → 773,7
 
\section{\shellcmd{wigen} -- Interconnect generator}
 
\shellcmd{wigen} is a small tool that generates VHDL description of a simple WISHBONE interconnect based on shared bus topology. It supports any number of masters and slaves.
\shellcmd{wigen} is a small tool that generates VHDL description of a simple WISHBONE interconnect based on shared bus topology. It supports any number of masters and slaves. The interconnect can then be used to create a SoC based on \lxp{}.
 
For interconnects with multiple masters a priority-based arbitration circuit is inserted with lower-numbered masters taking precedence. However, when a bus cycle is in progress ([CYC\_O] is asserted by the active master), the arbiter will not interrupt it even if a master with a higher priority level requests bus ownership.
 
745,7 → 824,7
 
\subsection{Build procedure}
 
This software uses CMake as a build system generator. Building it involves two steps: first, the \shellcmd{cmake} program is invoked to generate a native build environment (a set of Makefiles or an IDE project); second, the generated environment is used to build the software.
This software uses CMake as a build system generator. Building it involves two steps: first, the \shellcmd{cmake} program is invoked to generate a native build environment (a set of Makefiles or an IDE project); second, the generated environment is used to build the software. More details can be found in the CMake documentation.
 
\subsubsection{Examples}
 
791,8 → 870,6
make install
\end{codepar}
 
More details can be found in the CMake documentation.
 
\appendix
 
\chapter{Instruction set reference}
810,6 → 887,7
\midrule
\hyperref[subsec:instr:mov]{\instr{mov}} & Move & alias for \code{\instr{add} dst, src, 0} \\
\hyperref[subsec:instr:lc]{\instr{lc}} & Load Constant & \code{000001} \\
\hyperref[subsec:instr:lcs]{\instr{lcs}} & Load Constant Short & \code{101xxx} \\
\hyperref[subsec:instr:lw]{\instr{lw}} & Load Word & \code{001000} \\
\hyperref[subsec:instr:lub]{\instr{lub}} & Load Unsigned Byte & \code{001010} \\
\hyperref[subsec:instr:lsb]{\instr{lsb}} & Load Signed Byte & \code{001011} \\
820,6 → 898,7
\midrule
\hyperref[subsec:instr:add]{\instr{add}} & Add & \code{010000} \\
\hyperref[subsec:instr:sub]{\instr{sub}} & Subtract & \code{010001} \\
\hyperref[subsec:instr:neg]{\instr{neg}} & Negate & alias for \code{\instr{sub} dst, 0, src} \\
\hyperref[subsec:instr:mul]{\instr{mul}} & Multiply & \code{010010} \\
\hyperref[subsec:instr:divu]{\instr{divu}} & Divide Unsigned & \code{010100} \\
\hyperref[subsec:instr:divs]{\instr{divs}} & Divide Signed & \code{010101} \\
959,7 → 1038,7
\instr{cjmpuge} & \code{111010} \\
\end{tabularx}
 
\instr{cjmpsl}, \instr{cjmpsle}, \instr{cjmpul}, \instr{cjmpule} are aliases for \instr{cjmpsg}, \instr{cjmpsge}, \instr{cjmpug}, \instr{cjmpuge}, respectively, with RD1 and RD2 operands swapped.
\instr{cjmpsl}, \instr{cjmpsle}, \instr{cjmpul}, \instr{cjmpule} instructions are aliases for \instr{cjmpsg}, \instr{cjmpsge}, \instr{cjmpug}, \instr{cjmpuge}, respectively, with RD1 and RD2 operands swapped.
 
Example: \code{\instr{cjmpuge} r2, r1, 5} $\rightarrow$ \code{0xEA020105}
 
1061,7 → 1140,7
\subsection{\instr{lc} -- Load Constant}
\label{subsec:instr:lc}
 
Load a 32-bit word to the specified register. Note that values in the [-128; 127] range can be loaded more efficiently using the \instr{mov} instruction alias.
Load a 32-bit word to the specified register. Note that values from the [-1048576; 1048575] range can be loaded more efficiently using the \instr{lcs} instruction.
 
\subsubsection{Syntax}
 
1079,6 → 1158,25
 
\code{DST := WORD32}
 
\subsection{\instr{lcs} -- Load Constant Short}
\label{subsec:instr:lcs}
 
Load a signed value from the [-1048576; 1048575] range (a sign extended 21-bit value) to the specified register. Unlike the \instr{lc} instruction, this instruction is encoded as a single word.
 
\subsubsection{Syntax}
 
\code{\instr{lcs} DST, VAL}
 
\subsubsection{Encoding}
 
\code{101 VAL[20:16] DST VAL[15:0]}
 
Example: \code{\instr{lcs} r1, -1000000} $\rightarrow$ \code{0xB001BDC0}
 
\subsubsection{Operation}
 
\code{DST := (\emph{signed}) VAL}
 
\subsection{\instr{lsb} -- Load Signed Byte}
\label{subsec:instr:lsb}
 
1220,6 → 1318,15
 
Since the product width is the same as the operand width, the result of a multiplication does not depend on operand signedness.
 
\subsection{\instr{neg} -- Negate}
\label{subsec:instr:neg}
 
\subsubsection{Syntax}
 
\code{\instr{neg} DST, RD2}
 
Alias for \code{\instr{sub} DST, 0, RD2}
 
\subsection{\instr{nop} -- No Operation}
\label{subsec:instr:nop}
 
1415,7 → 1522,7
 
\chapter{Instruction cycle counts}
 
Cycle counts for \lxp{} instructions are listed in Table \ref{tab:cycles}. These values can change in future hardware revisions.
Cycle counts for \lxp{} instructions are listed in Table \ref{tab:cycles}, based on an assumption that no pipeline stalls are caused by the instruction bus latency or cache misses. These data are provided for reference purposes; the software should not depend on them as they can change in future hardware revisions.
 
\begin{table}[htbp]
\centering
1423,18 → 1530,19
\label{tab:cycles}
\begin{tabularx}{0.8\textwidth}{LLLL}
\toprule
Instruction & Cycle count & Instruction & Cycle count \\
Instruction & Cycles & Instruction & Cycles \\
\midrule
\instr{add} & 1 & \instr{modu} & 37 \\
\instr{and} & 1 & \instr{mov} & 1 \\
\instr{call} & $\ge$ 4\footnotemark[1] & \instr{mul} & 2, 6 or 34\footnotemark[3] \\
\instr{cjmp\emph{xxx}} & $\ge$ 5\footnotemark[1] & \instr{nop} & 1 \\
\instr{divs} & 37 & \instr{not} & 1 \\
\instr{divu} & 37 & \instr{or} & 1 \\
\instr{hlt} & N/A & \instr{ret} & $\ge$ 4\footnotemark[1] \\
\instr{jmp} & $\ge$ 4\footnotemark[1] & \instr{sb} & $\ge$ 2\footnotemark[2] \\
\instr{iret} & $\ge$ 4\footnotemark[1] & \instr{sl} & 2 \\
\instr{lc} & 2 & \instr{srs} & 2 \\
\instr{call} & 4 & \instr{mul} & 2, 6 or 34\footnotemark[3] \\
\instr{cjmp\emph{xxx}} & 5 or 2\footnotemark[1] & \instr{neg} & 1 \\
\instr{divs} & 36 & \instr{nop} & 1 \\
\instr{divu} & 36 & \instr{not} & 1 \\
\instr{hlt} & N/A & \instr{or} & 1 \\
\instr{jmp} & 4 & \instr{ret} & 4 \\
\instr{iret} & 4 & \instr{sb} & $\ge$ 2\footnotemark[2] \\
\instr{lc} & 2 & \instr{sl} & 2 \\
\instr{lcs} & 1 & \instr{srs} & 2 \\
\instr{lsb} & $\ge$ 3\footnotemark[2] & \instr{sru} & 2 \\
\instr{lub} & $\ge$ 3\footnotemark[2] & \instr{sub} & 1 \\
\instr{lw} & $\ge$ 3\footnotemark[2] & \instr{sw} & $\ge$ 2\footnotemark[2] \\
1443,9 → 1551,9
\end{tabularx}
\end{table}
 
\footnotetext[1]{Depends on instruction bus latency. Includes pipeline flushing overhead.}
\footnotetext[2]{Depends on data bus latency.}
\footnotetext[3]{Depends on multiplier architecture set with the \code{MUL\_ARCH} generic. See Section \ref{sec:generics}.}
\footnotetext[1]{Depends on whether the jump is taken or not.}
\footnotetext[2]{Depends on the data bus latency.}
\footnotetext[3]{Depends on the multiplier architecture. See Section \ref{sec:generics}.}
 
\chapter{LXP32 assembly language}
\label{app:assemblylanguage}
1472,7 → 1580,7
 
Numeric literals can take form of decimal, hexadecimal or octal numbers. Literals prefixed with \code{0x} are interpreted as hexadecimal, literals prefixed with \code{0} are interpreted as octal, other literals are interpreted as decimal. A numeric literal can also start with an unary plus or minus sign which is also considered a part of the literal.
 
String literals must be enclosed in double quotes. The most common escape sequences used in C are supported (Table \ref{tab:stringescape}).
String literals must be enclosed in double quotes. The most common escape sequences used in C are supported (Table \ref{tab:stringescape}). Note that strings are not null-terminated in the LXP32 assembly language; when required, terminating null character must be inserted explicitly.
 
\begin{table}[htbp]
\caption{Escape sequences used in string literals}
1496,16 → 1604,18
\section{Symbols}
\label{sec:symbols}
 
Symbols are used to refer to data or code locations. \lxp{} assembly language does not have distinct code labels and variable declarations: symbols are used in both these contexts.
Symbols (labels) are used to refer to data or code locations. \lxp{} assembly language does not have distinct code and data labels: symbols are used in both these contexts.
 
Symbol names must be valid identifiers. A valid identifier must start with an alphabetic character or an underscore, and may contain alphanumeric characters and underscores.
 
A symbol definition must be the first token in a source code line followed by a colon. A symbol definition can occupy a separate line (in which case it refers to the following statement). Alternatively, a statement can follow the symbol definition on the same line.
 
A special \code{entry} symbol is used to inform the linker about program entry point if there are multiple input files. If defined, this symbol must precede the first instruction or data definition statement in the module.
Symbols can be used as operands to the \instr{lc} and \instr{lcs} instruction statements. A symbol reference can end with a \code{@\emph{n}} sequence, where \code{\emph{n}} is a numeric literal; in this case it is interpreted as an offset (in bytes) relative to the symbol definition. For the \instr{lcs} instruction, the resulting address must still fit into the sign extended 21-bit value range (\code{0x00000000}--\code{0x000FFFFF} or \code{0xFFF00000}--\code{0xFFFFFFFF}), otherwise the linker will report an error.
 
Symbols can be used as operands to the \instr{lc} instruction statement. A symbol reference can end with a \code{@\emph{n}} sequence, where \code{\emph{n}} is a numeric literal; in this case it is interpreted as an offset (in bytes) relative to the symbol definition. To refer to symbols defined in other modules, they must first be declared external using the \instr{\#extern} directive.
By default all symbols are local, that is, they can be only referenced from the module where they were defined. To make a symbol accessible from other modules, use the \instr{\#export} directive. To reference a symbol defined in another module use the \instr{\#import} directive.
 
A symbol named \code{entry} or \code{Entry} has a special meaning: it is used to inform the linker about the program entry point if there are multiple input files. It does not have to be exported. If defined, this symbol must precede the first instruction or data definition statement in the module. Only one module in the program can define the entry symbol.
 
\begin{codeparbreakable}
\instr{lc} r10, jump\_label
\instr{lc} r11, data\_word
1542,12 → 1652,18
Defines a macro that will be substituted with one or more tokens. The \code{\emph{identifier}} must satisfy the requirements listed in Section \ref{sec:symbols}. Tokens can be anything, including keywords, identifiers, literals and separators (i.e. comma and colon characters).
 
\begin{codepar}
\instr{\#extern} \emph{identifier}
\instr{\#export} \emph{identifier}
\end{codepar}
 
Declares \code{\emph{identifier}} as an external symbol. Used to refer to symbols defined in other modules.
Declares \code{\emph{identifier}} as an exported symbol. Exported symbols can be referenced by other modules.
 
\begin{codepar}
\instr{\#import} \emph{identifier}
\end{codepar}
 
Declares \code{\emph{identifier}} as an imported symbol. Used to refer to symbols exported by other modules.
 
\begin{codepar}
\instr{\#include} \emph{filename}
\end{codepar}
 
1567,8 → 1683,10
\instr{.align} [ \emph{alignment} ]
\end{codepar}
 
Ensures that code generated by the next data definition or instruction statement is aligned to a multiple of \code{\emph{alignment}} bytes, inserting padding zeros if needed. Default \code{\emph{alignment}} is 4. Instructions and words are always at least word-aligned; the \instr{.align} statement can be used to align them to a larger boundary, or to align byte data (see below).
Ensures that code generated by the next data definition or instruction statement is aligned to a multiple of \code{\emph{alignment}} bytes, inserting padding zeros if needed. \code{\emph{alignment}} must be a power of 2 and can't be less than 4. Default \code{\emph{alignment}} is 4. Instructions and words are always at least word-aligned; the \instr{.align} statement can be used to align them to a larger boundary, or to align byte data (see below).
 
The \instr{.align} statement is not guaranteed to work if the requested alignment is greater than the section alignment specified for the linker (see Subsection \ref{subsec:assemblercmdline}).
 
\begin{codepar}
\instr{.byte} \emph{token} [, \emph{token} ... ]
\end{codepar}
1575,6 → 1693,8
 
Inserts one or more bytes to the output code. Each \code{\emph{token}} can be either a numeric literal with a valid range of [-128; 255] or a string literal. By default, bytes are not aligned.
 
To define a null-terminated string, the terminating null character must be inserted explicitly.
 
\begin{codepar}
\instr{.reserve} \emph{n}
\end{codepar}
1674,4 → 1794,24
\bottomrule
\end{ctabular}
 
\chapter{List of changes}
 
\section*{Version 1.1 (2019-01-11)}
 
This release introduces a minor but technically breaking hardware change: the START\_ADDR generic, which used to be 30-bit, has been for convenience extended to a full 32-bit word; the two least significant bits are ignored.
 
The other breaking change affects the assembly language syntax. Previously all symbols used to be public, and multiple modules could not define symbols with the same name. As of now only symbols explicitly exported using the \instr{\#export} directive are public. \instr{\#extern} directive has been replaced by \instr{\#import}.
 
Other notable changes include:
 
\begin{itemize}
\item A new instruction, \instr{lcs} (\instrname{Load Constant Short}), has been added, which loads a 21-bit sign extended constant to a register. Unlike \instr{lc}, it is encoded as a single word and takes one cycle to execute.
\item Optimizations in the divider unit. Division instructions (\instr{divs} and \instr{divu}) now take one fewer cycle to execute (modulo instructions are unaffected).
\item LXP32 assembly language now supports a new instruction alias, \instr{neg} (\instrname{Negate}), which is equivalent to \code{\instr{sub} dst, 0, src}.
\end{itemize}
 
\section*{Version 1.0 (2016-02-20)}
 
Initial public release.
 
\end{document}
/doc/src/trm/preamble.tex
1,4 → 1,5
\usepackage{microtype}
\usepackage{graphicx}
\usepackage{alltt}
\usepackage{amsmath}
\usepackage[charter]{mathdesign}
/misc/highlight/akelpad/asm.coder Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
/misc/highlight/notepad++/LXP32Assembly.xml
1,5 → 1,5
<NotepadPlus>
<UserLang name="LXP32 Assembly" ext="asm" udlVersion="2.1">
<UserLang name="LXP32 Assembly" ext="asm inc" udlVersion="2.1">
<Settings>
<Global caseIgnored="no" allowFoldOfComments="yes" foldCompact="no" forcePureLC="0" decimalSeparator="0" />
<Prefix Keywords1="no" Keywords2="no" Keywords3="no" Keywords4="no" Keywords5="no" Keywords6="no" Keywords7="no" Keywords8="no" />
24,9 → 24,9
<Keywords name="Folders in comment, open"></Keywords>
<Keywords name="Folders in comment, middle"></Keywords>
<Keywords name="Folders in comment, close"></Keywords>
<Keywords name="Keywords1">add and call cjmpe cjmpne cjmpsg cjmpsge cjmpsl cjmpsle cjmpug cjmpuge cjmpul cjmpule divs divu hlt jmp iret lc lsb lub lw mods modu mov mul nop not or ret sb sl srs sru sub sw xor</Keywords>
<Keywords name="Keywords1">add and call cjmpe cjmpne cjmpsg cjmpsge cjmpsl cjmpsle cjmpug cjmpuge cjmpul cjmpule divs divu hlt jmp iret lc lcs lsb lub lw mods modu mov mul neg nop not or ret sb sl srs sru sub sw xor</Keywords>
<Keywords name="Keywords2">cr irp iv0 iv1 iv2 iv3 iv4 iv5 iv6 iv7 r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 r16 r17 r18 r19 r20 r21 r22 r23 r24 r25 r26 r27 r28 r29 r30 r31 r32 r33 r34 r35 r36 r37 r38 r39 r40 r41 r42 r43 r44 r45 r46 r47 r48 r49 r50 r51 r52 r53 r54 r55 r56 r57 r58 r59 r60 r61 r62 r63 r64 r65 r66 r67 r68 r69 r70 r71 r72 r73 r74 r75 r76 r77 r78 r79 r80 r81 r82 r83 r84 r85 r86 r87 r88 r89 r90 r91 r92 r93 r94 r95 r96 r97 r98 r99 r100 r101 r102 r103 r104 r105 r106 r107 r108 r109 r110 r111 r112 r113 r114 r115 r116 r117 r118 r119 r120 r121 r122 r123 r124 r125 r126 r127 r128 r129 r130 r131 r132 r133 r134 r135 r136 r137 r138 r139 r140 r141 r142 r143 r144 r145 r146 r147 r148 r149 r150 r151 r152 r153 r154 r155 r156 r157 r158 r159 r160 r161 r162 r163 r164 r165 r166 r167 r168 r169 r170 r171 r172 r173 r174 r175 r176 r177 r178 r179 r180 r181 r182 r183 r184 r185 r186 r187 r188 r189 r190 r191 r192 r193 r194 r195 r196 r197 r198 r199 r200 r201 r202 r203 r204 r205 r206 r207 r208 r209 r210 r211 r212 r213 r214 r215 r216 r217 r218 r219 r220 r221 r222 r223 r224 r225 r226 r227 r228 r229 r230 r231 r232 r233 r234 r235 r236 r237 r238 r239 r240 r241 r242 r243 r244 r245 r246 r247 r248 r249 r250 r251 r252 r253 r254 r255 rp sp</Keywords>
<Keywords name="Keywords3">#define #extern #include #message</Keywords>
<Keywords name="Keywords3">#define #export #import #include #message</Keywords>
<Keywords name="Keywords4">.align .byte .reserve .word</Keywords>
<Keywords name="Keywords5"></Keywords>
<Keywords name="Keywords6"></Keywords>
/rtl/lxp32_alu.vhd
31,7 → 31,6
cmd_cmp_i: in std_logic;
cmd_negate_op2_i: in std_logic;
cmd_and_i: in std_logic;
cmd_or_i: in std_logic;
cmd_xor_i: in std_logic;
cmd_shift_i: in std_logic;
cmd_shift_right_i: in std_logic;
62,22 → 61,16
signal cmp_s1: std_logic;
signal cmp_s2: std_logic;
 
signal and_result: std_logic_vector(31 downto 0);
signal and_we: std_logic;
signal or_result: std_logic_vector(31 downto 0);
signal or_we: std_logic;
signal xor_result: std_logic_vector(31 downto 0);
signal xor_we: std_logic;
signal logic_result: std_logic_vector(31 downto 0);
signal logic_we: std_logic;
 
signal mul_result: std_logic_vector(31 downto 0);
signal mul_ce: std_logic;
signal mul_we: std_logic;
 
signal div_quotient: std_logic_vector(31 downto 0);
signal div_remainder: std_logic_vector(31 downto 0);
signal div_result: std_logic_vector(31 downto 0);
signal div_ce: std_logic;
signal div_we: std_logic;
signal div_select_remainder: std_logic;
 
signal shift_result: std_logic_vector(31 downto 0);
signal shift_ce: std_logic;
97,7 → 90,11
-- Add/subtract
 
addend1<=unsigned(op1_i);
addend2<=unsigned(op2_i) when cmd_negate_op2_i='0' else not unsigned(op2_i);
 
addend2_gen: for i in addend2'range generate
addend2(i)<=op2_i(i) xor cmd_negate_op2_i;
end generate;
 
adder_result<=("0"&addend1)+("0"&addend2)+(to_unsigned(0,adder_result'length-1)&cmd_negate_op2_i);
adder_we<=cmd_addsub_i and valid_i;
 
126,15 → 123,16
(not cmp_s1 and not cmp_s2 and cmp_carry) or
(not cmp_s1 and cmp_s2)) and not cmp_eq;
 
-- Logical functions
-- Bitwise operations (and, or, xor)
-- Note: (a or b) = (a and b) or (a xor b)
 
and_result<=op1_i and op2_i;
and_we<=cmd_and_i and valid_i;
or_result<=op1_i or op2_i;
or_we<=cmd_or_i and valid_i;
xor_result<=op1_i xor op2_i;
xor_we<=cmd_xor_i and valid_i;
logic_result_gen: for i in logic_result'range generate
logic_result(i)<=((op1_i(i) and op2_i(i)) and cmd_and_i) or
((op1_i(i) xor op2_i(i)) and cmd_xor_i);
end generate;
 
logic_we<=(cmd_and_i or cmd_xor_i) and valid_i;
 
-- Multiplier
 
mul_ce<=cmd_mul_i and valid_i;
191,27 → 189,17
op1_i=>op1_i,
op2_i=>op2_i,
signed_i=>cmd_signed_i,
rem_i=>cmd_div_mod_i,
ce_o=>div_we,
quotient_o=>div_quotient,
remainder_o=>div_remainder
result_o=>div_result
);
end generate;
 
gen_no_divider: if not DIVIDER_EN generate
div_we<=div_ce;
div_quotient<=(others=>'0');
div_remainder<=(others=>'0');
div_result<=(others=>'0');
end generate;
 
process (clk_i) is
begin
if rising_edge(clk_i) then
if div_ce='1' then
div_select_remainder<=cmd_div_mod_i;
end if;
end if;
end process;
 
-- Shifter
 
shift_ce<=cmd_shift_i and valid_i;
233,18 → 221,15
 
result_mux_gen: for i in result_mux'range generate
result_mux(i)<=(adder_result(i) and adder_we) or
(and_result(i) and and_we) or
(or_result(i) and or_we) or
(xor_result(i) and xor_we) or
(logic_result(i) and logic_we) or
(mul_result(i) and mul_we) or
(div_quotient(i) and div_we and not div_select_remainder) or
(div_remainder(i) and div_we and div_select_remainder) or
(div_result(i) and div_we) or
(shift_result(i) and shift_we);
end generate;
 
result_o<=result_mux;
 
result_we<=adder_we or and_we or or_we or xor_we or mul_we or div_we or shift_we;
result_we<=adder_we or logic_we or mul_we or div_we or shift_we;
we_o<=result_we;
 
-- Pipeline control
252,15 → 237,10
process (clk_i) is
begin
if rising_edge(clk_i) then
if rst_i='1' then
if rst_i='1' or result_we='1' then
busy<='0';
else
if shift_ce='1' or mul_ce='1' or div_ce='1' then
busy<='1';
end if;
if result_we='1' then
busy<='0';
end if;
elsif shift_ce='1' or mul_ce='1' or div_ce='1' then
busy<='1';
end if;
end if;
end process;
/rtl/lxp32_cpu.vhd
14,7 → 14,7
DBUS_RMW: boolean;
DIVIDER_EN: boolean;
MUL_ARCH: string;
START_ADDR: std_logic_vector(29 downto 0)
START_ADDR: std_logic_vector(31 downto 0)
);
port(
clk_i: in std_logic;
42,6 → 42,7
 
signal fetch_word: std_logic_vector(31 downto 0);
signal fetch_next_ip: std_logic_vector(29 downto 0);
signal fetch_current_ip: std_logic_vector(29 downto 0);
signal fetch_valid: std_logic;
signal fetch_jump_ready: std_logic;
 
61,7 → 62,6
signal decode_cmd_jump: std_logic;
signal decode_cmd_negate_op2: std_logic;
signal decode_cmd_and: std_logic;
signal decode_cmd_or: std_logic;
signal decode_cmd_xor: std_logic;
signal decode_cmd_shift: std_logic;
signal decode_cmd_shift_right: std_logic;
89,8 → 89,6
signal interrupt_vector: std_logic_vector(2 downto 0);
signal interrupt_ready: std_logic;
signal interrupt_return: std_logic;
signal interrupts_enabled: std_logic_vector(7 downto 0);
signal interrupts_blocked: std_logic_vector(7 downto 0);
 
begin
 
109,6 → 107,7
word_o=>fetch_word,
next_ip_o=>fetch_next_ip,
current_ip_o=>fetch_current_ip,
valid_o=>fetch_valid,
ready_i=>decode_ready,
124,6 → 123,7
word_i=>fetch_word,
next_ip_i=>fetch_next_ip,
current_ip_i=>fetch_current_ip,
valid_i=>fetch_valid,
jump_valid_i=>execute_jump_valid,
ready_o=>decode_ready,
153,7 → 153,6
cmd_jump_o=>decode_cmd_jump,
cmd_negate_op2_o=>decode_cmd_negate_op2,
cmd_and_o=>decode_cmd_and,
cmd_or_o=>decode_cmd_or,
cmd_xor_o=>decode_cmd_xor,
cmd_shift_o=>decode_cmd_shift,
cmd_shift_right_o=>decode_cmd_shift_right,
189,7 → 188,6
cmd_jump_i=>decode_cmd_jump,
cmd_negate_op2_i=>decode_cmd_negate_op2,
cmd_and_i=>decode_cmd_and,
cmd_or_i=>decode_cmd_or,
cmd_xor_i=>decode_cmd_xor,
cmd_shift_i=>decode_cmd_shift,
cmd_shift_right_i=>decode_cmd_shift_right,
221,9 → 219,7
jump_dst_o=>execute_jump_dst,
jump_ready_i=>fetch_jump_ready,
interrupt_return_o=>interrupt_return,
interrupts_enabled_o=>interrupts_enabled,
interrupts_blocked_o=>interrupts_blocked
interrupt_return_o=>interrupt_return
);
 
scratchpad_inst: entity work.lxp32_scratchpad(rtl)
247,13 → 243,14
irq_i=>irq_i,
interrupts_enabled_i=>interrupts_enabled,
interrupts_blocked_i=>interrupts_blocked,
interrupt_valid_o=>interrupt_valid,
interrupt_vector_o=>interrupt_vector,
interrupt_ready_i=>interrupt_ready,
interrupt_return_i=>interrupt_return
interrupt_return_i=>interrupt_return,
sp_waddr_i=>sp_waddr,
sp_we_i=>sp_we,
sp_wdata_i=>sp_wdata
);
 
end architecture;
/rtl/lxp32_dbus.vhd
54,6 → 54,7
signal sig: std_logic;
signal rmw_mode: std_logic;
 
signal dbus_rdata: std_logic_vector(31 downto 0);
signal selected_byte: std_logic_vector(7 downto 0);
 
begin
64,6 → 65,13
if rst_i='1' then
we_out<='0';
strobe<='0';
sig<='-';
byte_mode<='-';
sel<=(others=>'-');
we<='-';
rmw_mode<='-';
dbus_adr_o<=(others=>'-');
dbus_dat_o<=(others=>'-');
else
we_out<='0';
if strobe='0' then
72,10 → 80,10
sig<=cmd_signed_i;
dbus_adr_o<=addr_i(31 downto 2);
dbus_dat_o<=wdata_i;
if cmd_dbus_byte_i='0' then
byte_mode<='0';
dbus_dat_o<=wdata_i;
sel<="1111";
-- synthesis translate_off
85,11 → 93,14
-- synthesis translate_on
else
byte_mode<='1';
dbus_dat_o<=wdata_i(7 downto 0)&wdata_i(7 downto 0)&
wdata_i(7 downto 0)&wdata_i(7 downto 0);
case addr_i(1 downto 0) is
when "00" => sel<="0001"; dbus_dat_o(7 downto 0)<=wdata_i(7 downto 0);
when "01" => sel<="0010"; dbus_dat_o(15 downto 8)<=wdata_i(7 downto 0);
when "10" => sel<="0100"; dbus_dat_o(23 downto 16)<=wdata_i(7 downto 0);
when "11" => sel<="1000"; dbus_dat_o(31 downto 24)<=wdata_i(7 downto 0);
when "00" => sel<="0001";
when "01" => sel<="0010";
when "10" => sel<="0100";
when "11" => sel<="1000";
when others =>
end case;
end if;
136,27 → 147,24
dbus_sel_o<=(others=>'1');
end generate;
 
selected_byte_gen: for i in selected_byte'range generate
selected_byte(i)<=(dbus_dat_i(i) and sel(0)) or
(dbus_dat_i(i+8) and sel(1)) or
(dbus_dat_i(i+16) and sel(2)) or
(dbus_dat_i(i+24) and sel(3));
end generate;
 
process (clk_i) is
begin
if rising_edge(clk_i) then
if byte_mode='0' then
rdata_o<=dbus_dat_i;
else
rdata_o(7 downto 0)<=selected_byte;
for i in rdata_o'high downto 8 loop
rdata_o(i)<=selected_byte(selected_byte'high) and sig;
end loop;
end if;
dbus_rdata<=dbus_dat_i;
end if;
end process;
 
selected_byte_gen: for i in selected_byte'range generate
selected_byte(i)<=(dbus_rdata(i) and sel(0)) or
(dbus_rdata(i+8) and sel(1)) or
(dbus_rdata(i+16) and sel(2)) or
(dbus_rdata(i+24) and sel(3));
end generate;
 
rdata_o<=dbus_rdata when byte_mode='0' else
X"000000"&selected_byte when selected_byte(selected_byte'high)='0' or sig='0' else
X"FFFFFF"&selected_byte;
 
we_o<=we_out;
busy_o<=strobe or we_out;
 
/rtl/lxp32_decode.vhd
19,6 → 19,7
word_i: in std_logic_vector(31 downto 0);
next_ip_i: in std_logic_vector(29 downto 0);
current_ip_i: in std_logic_vector(29 downto 0);
valid_i: in std_logic;
jump_valid_i: in std_logic;
ready_o: out std_logic;
48,7 → 49,6
cmd_jump_o: out std_logic;
cmd_negate_op2_o: out std_logic;
cmd_and_o: out std_logic;
cmd_or_o: out std_logic;
cmd_xor_o: out std_logic;
cmd_shift_o: out std_logic;
cmd_shift_right_o: out std_logic;
78,8 → 78,6
signal rd1: std_logic_vector(7 downto 0);
signal rd2: std_logic_vector(7 downto 0);
 
signal current_ip: unsigned(next_ip_i'range);
 
-- Signals related to pipeline control
 
signal downstream_busy: std_logic;
119,8 → 117,6
downstream_busy<=valid_out and not ready_i;
busy<=downstream_busy or self_busy;
 
current_ip<=unsigned(next_ip_i)-1;
 
process (clk_i) is
begin
if rising_edge(clk_i) then
129,6 → 125,29
self_busy<='0';
state<=Regular;
interrupt_ready<='0';
cmd_loadop3_o<='-';
cmd_signed_o<='-';
cmd_dbus_o<='-';
cmd_dbus_store_o<='-';
cmd_dbus_byte_o<='-';
cmd_addsub_o<='-';
cmd_negate_op2_o<='-';
cmd_mul_o<='-';
cmd_div_o<='-';
cmd_div_mod_o<='-';
cmd_cmp_o<='-';
cmd_jump_o<='-';
cmd_and_o<='-';
cmd_xor_o<='-';
cmd_shift_o<='-';
cmd_shift_right_o<='-';
rd1_select<='-';
rd1_direct<=(others=>'-');
rd2_select<='-';
rd2_direct<=(others=>'-');
op3_o<=(others=>'-');
jump_type_o<=(others=>'-');
dst_out<=(others=>'-');
else
interrupt_ready<='0';
if jump_valid_i='1' then
136,34 → 155,36
self_busy<='0';
state<=Regular;
elsif downstream_busy='0' then
op3_o<=(others=>'-');
rd1_direct<=std_logic_vector(resize(signed(rd1),rd1_direct'length));
rd2_direct<=std_logic_vector(resize(signed(rd2),rd2_direct'length));
cmd_signed_o<=opcode(0);
cmd_div_mod_o<=opcode(1);
cmd_shift_right_o<=opcode(1);
cmd_dbus_byte_o<=opcode(1);
cmd_dbus_store_o<=opcode(2);
case state is
when Regular =>
cmd_loadop3_o<='0';
cmd_signed_o<='0';
cmd_dbus_o<='0';
cmd_dbus_store_o<='0';
cmd_dbus_byte_o<='0';
cmd_addsub_o<='0';
cmd_negate_op2_o<='0';
cmd_mul_o<='0';
cmd_div_o<='0';
cmd_div_mod_o<='0';
cmd_cmp_o<='0';
cmd_jump_o<='0';
cmd_and_o<='0';
cmd_or_o<='0';
cmd_xor_o<='0';
cmd_shift_o<='0';
cmd_shift_right_o<='0';
op3_o<=(others=>'-');
jump_type_o<=opcode(3 downto 0);
if interrupt_valid_i='1' and valid_i='1' then
cmd_jump_o<='1';
cmd_loadop3_o<='1';
op3_o<=std_logic_vector(current_ip)&"01"; -- LSB indicates interrupt return
op3_o<=current_ip_i&"01"; -- LSB indicates interrupt return
dst_out<=X"FD"; -- interrupt return pointer
rd1_select<='1';
rd2_select<='0';
172,19 → 193,17
self_busy<='1';
state<=ContinueInterrupt;
else
if opcode="000001" then
if opcode(5 downto 3)="101" or opcode="000001" then -- lc or lcs
cmd_loadop3_o<='1';
-- Setting op3_o here only affects the lcs instruction
op3_o<=std_logic_vector(resize(signed(opcode(2 downto 0)&
t1&t2&rd1&rd2),op3_o'length));
end if;
cmd_signed_o<=opcode(0);
if opcode(5 downto 3)="001" then
cmd_dbus_o<='1';
end if;
cmd_dbus_store_o<=opcode(2);
cmd_dbus_byte_o<=opcode(1);
if opcode(5 downto 1)="01000" then
cmd_addsub_o<='1';
end if;
199,27 → 218,20
cmd_div_o<='1';
end if;
cmd_div_mod_o<=opcode(1);
if opcode="100000" then
if opcode(5 downto 3)="100" then -- jump or call
cmd_jump_o<='1';
end if;
if opcode="100001" then
cmd_jump_o<='1';
cmd_loadop3_o<='1';
cmd_loadop3_o<=opcode(0);
-- Setting op3_o here only affects the call instruction
op3_o<=next_ip_i&"00";
end if;
if opcode="011000" then
-- Note: (a or b) = (a and b) or (a xor b)
if opcode(5 downto 1)="01100" then
cmd_and_o<='1';
end if;
if opcode="011001" then
cmd_or_o<='1';
end if;
if opcode="011010" then
if opcode="011010" or opcode="011001" then
cmd_xor_o<='1';
end if;
227,8 → 239,6
cmd_shift_o<='1';
end if;
cmd_shift_right_o<=opcode(1);
if opcode(5 downto 4)="11" then
cmd_cmp_o<='1';
cmd_negate_op2_o<='1';
235,9 → 245,7
end if;
rd1_select<=t1;
rd1_direct<=std_logic_vector(resize(signed(rd1),rd1_direct'length));
rd2_select<=t2;
rd2_direct<=std_logic_vector(resize(signed(rd2),rd2_direct'length));
dst_out<=destination;
/rtl/lxp32_divider.vhd
5,8 → 5,8
--
-- Copyright (c) 2016 by Alex I. Kuznetsov
--
-- Based on the NRD (Non Restoring Division) algorithm. One division
-- takes 37 cycles.
-- Based on the NRD (Non Restoring Division) algorithm. Takes
-- 36 cycles to calculate quotient (37 for remainder).
---------------------------------------------------------------------
 
library ieee;
21,9 → 21,9
op1_i: in std_logic_vector(31 downto 0);
op2_i: in std_logic_vector(31 downto 0);
signed_i: in std_logic;
rem_i: in std_logic;
ce_o: out std_logic;
quotient_o: out std_logic_vector(31 downto 0);
remainder_o: out std_logic_vector(31 downto 0)
result_o: out std_logic_vector(31 downto 0)
);
end entity;
 
31,15 → 31,11
 
-- Complementor signals
 
signal compl1_inv: std_logic;
signal compl2_inv: std_logic;
signal compl1_mux: std_logic_vector(31 downto 0);
signal compl2_mux: std_logic_vector(31 downto 0);
signal compl1_out: std_logic_vector(31 downto 0);
signal compl2_out: std_logic_vector(31 downto 0);
signal compl_inv: std_logic;
signal compl_mux: std_logic_vector(31 downto 0);
signal compl_out: std_logic_vector(31 downto 0);
 
signal inv_q: std_logic;
signal inv_r: std_logic;
signal inv_res: std_logic;
 
-- Divider FSM signals
 
47,6 → 43,7
 
signal dividend: unsigned(31 downto 0);
signal divisor: unsigned(32 downto 0);
signal want_remainder: std_logic;
 
signal partial_remainder: unsigned(32 downto 0);
signal addend: unsigned(32 downto 0);
61,43 → 58,39
-- Output restoration signals
 
signal remainder_corrector: unsigned(31 downto 0);
signal remainder_res: unsigned(31 downto 0);
signal quotient_res: unsigned(31 downto 0);
signal remainder_corrector_1: std_logic;
signal remainder_pos: unsigned(31 downto 0);
signal result_pos: unsigned(31 downto 0);
 
begin
 
compl1_inv<=op1_i(31) and signed_i when ce_i='1' else inv_q;
compl2_inv<=op2_i(31) and signed_i when ce_i='1' else inv_r;
compl_inv<=op1_i(31) and signed_i when ce_i='1' else inv_res;
compl_mux<=op1_i when ce_i='1' else std_logic_vector(result_pos);
 
compl1_mux<=op1_i when ce_i='1' else std_logic_vector(quotient_res);
compl2_mux<=op2_i when ce_i='1' else std_logic_vector(remainder_res);
 
compl_op1_inst: entity work.lxp32_compl(rtl)
port map(
clk_i=>clk_i,
compl_i=>compl1_inv,
d_i=>compl1_mux,
d_o=>compl1_out
compl_i=>compl_inv,
d_i=>compl_mux,
d_o=>compl_out
);
 
compl_op2_inst: entity work.lxp32_compl(rtl)
port map(
clk_i=>clk_i,
compl_i=>compl2_inv,
d_i=>compl2_mux,
d_o=>compl2_out
);
 
process (clk_i) is
begin
if rising_edge(clk_i) then
if rst_i='1' then
fsm_ce<='0';
want_remainder<='-';
inv_res<='-';
else
fsm_ce<=ce_i;
if ce_i='1' then
inv_q<=(op1_i(31) xor op2_i(31)) and signed_i;
inv_r<=op1_i(31) and signed_i;
want_remainder<=rem_i;
if rem_i='1' then
inv_res<=op1_i(31) and signed_i;
else
inv_res<=(op1_i(31) xor op2_i(31)) and signed_i;
end if;
end if;
end if;
end if;
112,7 → 105,7
sum<=partial_remainder+addend+(to_unsigned(0,32)&sum_subtract);
sum_positive<=not sum(32);
 
-- Divisor state machine
-- Divider state machine
 
process (clk_i) is
begin
120,26 → 113,38
if rst_i='1' then
cnt<=0;
ceo<='0';
divisor<=(others=>'-');
dividend<=(others=>'-');
partial_remainder<=(others=>'-');
sum_subtract<='-';
else
ceo<='0';
if cnt=1 then
ceo<='1';
else
ceo<='0';
end if;
if ce_i='1' then
divisor(31 downto 0)<=unsigned(op2_i);
divisor(32)<=op2_i(31) and signed_i;
end if;
if fsm_ce='1' then
dividend<=unsigned(compl1_out(30 downto 0)&"0");
divisor<=unsigned("0"&compl2_out);
partial_remainder<=to_unsigned(0,32)&compl1_out(31);
sum_subtract<='1';
cnt<=34;
elsif cnt>0 then
dividend<=unsigned(compl_out(30 downto 0)&"0");
partial_remainder<=to_unsigned(0,32)&compl_out(31);
sum_subtract<=not divisor(32);
if want_remainder='1' then
cnt<=34;
else
cnt<=33;
end if;
else
partial_remainder<=sum(31 downto 0)&dividend(31);
sum_subtract<=sum_positive;
sum_subtract<=sum_positive xor divisor(32);
dividend<=dividend(30 downto 0)&sum_positive;
if cnt=1 then
ceo<='1';
if cnt>0 then
cnt<=cnt-1;
end if;
cnt<=cnt-1;
else
dividend<=(others=>'-');
divisor<=(others=>'-');
partial_remainder<=(others=>'-');
end if;
end if;
end if;
151,15 → 156,17
begin
if rising_edge(clk_i) then
for i in remainder_corrector'range loop
remainder_corrector(i)<=divisor(i) and not sum_positive;
remainder_corrector(i)<=(divisor(i) xor divisor(32)) and not sum_positive;
end loop;
quotient_res<=dividend;
remainder_res<=partial_remainder(32 downto 1)+remainder_corrector;
remainder_corrector_1<=divisor(32) and not sum_positive;
remainder_pos<=partial_remainder(32 downto 1)+remainder_corrector+
(to_unsigned(0,31)&remainder_corrector_1);
end if;
end process;
 
quotient_o<=compl1_out;
remainder_o<=compl2_out;
result_pos<=remainder_pos when want_remainder='1' else dividend;
 
result_o<=compl_out;
ce_o<=ceo;
 
end architecture;
/rtl/lxp32_execute.vhd
34,7 → 34,6
cmd_jump_i: in std_logic;
cmd_negate_op2_i: in std_logic;
cmd_and_i: in std_logic;
cmd_or_i: in std_logic;
cmd_xor_i: in std_logic;
cmd_shift_i: in std_logic;
cmd_shift_right_i: in std_logic;
66,9 → 65,7
jump_dst_o: out std_logic_vector(29 downto 0);
jump_ready_i: in std_logic;
interrupt_return_o: out std_logic;
interrupts_enabled_o: out std_logic_vector(7 downto 0);
interrupts_blocked_o: out std_logic_vector(7 downto 0)
interrupt_return_o: out std_logic
);
end entity;
 
116,8 → 113,6
-- Signals related to interrupt handling
 
signal interrupt_return: std_logic:='0';
signal interrupts_enabled: std_logic_vector(7 downto 0):=(others=>'0');
signal interrupts_blocked: std_logic_vector(7 downto 0):=(others=>'0');
 
begin
 
148,7 → 143,6
cmd_cmp_i=>cmd_cmp_i,
cmd_negate_op2_i=>cmd_negate_op2_i,
cmd_and_i=>cmd_and_i,
cmd_or_i=>cmd_or_i,
cmd_xor_i=>cmd_xor_i,
cmd_shift_i=>cmd_shift_i,
cmd_shift_right_i=>cmd_shift_right_i,
182,11 → 176,12
if rst_i='1' then
jump_valid<='0';
interrupt_return<='0';
jump_dst<=(others=>'-');
else
if jump_valid='0' then
jump_dst<=op1_i(31 downto 2);
if can_execute='1' and cmd_jump_i='1' and jump_condition='1' then
jump_valid<='1';
jump_dst<=op1_i(31 downto 2);
interrupt_return<=op1_i(0);
end if;
elsif jump_ready_i='1' then
262,22 → 257,4
sp_waddr_o<=result_regaddr;
sp_wdata_o<=result_mux;
 
process (clk_i) is
begin
if rising_edge(clk_i) then
if rst_i='1' then
interrupts_enabled<=(others=>'0');
interrupts_blocked<=(others=>'0');
else
if result_valid='1' and result_regaddr=X"FC" then
interrupts_enabled<=result_mux(7 downto 0);
interrupts_blocked<=result_mux(15 downto 8);
end if;
end if;
end if;
end process;
 
interrupts_enabled_o<=interrupts_enabled;
interrupts_blocked_o<=interrupts_blocked;
 
end architecture;
/rtl/lxp32_fetch.vhd
14,7 → 14,7
 
entity lxp32_fetch is
generic(
START_ADDR: std_logic_vector(29 downto 0)
START_ADDR: std_logic_vector(31 downto 0)
);
port(
clk_i: in std_logic;
26,6 → 26,7
lli_busy_i: in std_logic;
word_o: out std_logic_vector(31 downto 0);
current_ip_o: out std_logic_vector(29 downto 0);
next_ip_o: out std_logic_vector(29 downto 0);
valid_o: out std_logic;
ready_i: in std_logic;
41,7 → 42,7
signal init: std_logic:='1';
signal init_cnt: unsigned(7 downto 0):=(others=>'0');
 
signal fetch_addr: std_logic_vector(29 downto 0):=START_ADDR;
signal fetch_addr: std_logic_vector(29 downto 0):=START_ADDR(31 downto 2);
 
signal next_word: std_logic;
signal suppress_re: std_logic:='0';
50,14 → 51,17
 
signal fifo_rst: std_logic;
signal fifo_we: std_logic;
signal fifo_din: std_logic_vector(61 downto 0);
signal fifo_din: std_logic_vector(31 downto 0);
signal fifo_re: std_logic;
signal fifo_dout: std_logic_vector(61 downto 0);
signal fifo_dout: std_logic_vector(31 downto 0);
signal fifo_empty: std_logic;
signal fifo_full: std_logic;
 
signal jr: std_logic:='0';
 
signal next_ip: std_logic_vector(fetch_addr'range);
signal current_ip: std_logic_vector(fetch_addr'range);
 
begin
 
-- INIT state machine (to initialize all registers)
96,10 → 100,11
begin
if rising_edge(clk_i) then
if rst_i='1' then
fetch_addr<=START_ADDR;
fetch_addr<=START_ADDR(31 downto 2);
requested<='0';
jr<='0';
suppress_re<='0';
next_ip<=(others=>'-');
else
jr<='0';
-- Suppress LLI request if jump signal is active but will not be processed
112,6 → 117,13
requested<=re and not (jump_valid_i and not jr);
end if;
if next_word='1' then
-- It's not immediately obvious why, but current_ip and next_ip will contain
-- the addresses of the current instruction and the next instruction to be
-- fetched, respectively, by the time the instruction is passed to the decode
-- stage. Basically, this is because when either the decoder or the IBUS
-- stalls, the fetch_addr counter will also stop incrementing.
next_ip<=fetch_addr;
current_ip<=next_ip;
if jump_valid_i='1' and jr='0' then
fetch_addr<=jump_dst_i;
jr<='1';
134,12 → 146,12
 
fifo_rst<=rst_i or (jump_valid_i and not jr);
fifo_we<=requested and not lli_busy_i;
fifo_din<=fetch_addr&lli_dat_i;
fifo_din<=lli_dat_i;
fifo_re<=ready_i and not fifo_empty;
 
ubuf_inst: entity work.lxp32_ubuf(rtl)
generic map(
DATA_WIDTH=>62
DATA_WIDTH=>32
)
port map(
clk_i=>clk_i,
154,9 → 166,61
full_o=>fifo_full
);
 
next_ip_o<=fifo_dout(61 downto 32);
 
word_o<=fifo_dout(31 downto 0) when init='1' else X"40"&std_logic_vector(init_cnt)&X"0000";
next_ip_o<=next_ip;
current_ip_o<=current_ip;
word_o<=fifo_dout when init='1' else X"40"&std_logic_vector(init_cnt)&X"0000";
valid_o<=not fifo_empty or not init;
 
-- Note: the following code contains a few simulation-only assertions
-- to check that current_ip and next_ip signals, used in procedure calls
-- and interrupts, are correct.
-- This code should be ignored by a synthesizer since it doesn't drive
-- any signals, but we also surround it by metacomments, just in case.
 
-- synthesis translate_off
 
process (clk_i) is
type Pair is record
addr: std_logic_vector(fetch_addr'range);
data: std_logic_vector(31 downto 0);
end record;
type Pairs is array (7 downto 0) of Pair;
variable buf: Pairs;
variable count: integer range buf'range:=0;
variable current_pair: Pair;
begin
if rising_edge(clk_i) then
if fifo_rst='1' then -- jump
count:=0;
elsif fifo_we='1' then -- LLI returned data
current_pair.data:=fifo_din;
buf(count):=current_pair;
count:=count+1;
end if;
if re='1' and lli_busy_i='0' then -- data requested
current_pair.addr:=fetch_addr;
end if;
if fifo_empty='0' and fifo_rst='0' then -- fetch output is valid
assert count>0
report "Fetch: buffer should be empty"
severity failure;
assert buf(0).data=fifo_dout
report "Fetch: incorrect data"
severity failure;
assert buf(0).addr=current_ip
report "Fetch: incorrect current_ip"
severity failure;
assert std_logic_vector(unsigned(buf(0).addr)+1)=next_ip
report "Fetch: incorrect next_ip"
severity failure;
if ready_i='1' then
buf(buf'high-1 downto 0):=buf(buf'high downto 1); -- we don't care about the highest item
count:=count-1;
end if;
end if;
end if;
end process;
 
-- synthesis translate_on
 
end architecture;
/rtl/lxp32_icache.vhd
111,12 → 111,12
 
ram_inst: entity work.lxp32_ram256x32(rtl)
port map(
wclk_i=>clk_i,
clk_i=>clk_i,
we_i=>ram_we,
waddr_i=>ram_waddr,
wdata_i=>wbm_dat_i,
rclk_i=>clk_i,
re_i=>ram_re,
raddr_i=>ram_raddr,
rdata_o=>lli_dat_o
202,6 → 202,22
burst_cnt<=0;
wb_stb<='0';
wrap_cnt<=0;
wb_cti<=(others=>'-');
burst1<='-';
current_offset<=(others=>'-');
start_offset<=(others=>'-');
current_base<=(others=>'-');
next_base<=(others=>'-');
prev_base<=(others=>'-');
-- To suppress numeric_std warnings
-- synthesis translate_off
current_offset<=(others=>'0');
start_offset<=(others=>'0');
current_base<=(others=>'0');
next_base<=(others=>'0');
prev_base<=(others=>'0');
-- synthesis translate_on
else
if burst_cnt=0 and init='1' then
if miss='1' and near_miss='0' then
/rtl/lxp32_interrupt_mux.vhd
20,13 → 20,14
irq_i: in std_logic_vector(7 downto 0);
interrupts_enabled_i: in std_logic_vector(7 downto 0);
interrupts_blocked_i: in std_logic_vector(7 downto 0);
interrupt_valid_o: out std_logic;
interrupt_vector_o: out std_logic_vector(2 downto 0);
interrupt_ready_i: in std_logic;
interrupt_return_i: in std_logic
interrupt_return_i: in std_logic;
sp_waddr_i: in std_logic_vector(7 downto 0);
sp_we_i: in std_logic;
sp_wdata_i: in std_logic_vector(31 downto 0)
);
end entity;
 
41,6 → 42,9
 
signal interrupt_valid: std_logic:='0';
 
signal interrupts_enabled: std_logic_vector(7 downto 0):=(others=>'0');
signal interrupts_blocked: std_logic_vector(7 downto 0):=(others=>'0');
 
begin
 
-- Note: "disabled" interrupts (i.e. for which interrupts_enabled_i(i)='0')
57,17 → 61,18
pending_interrupts<=(others=>'0');
state<=Ready;
interrupt_valid<='0';
interrupt_vector_o<=(others=>'-');
else
irq_reg<=irq_i;
pending_interrupts<=(pending_interrupts or
(irq_i and not irq_reg)) and
interrupts_enabled_i;
interrupts_enabled;
case state is
when Ready =>
for i in pending_interrupts'reverse_range loop -- lower interrupts have priority
if pending_interrupts(i)='1' and interrupts_blocked_i(i)='0' then
if pending_interrupts(i)='1' and interrupts_blocked(i)='0' then
pending_interrupts(i)<='0';
interrupt_valid<='1';
interrupt_vector_o<=std_logic_vector(to_unsigned(i,3));
91,4 → 96,17
 
interrupt_valid_o<=interrupt_valid;
 
process (clk_i) is
begin
if rising_edge(clk_i) then
if rst_i='1' then
interrupts_enabled<=(others=>'0');
interrupts_blocked<=(others=>'0');
elsif sp_we_i='1' and sp_waddr_i=X"FC" then
interrupts_enabled<=sp_wdata_i(7 downto 0);
interrupts_blocked<=sp_wdata_i(15 downto 8);
end if;
end if;
end process;
 
end architecture;
/rtl/lxp32_mul_dsp.vhd
28,9 → 28,9
 
architecture rtl of lxp32_mul_dsp is
 
signal pp00: unsigned(31 downto 0);
signal pp01: unsigned(31 downto 0);
signal pp10: unsigned(31 downto 0);
signal pp00: std_logic_vector(31 downto 0);
signal pp01: std_logic_vector(31 downto 0);
signal pp10: std_logic_vector(31 downto 0);
 
signal product: unsigned(31 downto 0);
 
43,7 → 43,7
clk_i=>clk_i,
a_i=>op1_i(15 downto 0),
b_i=>op2_i(15 downto 0),
unsigned(p_o)=>pp00
p_o=>pp00
);
 
mul01_inst: entity work.lxp32_mul16x16
51,7 → 51,7
clk_i=>clk_i,
a_i=>op1_i(15 downto 0),
b_i=>op2_i(31 downto 16),
unsigned(p_o)=>pp01
p_o=>pp01
);
 
mul10_inst: entity work.lxp32_mul16x16
59,11 → 59,11
clk_i=>clk_i,
a_i=>op1_i(31 downto 16),
b_i=>op2_i(15 downto 0),
unsigned(p_o)=>pp10
p_o=>pp10
);
 
product(31 downto 16)<=pp00(31 downto 16)+pp01(15 downto 0)+pp10(15 downto 0);
product(15 downto 0)<=pp00(15 downto 0);
product(31 downto 16)<=unsigned(pp00(31 downto 16))+unsigned(pp01(15 downto 0))+unsigned(pp10(15 downto 0));
product(15 downto 0)<=unsigned(pp00(15 downto 0));
result_o<=std_logic_vector(product);
 
process (clk_i) is
/rtl/lxp32_mul_opt.vhd
65,6 → 65,7
 
signal cnt: integer range 0 to 4:=0;
 
signal result: std_logic_vector(result_o'range);
signal ceo: std_logic:='0';
 
begin
109,8 → 110,17
if rst_i='1' then
ceo<='0';
cnt<=0;
reg1<=(others=>'-');
reg2<=(others=>'-');
acc_sum<=(others=>'-');
acc_carry<=(others=>'-');
else
ceo<='0';
if cnt=1 then
ceo<='1';
else
ceo<='0';
end if;
if ce_i='1' then
cnt<=4;
reg1<=unsigned(op1_i);
117,14 → 127,13
reg2<=unsigned(op2_i);
acc_sum<=(others=>'0');
acc_carry<=(others=>'0');
elsif cnt>0 then
else
acc_sum<=pp_sum(7);
acc_carry<=pp_carry(7)(acc_carry'range);
reg1<=reg1(reg1'high-8 downto 0)&X"00";
reg2<=X"00"&reg2(reg2'high downto 8);
cnt<=cnt-1;
if cnt=1 then
ceo<='1';
if cnt>0 then
cnt<=cnt-1;
end if;
end if;
end if;
131,7 → 140,29
end if;
end process;
 
result_o<=std_logic_vector(acc_sum+acc_carry);
result<=std_logic_vector(acc_sum+acc_carry);
 
result_o<=result;
ce_o<=ceo;
 
-- A simulation-time multiplication check
 
-- synthesis translate_off
 
process (clk_i) is
variable p: unsigned(op1_i'length+op2_i'length-1 downto 0);
begin
if rising_edge(clk_i) then
if ce_i='1' then
p:=unsigned(op1_i)*unsigned(op2_i);
elsif ceo='1' then
assert result=std_logic_vector(p(result'range))
report "Incorrect multiplication result"
severity failure;
end if;
end if;
end process;
 
-- synthesis translate_on
 
end architecture;
/rtl/lxp32_mul_seq.vhd
44,20 → 44,27
if rst_i='1' then
ceo<='0';
cnt<=0;
reg1<=(others=>'-');
reg2<=(others=>'-');
acc_sum<=(others=>'-');
else
ceo<='0';
if cnt=1 then
ceo<='1';
else
ceo<='0';
end if;
if ce_i='1' then
cnt<=32;
reg1<=unsigned(op1_i);
reg2<=unsigned(op2_i);
acc_sum<=(others=>'0');
elsif cnt>0 then
else
acc_sum<=acc_sum+pp;
reg1<=reg1(reg1'high-1 downto 0)&"0";
reg2<="0"&reg2(reg2'high downto 1);
cnt<=cnt-1;
if cnt=1 then
ceo<='1';
if cnt>0 then
cnt<=cnt-1;
end if;
end if;
end if;
/rtl/lxp32_ram256x32.vhd
17,12 → 17,12
 
entity lxp32_ram256x32 is
port(
wclk_i: in std_logic;
clk_i: in std_logic;
we_i: in std_logic;
waddr_i: in std_logic_vector(7 downto 0);
wdata_i: in std_logic_vector(31 downto 0);
rclk_i: in std_logic;
re_i: in std_logic;
raddr_i: in std_logic_vector(7 downto 0);
rdata_o: out std_logic_vector(31 downto 0)
35,7 → 35,7
signal ram: ram_type:=(others=>(others=>'0')); -- zero-initialize for SRAM-based FPGAs
 
attribute syn_ramstyle: string;
attribute syn_ramstyle of ram: signal is "block_ram,no_rw_check";
attribute syn_ramstyle of ram: signal is "no_rw_check";
attribute ram_style: string; -- for Xilinx
attribute ram_style of ram: signal is "block";
 
43,9 → 43,9
 
-- Write port
 
process (wclk_i) is
process (clk_i) is
begin
if rising_edge(wclk_i) then
if rising_edge(clk_i) then
if we_i='1' then
ram(to_integer(unsigned(waddr_i)))<=wdata_i;
end if;
54,11 → 54,15
 
-- Read port
 
process (rclk_i) is
process (clk_i) is
begin
if rising_edge(rclk_i) then
if rising_edge(clk_i) then
if re_i='1' then
rdata_o<=ram(to_integer(to_01(unsigned(raddr_i))));
if is_x(raddr_i) then -- to avoid numeric_std warnings during simulation
rdata_o<=(others=>'X');
else
rdata_o<=ram(to_integer(unsigned(raddr_i)));
end if;
end if;
end if;
end process;
/rtl/lxp32_scratchpad.vhd
42,12 → 42,12
 
ram_inst1: entity work.lxp32_ram256x32(rtl)
port map(
wclk_i=>clk_i,
clk_i=>clk_i,
we_i=>we_i,
waddr_i=>waddr_i,
wdata_i=>wdata_i,
rclk_i=>clk_i,
re_i=>'1',
raddr_i=>raddr1_i,
rdata_o=>ram1_rdata
57,12 → 57,12
 
ram_inst2: entity work.lxp32_ram256x32(rtl)
port map(
wclk_i=>clk_i,
clk_i=>clk_i,
we_i=>we_i,
waddr_i=>waddr_i,
wdata_i=>wdata_i,
rclk_i=>clk_i,
re_i=>'1',
raddr_i=>raddr2_i,
rdata_o=>ram2_rdata
/rtl/lxp32_shifter.vhd
68,6 → 68,10
if rising_edge(clk_i) then
if rst_i='1' then
ceo<='0';
stage2_data<=(others=>'-');
stage2_s<=(others=>'-');
stage2_fill<='-';
stage2_right<='-';
else
ceo<=ce_i;
stage2_data<=cascades(2);
/rtl/lxp32_ubuf.vhd
42,8 → 42,6
signal regs: regs_type;
signal regs_mux: regs_type;
 
signal wpointer: std_logic_vector(2 downto 0):="001";
 
begin
 
we<=we_i and not full;
53,23 → 51,23
begin
if rising_edge(clk_i) then
if rst_i='1' then
wpointer<="001";
empty<='1';
full<='0';
regs<=(others=>(others=>'-'));
else
if re='0' then
regs<=regs_mux;
regs(0)<=regs_mux(0);
else
regs(0)<=regs_mux(1);
end if;
regs(1)<=regs_mux(1);
if we='1' and re='0' then
wpointer<=wpointer(1 downto 0)&"0";
empty<='0';
full<=wpointer(1);
full<=not empty;
elsif we='0' and re='1' then
wpointer<="0"&wpointer(2 downto 1);
empty<=wpointer(1);
empty<=not full;
full<='0';
end if;
end if;
76,9 → 74,8
end if;
end process;
 
mux: for i in regs_mux'range generate
regs_mux(i)<=regs(i) when we='0' or wpointer(i)='0' else d_i;
end generate;
regs_mux(0)<=regs(0) when we='0' or empty='0' else d_i;
regs_mux(1)<=regs(1) when we='0' or empty='1' else d_i;
 
d_o<=regs(0);
empty_o<=empty;
/rtl/lxp32c_top.vhd
32,7 → 32,7
IBUS_BURST_SIZE: integer:=16;
IBUS_PREFETCH_SIZE: integer:=32;
MUL_ARCH: string:="dsp";
START_ADDR: std_logic_vector(29 downto 0):=(others=>'0')
START_ADDR: std_logic_vector(31 downto 0):=(others=>'0')
);
port(
clk_i: in std_logic;
/rtl/lxp32u_top.vhd
27,7 → 27,7
DBUS_RMW: boolean:=false;
DIVIDER_EN: boolean:=true;
MUL_ARCH: string:="dsp";
START_ADDR: std_logic_vector(29 downto 0):=(others=>'0')
START_ADDR: std_logic_vector(31 downto 0):=(others=>'0')
);
port(
clk_i: in std_logic;
/tools/src/lxp32asm/assembler.cpp
30,6 → 30,7
_state=Initial;
_currentFileName=filename;
processFileRecursive(filename);
 
// Examine symbol table
for(auto const &sym: _obj.symbols()) {
if(sym.second.type==LinkableObject::Unknown&&!sym.second.refs.empty()) {
40,6 → 41,8
throw std::runtime_error(msg.str());
}
}
for(auto const &sym: _exportedSymbols) _obj.exportSymbol(sym);
}
 
void Assembler::processFileRecursive(const std::string &filename) {
63,16 → 66,14
_line++;
}
if(_state!=Initial) throw std::runtime_error("Unexpected end of file");
_line=savedLine;
_state=savedState;
_currentFileName=savedFileName;
for(auto const &label: _currentLabels) {
_obj.addLocalSymbol(label,
static_cast<LinkableObject::Word>(_obj.codeSize()));
}
_currentLabels.clear();
if(!_currentLabels.empty())
throw std::runtime_error("Symbol definition must be followed by an instruction or data definition statement");
}
 
void Assembler::addIncludeSearchDir(const std::string &dir) {
127,7 → 128,7
else throw std::runtime_error(std::string("Unexpected character: \"")+ch+"\"");
break;
case Word:
if(std::isalnum(ch)||ch=='_'||ch=='@') word+=ch;
if(std::isalnum(ch)||ch=='_'||ch=='@'||ch=='+'||ch=='-') word+=ch;
else {
i--;
_state=Initial;
206,7 → 207,12
// Perform macro substitution
for(auto &token: list) {
auto it=_macros.find(token);
if(it==_macros.end()) newlist.push_back(std::move(token));
// Note: we don't expand a macro identifier in the #define statement
// since that would lead to counter-intuitive results
if(it==_macros.end()||
(newlist.size()==1&&newlist[0]=="#define")||
(newlist.size()==3&&newlist[1]==":"&&newlist[2]=="#define"))
newlist.push_back(std::move(token));
else for(auto const &replace: it->second) newlist.push_back(replace);
}
list=std::move(newlist);
233,7 → 239,7
else rva=elaborateInstruction(list);
for(auto const &label: _currentLabels) {
_obj.addLocalSymbol(label,rva);
_obj.addSymbol(label,rva);
}
_currentLabels.clear();
}
243,15 → 249,24
assert(!list.empty());
if(list[0]=="#define") {
if(list.size()<3) throw std::runtime_error("Wrong number of tokens in the directive");
if(!validateIdentifier(list[1])) throw std::runtime_error("Ill-formed identifier: \""+list[1]+"\"");
if(list.size()<3)
throw std::runtime_error("Wrong number of tokens in the directive");
if(_macros.find(list[1])!=_macros.end())
throw std::runtime_error("Macro \""+list[1]+"\" has been already defined");
if(!validateIdentifier(list[1]))
throw std::runtime_error("Ill-formed identifier: \""+list[1]+"\"");
_macros.emplace(list[1],TokenList(list.begin()+2,list.end()));
}
else if(list[0]=="#extern") {
else if(list[0]=="#export") {
if(list.size()!=2) std::runtime_error("Wrong number of tokens in the directive");
if(!validateIdentifier(list[1])) throw std::runtime_error("Ill-formed identifier: \""+list[1]+"\"");
_obj.addExternalSymbol(list[1]);
_exportedSymbols.push_back(list[1]);
}
else if(list[0]=="#import") {
if(list.size()!=2) std::runtime_error("Wrong number of tokens in the directive");
if(!validateIdentifier(list[1])) throw std::runtime_error("Ill-formed identifier: \""+list[1]+"\"");
_obj.addImportedSymbol(list[1]);
}
else if(list[0]=="#include") {
if(list.size()!=2) std::runtime_error("Wrong number of tokens in the directive");
auto filename=Utils::dequoteString(list[1]);
285,6 → 300,8
if(list.size()>2) throw std::runtime_error("Unexpected token: \""+list[2]+"\"");
std::size_t align=4;
if(list.size()>1) align=static_cast<std::size_t>(numericLiteral(list[1]));
if(!Utils::isPowerOf2(align)) throw std::runtime_error("Alignment must be a power of 2");
if(align<4) throw std::runtime_error("Alignment must be at least 4");
rva=_obj.addPadding(align);
}
else if(list[0]==".reserve") {
351,6 → 368,7
else if(list[0]=="jmp") encodeJmp(list);
else if(list[0]=="iret") encodeIret(list);
else if(list[0]=="lc") encodeLc(list);
else if(list[0]=="lcs") encodeLcs(list);
else if(list[0]=="lsb") encodeLsb(list);
else if(list[0]=="lub") encodeLub(list);
else if(list[0]=="lw") encodeLw(list);
358,6 → 376,7
else if(list[0]=="modu") encodeModu(list);
else if(list[0]=="mov") encodeMov(list);
else if(list[0]=="mul") encodeMul(list);
else if(list[0]=="neg") encodeNeg(list);
else if(list[0]=="nop") encodeNop(list);
else if(list[0]=="not") encodeNot(list);
else if(list[0]=="or") encodeOr(list);
456,7 → 475,7
arglist.push_back(std::move(a));
}
else if(list[i].size()==3&&list[i].substr(0,2)=="iv"&&
std::isdigit(list[i][2])) // interrupt vector
list[i][2]>='0'&&list[i][2]<='7') // interrupt vector
{
a.type=Operand::Register;
a.reg=240+(list[i][2]-'0');
598,11 → 617,6
void Assembler::encodeDivs(const TokenList &list) {
auto args=getOperands(list);
if(args.size()!=3) throw std::runtime_error("divs instruction requires 3 operands");
if(args[2].type==Operand::NumericLiteral&&args[2].i==0) {
std::cerr<<currentFileName()<<":"<<line()<<": ";
std::cerr<<"Warning: Division by zero"<<std::endl;
}
LinkableObject::Word w=0x54000000;
encodeDstOperand(w,args[0]);
encodeRd1Operand(w,args[1]);
613,11 → 627,6
void Assembler::encodeDivu(const TokenList &list) {
auto args=getOperands(list);
if(args.size()!=3) throw std::runtime_error("divu instruction requires 3 operands");
if(args[2].type==Operand::NumericLiteral&&args[2].i==0) {
std::cerr<<currentFileName()<<":"<<line()<<": ";
std::cerr<<"Warning: Division by zero"<<std::endl;
}
LinkableObject::Word w=0x50000000;
encodeDstOperand(w,args[0]);
encodeRd1Operand(w,args[1]);
656,8 → 665,13
_obj.addWord(w);
if(args[1].type==Operand::Identifier) {
auto symRva=_obj.addWord(static_cast<LinkableObject::Word>(args[1].i));
_obj.addReference(args[1].str,currentFileName(),line(),symRva);
LinkableObject::Reference ref;
ref.source=currentFileName();
ref.line=line();
ref.rva=_obj.addWord(0);
ref.offset=args[1].i;
ref.type=LinkableObject::Regular;
_obj.addReference(args[1].str,ref);
}
else if(args[1].type==Operand::NumericLiteral) {
_obj.addWord(static_cast<LinkableObject::Word>(args[1].i));
665,6 → 679,33
else throw std::runtime_error("\""+args[1].str+"\": bad argument");
}
 
void Assembler::encodeLcs(const TokenList &list) {
auto args=getOperands(list);
if(args.size()!=2) throw std::runtime_error("lcs instruction requires 2 operands");
LinkableObject::Word w=0xA0000000;
encodeDstOperand(w,args[0]);
if(args[1].type==Operand::NumericLiteral) {
if((args[1].i<-1048576||args[1].i>1048575)&&(args[1].i<0xFFF00000||args[1].i>0xFFFFFFFF))
throw std::runtime_error("\""+args[1].str+"\": out of range");
auto c=static_cast<LinkableObject::Word>(args[1].i)&0x1FFFFF;
w|=(c&0xFFFF);
w|=((c<<8)&0x1F000000);
_obj.addWord(w);
}
else if(args[1].type==Operand::Identifier) {
LinkableObject::Reference ref;
ref.source=currentFileName();
ref.line=line();
ref.rva=_obj.addWord(w);
ref.offset=args[1].i;
ref.type=LinkableObject::Short;
_obj.addReference(args[1].str,ref);
}
else throw std::runtime_error("\""+args[1].str+"\": bad argument");
}
 
void Assembler::encodeLsb(const TokenList &list) {
auto args=getOperands(list);
if(args.size()!=2) throw std::runtime_error("lsb instruction requires 2 operands");
735,6 → 776,16
_obj.addWord(w);
}
 
void Assembler::encodeNeg(const TokenList &list) {
// Note: "neg" is not a real instruction, but an alias for "sub dst, 0, src"
auto args=getOperands(list);
if(args.size()!=2) throw std::runtime_error("neg instruction requires 2 operands");
LinkableObject::Word w=0x44000000;
encodeDstOperand(w,args[0]);
encodeRd2Operand(w,args[1]);
_obj.addWord(w);
}
 
void Assembler::encodeNop(const TokenList &list) {
auto args=getOperands(list);
if(!args.empty()) throw std::runtime_error("nop instruction doesn't take operands");
/tools/src/lxp32asm/assembler.h
41,6 → 41,7
std::vector<std::string> _currentLabels;
std::string _currentFileName;
std::vector<std::string> _includeSearchDirs;
std::vector<std::string> _exportedSymbols;
public:
void processFile(const std::string &filename);
80,6 → 81,7
void encodeJmp(const TokenList &list);
void encodeIret(const TokenList &list);
void encodeLc(const TokenList &list);
void encodeLcs(const TokenList &list);
void encodeLsb(const TokenList &list);
void encodeLub(const TokenList &list);
void encodeLw(const TokenList &list);
87,6 → 89,7
void encodeModu(const TokenList &list);
void encodeMov(const TokenList &list);
void encodeMul(const TokenList &list);
void encodeNeg(const TokenList &list);
void encodeNop(const TokenList &list);
void encodeNot(const TokenList &list);
void encodeOr(const TokenList &list);
/tools/src/lxp32asm/linkableobject.cpp
96,7 → 96,7
_code[rva++]=static_cast<Byte>(value>>24);
}
 
void LinkableObject::addLocalSymbol(const std::string &name,Word rva) {
void LinkableObject::addSymbol(const std::string &name,Word rva) {
auto &data=symbol(name);
if(data.type!=Unknown) throw std::runtime_error("Symbol \""+name+"\" is already defined");
data.type=Local;
103,15 → 103,23
data.rva=rva;
}
 
void LinkableObject::addExternalSymbol(const std::string &name) {
void LinkableObject::addImportedSymbol(const std::string &name) {
auto &data=symbol(name);
if(data.type!=Unknown) throw std::runtime_error("Symbol \""+name+"\" is already defined");
data.type=External;
data.type=Imported;
}
 
void LinkableObject::addReference(const std::string &symbolName,const std::string &source,int line,Word rva) {
void LinkableObject::exportSymbol(const std::string &name) {
auto it=_symbols.find(name);
if(it==_symbols.end()||it->second.type==Unknown) throw std::runtime_error("Undefined symbol \""+name+"\"");
if(it->second.type==Imported) throw std::runtime_error("Symbol \""+name+"\" can't be both imported and exported at the same time");
if(it->second.type==Exported) throw std::runtime_error("Symbol \""+name+"\" has been already exported");
it->second.type=Exported;
}
 
void LinkableObject::addReference(const std::string &symbolName,const Reference &ref) {
auto &data=symbol(symbolName);
data.refs.push_back({source,line,rva});
data.refs.push_back(ref);
}
 
LinkableObject::SymbolData &LinkableObject::symbol(const std::string &name) {
120,7 → 128,7
 
const LinkableObject::SymbolData &LinkableObject::symbol(const std::string &name) const {
auto const it=_symbols.find(name);
if(it==_symbols.end()) throw std::runtime_error("Undefined symbol");
if(it==_symbols.end()) throw std::runtime_error("Undefined symbol \""+name+"\"");
return it->second;
}
 
151,10 → 159,18
out<<std::endl;
out<<"Start Symbol"<<std::endl;
out<<"\tName "<<Utils::urlEncode(sym.first)<<std::endl;
if(sym.second.type==Local) out<<"\tRVA 0x"<<Utils::hex(sym.second.rva)<<std::endl;
else out<<"\tExternal"<<std::endl;
if(sym.second.type==Local) out<<"\tType Local"<<std::endl;
else if(sym.second.type==Exported) out<<"\tType Exported"<<std::endl;
else out<<"\tType Imported"<<std::endl;
if(sym.second.type!=Imported) out<<"\tRVA 0x"<<Utils::hex(sym.second.rva)<<std::endl;
for(auto const &ref: sym.second.refs) {
out<<"\tRef "<<Utils::urlEncode(ref.source)<<" "<<ref.line<<" 0x"<<Utils::hex(ref.rva)<<std::endl;
out<<"\tRef ";
out<<Utils::urlEncode(ref.source)<<" ";
out<<ref.line<<" ";
out<<"0x"<<Utils::hex(ref.rva)<<" ";
out<<ref.offset<<" ";
if(ref.type==Regular) out<<"Regular"<<std::endl;
else if(ref.type==Short) out<<"Short"<<std::endl;
}
out<<"End Symbol"<<std::endl;
}
231,10 → 247,15
if(tokens.size()<2) throw std::runtime_error("Unexpected end of line");
name=Utils::urlDecode(tokens[1]);
}
else if(tokens[0]=="External") data.type=External;
else if(tokens[0]=="Type") {
if(tokens.size()<2) throw std::runtime_error("Unexpected end of line");
if(tokens[1]=="Local") data.type=Local;
else if(tokens[1]=="Exported") data.type=Exported;
else if(tokens[1]=="Imported") data.type=Imported;
else throw std::runtime_error("Bad symbol type");
}
else if(tokens[0]=="RVA") {
if(tokens.size()<2) throw std::runtime_error("Unexpected end of line");
data.type=Local;
data.rva=std::strtoul(tokens[1].c_str(),NULL,0);
}
else if(tokens[0]=="Ref") {
243,6 → 264,10
ref.source=Utils::urlDecode(tokens[1]);
ref.line=std::strtoul(tokens[2].c_str(),NULL,0);
ref.rva=std::strtoul(tokens[3].c_str(),NULL,0);
ref.offset=std::strtoll(tokens[4].c_str(),NULL,0);
if(tokens[5]=="Regular") ref.type=Regular;
else if(tokens[5]=="Short") ref.type=Short;
else throw std::runtime_error("Invalid reference type: \""+tokens[5]+"\"");
data.refs.push_back(std::move(ref));
}
}
/tools/src/lxp32asm/linkableobject.h
20,12 → 20,17
public:
typedef unsigned char Byte;
typedef std::uint32_t Word;
typedef std::int_least64_t Integer;
enum SymbolType {Unknown,Local,External};
enum SymbolType {Unknown,Local,Exported,Imported};
enum RefType {Regular,Short};
struct Reference {
std::string source;
int line;
Word rva;
Integer offset;
RefType type;
};
struct SymbolData {
SymbolType type=Unknown;
32,6 → 37,7
Word rva;
std::vector<Reference> refs;
};
typedef std::map<std::string,SymbolData> SymbolTable;
private:
61,9 → 67,10
Word getWord(Word rva) const;
void replaceWord(Word rva,Word value);
void addLocalSymbol(const std::string &name,Word rva);
void addExternalSymbol(const std::string &name);
void addReference(const std::string &symbolName,const std::string &source,int line,Word rva);
void addSymbol(const std::string &name,Word rva);
void addImportedSymbol(const std::string &name);
void exportSymbol(const std::string &name);
void addReference(const std::string &symbolName,const Reference &ref);
SymbolData &symbol(const std::string &name);
const SymbolData &symbol(const std::string &name) const;
/tools/src/lxp32asm/linker.cpp
9,6 → 9,7
#include "linker.h"
 
#include "linkableobject.h"
#include "utils.h"
 
#include <iostream>
#include <fstream>
16,6 → 17,7
#include <map>
#include <stdexcept>
#include <cassert>
#include <algorithm>
 
void Linker::addObject(LinkableObject &obj) {
_objects.push_back(&obj);
29,14 → 31,8
// Determine entry point
if(_objects.size()==1) _entryObject=_objects[0];
else {
auto const it=_globalSymbolTable.find("entry");
if(it==_globalSymbolTable.end())
throw std::runtime_error("Entry point not defined: cannot find \"entry\" symbol");
if(it->second.rva!=0)
throw std::runtime_error(it->second.obj->name()+": Entry point must refer to the start of the object");
_entryObject=it->second.obj;
}
else if(_entryObject==nullptr)
throw std::runtime_error("Entry point not defined: cannot find \"entry\" or \"Entry\" symbol");
// Assign virtual addresses
placeObjects();
46,6 → 42,7
// Write binary data
writeObjects(writer);
_bytesWritten=writer.size();
}
 
void Linker::setBase(LinkableObject::Word base) {
60,6 → 57,41
_imageSize=size;
}
 
void Linker::generateMap(std::ostream &s) {
// Calculate the maximum length of a symbol name
std::size_t len=0;
for(auto const &obj: _objects) {
for(auto const &sym: obj->symbols()) {
if(sym.second.type!=LinkableObject::Imported)
len=std::max(len,sym.first.size());
}
}
len=std::max(len+3,std::size_t(8)); // width of the first column
s<<"Image base address: "<<Utils::hex(_base)<<std::endl;
s<<"Object alignment: "<<_align<<std::endl;
s<<"Image size: "<<(_bytesWritten/4)<<" words"<<std::endl;
s<<"Number of objects: "<<_objects.size()<<std::endl;
s<<std::endl;
for(auto const &obj: _objects) {
s<<"Object \""<<obj->name()<<"\" at address "<<Utils::hex(obj->virtualAddress())<<std::endl;
s<<std::endl;
std::multimap<LinkableObject::Word,std::pair<std::string,LinkableObject::SymbolData> > sorted;
for(auto const &sym: obj->symbols()) sorted.emplace(sym.second.rva,sym);
for(auto const &sym: sorted) {
if(sym.second.second.type==LinkableObject::Imported) continue;
s<<sym.second.first;
s<<std::string(len-sym.second.first.size(),' ');
s<<Utils::hex(obj->virtualAddress()+sym.second.second.rva);
if(sym.second.second.type==LinkableObject::Local) s<<" Local";
else s<<" Exported";
s<<std::endl;
}
s<<std::endl;
}
}
 
/*
* Private members
*/
67,14 → 99,31
void Linker::buildSymbolTable() {
_globalSymbolTable.clear();
// Build a table of exported symbols from all modules
for(auto const &obj: _objects) {
auto const &table=obj->symbols();
for(auto const &item: table) {
if((item.first=="entry"||item.first=="Entry")&&item.second.type!=LinkableObject::Imported) {
if(_entryObject) {
std::ostringstream msg;
msg<<obj->name()<<": Duplicate definition of the entry symbol ";
msg<<"(previously defined in "<<_entryObject->name()<<")";
throw std::runtime_error(msg.str());
}
if(item.second.rva!=0) {
std::ostringstream msg;
msg<<obj->name()<<": ";
msg<<"Entry point must refer to the start of the object";
throw std::runtime_error(msg.str());
}
_entryObject=obj;
}
if(item.second.type==LinkableObject::Local) continue;
// Insert item to the global symbol table if it doesn't exist yet
auto it=_globalSymbolTable.emplace(item.first,GlobalSymbolData()).first;
 
// If the symbol is local, check that it has not been already defined in another object
if(item.second.type==LinkableObject::Local) {
// Check that the symbol has not been already defined in another object
if(item.second.type==LinkableObject::Exported) {
if(it->second.obj) {
std::ostringstream msg;
msg<<obj->name()<<": Duplicate definition of \""<<item.first;
84,12 → 133,28
it->second.obj=obj;
it->second.rva=item.second.rva;
}
 
// Merge reference tables
for(auto const &ref: item.second.refs) it->second.refs.emplace(obj,ref.rva);
if(!item.second.refs.empty()) it->second.refs.insert(obj);
}
}
// Check that local symbols don't shadow the public ones
for(auto const &obj: _objects) {
auto const &table=obj->symbols();
for(auto const &item: table) {
if(item.second.type!=LinkableObject::Local) continue;
auto it=_globalSymbolTable.find(item.first);
if(it==_globalSymbolTable.end()) continue;
if(!it->second.obj) continue;
if(item.first==it->first) {
std::ostringstream msg;
msg<<obj->name()<<": Local symbol \""<<item.first<<"\" shadows the public one ";
msg<<"(defined in "<<it->second.obj->name()<<")";
throw std::runtime_error(msg.str());
}
}
}
// Check that no undefined symbols remain
for(auto const &item: _globalSymbolTable) {
if(item.second.obj==nullptr&&!item.second.refs.empty()) {
96,7 → 161,7
std::ostringstream msg;
msg<<"Undefined symbol: \""<<item.first<<"\"";
auto const it=item.second.refs.begin();
msg<<" (referenced from "<<it->first->name()<<")";
msg<<" (referenced from "<<(*it)->name()<<")";
throw std::runtime_error(msg.str());
}
}
109,12 → 174,31
if(_objects.size()>1) {
for(auto it=_objects.begin();it!=_objects.end();++it) {
if(*it==_entryObject) {
std::swap(*it,_objects[0]);
_objects.erase(it);
break;
}
}
_objects.insert(_objects.begin(),_entryObject);
}
// Remove unreferenced objects
if(_objects.size()>1) {
std::set<const LinkableObject*> used;
markAsUsed(_objects[0],used);
for(auto it=_objects.begin();it!=_objects.end();) {
if(used.find(*it)==used.end()) {
std::cerr<<"Linker warning: skipping an unreferenced object \"";
std::cerr<<(*it)->name()<<"\""<<std::endl;
for(auto sym=_globalSymbolTable.begin();sym!=_globalSymbolTable.end();) {
if(sym->second.obj==*it) sym=_globalSymbolTable.erase(sym);
else ++sym;
}
it=_objects.erase(it);
}
else ++it;
}
}
// Set base addresses
for(auto it=_objects.begin();it!=_objects.end();++it) {
(*it)->setVirtualAddress(currentBase);
126,14 → 210,33
 
void Linker::relocateObject(LinkableObject *obj) {
for(auto const &sym: obj->symbols()) {
auto it=_globalSymbolTable.find(sym.first);
assert(it!=_globalSymbolTable.end());
if(it->second.refs.empty()) continue;
assert(it->second.obj);
auto addr=it->second.obj->virtualAddress()+it->second.rva;
LinkableObject::Word addr;
if(sym.second.refs.empty()) continue;
if(sym.second.type==LinkableObject::Local) addr=obj->virtualAddress()+sym.second.rva;
else {
auto it=_globalSymbolTable.find(sym.first);
assert(it!=_globalSymbolTable.end());
assert(it->second.obj);
addr=it->second.obj->virtualAddress()+it->second.rva;
}
for(auto const &ref: sym.second.refs) {
auto offset=obj->getWord(ref.rva);
obj->replaceWord(ref.rva,addr+offset);
if(ref.type==LinkableObject::Regular) obj->replaceWord(ref.rva,addr+ref.offset);
else {
auto target=static_cast<LinkableObject::Word>(addr+ref.offset);
if(target>0xFFFFF&&target<0xFFF00000) {
std::ostringstream msg;
msg<<"Address 0x"<<Utils::hex(target)<<" is out of the range for a short reference";
msg<<" (referenced from "<<ref.source<<":"<<ref.line<<")";
throw std::runtime_error(msg.str());
}
target&=0x1FFFFF;
auto w=obj->getWord(ref.rva);
w|=(target&0xFFFF);
w|=((target<<8)&0x1F000000);
obj->replaceWord(ref.rva,w);
}
}
}
}
157,3 → 260,13
else if(currentSize<_imageSize) writer.pad(_imageSize-currentSize);
}
}
 
void Linker::markAsUsed(const LinkableObject *obj,std::set<const LinkableObject*> &used) {
if(used.find(obj)!=used.end()) return; // already processed
used.insert(obj);
for(auto const &sym: _globalSymbolTable) {
for(auto const &ref: sym.second.refs) {
if(ref==obj) markAsUsed(sym.second.obj,used);
}
}
}
/tools/src/lxp32asm/linker.h
17,16 → 17,17
#include <map>
#include <vector>
#include <string>
#include <set>
 
class Linker {
struct GlobalSymbolData {
LinkableObject *obj=nullptr;
LinkableObject::Word rva=0;
std::multimap<const LinkableObject*,LinkableObject::Word> refs;
std::set<const LinkableObject*> refs;
};
std::vector<LinkableObject*> _objects;
LinkableObject *_entryObject;
LinkableObject *_entryObject=nullptr;
std::map<std::string,GlobalSymbolData> _globalSymbolTable;
// Various output options
33,6 → 34,7
LinkableObject::Word _base=0;
std::size_t _align=4;
std::size_t _imageSize=0;
std::size_t _bytesWritten=0;
public:
void addObject(LinkableObject &obj);
void link(OutputWriter &writer);
39,11 → 41,13
void setBase(LinkableObject::Word base);
void setAlignment(std::size_t align);
void setImageSize(std::size_t size);
void generateMap(std::ostream &s);
private:
void buildSymbolTable();
void placeObjects();
void relocateObject(LinkableObject *obj);
void writeObjects(OutputWriter &writer);
void markAsUsed(const LinkableObject *obj,std::set<const LinkableObject*> &used);
};
 
#endif
/tools/src/lxp32asm/main.cpp
8,6 → 8,7
 
#include "assembler.h"
#include "linker.h"
#include "utils.h"
 
#include <iostream>
#include <fstream>
25,6 → 26,7
bool compileOnly=false;
std::string outputFileName;
std::string mapFileName;
std::vector<std::string> includeSearchDirs;
LinkableObject::Word base=0;
std::size_t align=4;
38,7 → 40,7
os<<" "<<program<<" [ option(s) | input file(s) ]"<<std::endl<<std::endl;
os<<"Options:"<<std::endl;
os<<" -a <align> Section alignment (default: 4)"<<std::endl;
os<<" -a <align> Object alignment (default: 4)"<<std::endl;
os<<" -b <addr> Base address (default: 0)"<<std::endl;
os<<" -c Compile only (don't link)"<<std::endl;
os<<" -f <fmt> Output file format (see below)"<<std::endl;
45,12 → 47,14
os<<" -h, --help Display a short help message"<<std::endl;
os<<" -i <dir> Add directory to the list of directories used to search"<<std::endl;
os<<" for included files (multiple directories can be specified)"<<std::endl;
os<<" -m <file> Generate map file"<<std::endl;
os<<" -o <file> Output file name"<<std::endl;
os<<" -s <size> Output image size"<<std::endl;
os<<" -- Do not interpret subsequent arguments as options"<<std::endl;
os<<std::endl;
os<<"Section alignment and image size must be multiples of 4."<<std::endl;
os<<"Base address must be a multiple of section alignment."<<std::endl;
os<<"Object alignment must be a power of two and can't be less than 4."<<std::endl;
os<<"Base address must be a multiple of object alignment."<<std::endl;
os<<"Image size must be a multiple of 4."<<std::endl;
os<<std::endl;
os<<"Output file formats:"<<std::endl;
67,6 → 71,8
std::ifstream in(filename,std::ios_base::in);
if(!in) return false;
if(in.tellg()==static_cast<std::ifstream::pos_type>(-1))
return false; // the stream is not seekable
std::vector<char> buf(idSize);
in.read(buf.data(),idSize);
84,7 → 90,7
bool noMoreOptions=false;
std::cout<<"LXP32 Platform Assembler and Linker"<<std::endl;
std::cout<<"Copyright (c) 2016 by Alex I. Kuznetsov"<<std::endl;
std::cout<<"Copyright (c) 2016-2019 by Alex I. Kuznetsov"<<std::endl;
if(argc<=1) {
displayUsage(std::cout,argv[0]);
101,11 → 107,12
}
try {
options.align=std::stoul(argv[i],nullptr,0);
if(options.align%4!=0||options.align==0) throw std::exception();
if(!Utils::isPowerOf2(options.align)) throw std::exception();
if(options.align<4) throw std::exception();
alignmentSpecified=true;
}
catch(std::exception &) {
throw std::runtime_error("Invalid section alignment");
throw std::runtime_error("Invalid object alignment");
}
}
else if(!strcmp(argv[i],"-b")) {
115,7 → 122,6
}
try {
options.base=std::stoul(argv[i],nullptr,0);
//if(options.base%4!=0) throw std::exception();
baseSpecified=true;
}
catch(std::exception &) {
148,6 → 154,13
}
options.includeSearchDirs.push_back(argv[i]);
}
else if(!strcmp(argv[i],"-m")) {
if(++i==argc) {
displayUsage(std::cerr,argv[0]);
return EXIT_FAILURE;
}
options.mapFileName=argv[i];
}
else if(!strcmp(argv[i],"-o")) {
if(++i==argc) {
displayUsage(std::cerr,argv[0]);
172,11 → 185,11
}
if(options.base%options.align!=0)
throw std::runtime_error("Base address must be a multiple of section alignment");
throw std::runtime_error("Base address must be a multiple of object alignment");
if(options.compileOnly) {
if(alignmentSpecified)
std::cerr<<"Warning: Section alignment is ignored in compile-only mode"<<std::endl;
std::cerr<<"Warning: Object alignment is ignored in compile-only mode"<<std::endl;
if(baseSpecified)
std::cerr<<"Warning: Base address is ignored in compile-only mode"<<std::endl;
if(formatSpecified)
183,6 → 196,8
std::cerr<<"Warning: Output format is ignored in compile-only mode"<<std::endl;
if(options.imageSize>0)
std::cerr<<"Warning: Image size is ignored in compile-only mode"<<std::endl;
if(!options.mapFileName.empty())
std::cerr<<"Warning: Map file is not generated in compile-only mode"<<std::endl;
}
if(inputFiles.empty())
278,6 → 293,14
std::cerr<<"Linker error: "<<ex.what()<<std::endl;
return EXIT_FAILURE;
}
std::cout<<writer->size()/4<<" words written"<<std::endl;
if(!options.mapFileName.empty()) {
std::ofstream out(options.mapFileName);
if(!out) throw std::runtime_error("Cannot open file \""+options.mapFileName+"\" for writing");
linker.generateMap(out);
}
}
catch(std::exception &ex) {
std::cerr<<"Error: "<<ex.what()<<std::endl;
/tools/src/lxp32asm/outputwriter.cpp
22,6 → 22,11
* OutputWriter members
*/
 
void OutputWriter::write(const char *data,std::size_t n) {
writeData(data,n);
_size+=n;
}
 
void OutputWriter::pad(std::size_t size) {
static char zeros[256]; // static objects are zero-initialized
while(size>0) {
31,6 → 36,10
}
}
 
std::size_t OutputWriter::size() const {
return _size;
}
 
/*
* BinaryOutputWriter members
*/
42,7 → 51,7
if(!_os) throw std::runtime_error("Cannot open \""+filename+"\" for writing");
}
 
void BinaryOutputWriter::write(const char *data,std::size_t n) {
void BinaryOutputWriter::writeData(const char *data,std::size_t n) {
_os.write(data,n);
}
 
70,7 → 79,7
}
}
 
void TextOutputWriter::write(const char *data,std::size_t n) {
void TextOutputWriter::writeData(const char *data,std::size_t n) {
while(n>0) {
assert(_buf.size()<4);
auto count=std::min(4-_buf.size(),n);
/tools/src/lxp32asm/outputwriter.h
19,11 → 19,15
*/
 
class OutputWriter {
std::size_t _size=0;
public:
virtual ~OutputWriter() {}
virtual void write(const char *data,std::size_t n)=0;
virtual void write(const char *data,std::size_t n);
virtual void abort() {}
void pad(std::size_t size);
std::size_t size() const;
protected:
virtual void writeData(const char *data,std::size_t n)=0;
};
 
/*
35,8 → 39,9
std::ofstream _os;
public:
BinaryOutputWriter(const std::string &filename);
virtual void write(const char *data,std::size_t n) override;
virtual void abort() override;
protected:
virtual void writeData(const char *data,std::size_t n) override;
};
 
/*
54,8 → 59,9
public:
TextOutputWriter(const std::string &filename,Format f);
~TextOutputWriter();
virtual void write(const char *data,std::size_t n) override;
virtual void abort() override;
protected:
virtual void writeData(const char *data,std::size_t n) override;
};
 
#endif
/tools/src/lxp32asm/utils.h
52,6 → 52,11
bool ishexdigit(char ch);
bool isoctdigit(char ch);
template <typename T> bool isPowerOf2(const T &x) {
static_assert(std::is_integral<T>::value,"Argument must be of integral type");
return (x!=0)&&((x&(x-1))==0);
}
}
 
#endif
/tools/src/lxp32dump/disassembler.cpp
26,24 → 26,12
return _value;
}
 
std::string Disassembler::Operand::str() const {
if(_type==Register) {
if(_value>=240&&_value<=247) return "iv"+std::to_string(_value-240);
else if(_value==252) return "cr";
else if(_value==253) return "irp";
else if(_value==254) return "rp";
else if(_value==255) return "sp";
else return "r"+std::to_string(_value);
}
else return std::to_string(_value);
}
 
/*
* Disassembler class members
*/
 
Disassembler::Disassembler(std::istream &is,std::ostream &os):
_is(is),_os(os),_fmt(Bin),_lineNumber(0),_pos(0) {}
_is(is),_os(os),_fmt(Bin),_preferAliases(true),_lineNumber(0),_pos(0) {}
 
void Disassembler::setFormat(Format fmt) {
_fmt=fmt;
53,6 → 41,10
_pos=base;
}
 
void Disassembler::setPreferAliases(bool b) {
_preferAliases=b;
}
 
void Disassembler::dump() {
Word word;
138,6 → 130,7
break;
default:
if((opcode>>4)==0x03) instruction=decodeCjmpxx(word);
else if((opcode>>3)==0x05) instruction=decodeLcs(word);
else instruction=decodeWord(word);
}
183,6 → 176,19
return true;
}
 
std::string Disassembler::str(const Operand &op) {
if(op.type()==Operand::Register) {
if(!_preferAliases) return "r"+std::to_string(op.value());
else if(op.value()>=240&&op.value()<=247) return "iv"+std::to_string(op.value()-240);
else if(op.value()==252) return "cr";
else if(op.value()==253) return "irp";
else if(op.value()==254) return "rp";
else if(op.value()==255) return "sp";
else return "r"+std::to_string(op.value());
}
else return std::to_string(op.value());
}
 
Disassembler::Operand Disassembler::decodeRd1Operand(Word w) {
int value=(w>>8)&0xFF;
if(w&0x02000000) return Operand(Operand::Register,value);
211,7 → 217,7
auto dst=decodeDstOperand(w);
auto rd1=decodeRd1Operand(w);
auto rd2=decodeRd2Operand(w);
oss<<op<<' '<<dst.str()<<", "<<rd1.str()<<", "<<rd2.str();
oss<<op<<' '<<str(dst)<<", "<<str(rd1)<<", "<<str(rd2);
return oss.str();
}
 
222,10 → 228,10
auto rd1=decodeRd1Operand(w);
auto rd2=decodeRd2Operand(w);
if(rd2.type()==Operand::Direct&&rd2.value()==0)
oss<<"mov "<<dst.str()<<", "<<rd1.str();
if(rd2.type()==Operand::Direct&&rd2.value()==0&&_preferAliases)
oss<<"mov "<<str(dst)<<", "<<str(rd1);
else
oss<<"add "<<dst.str()<<", "<<rd1.str()<<", "<<rd2.str();
oss<<"add "<<str(dst)<<", "<<str(rd1)<<", "<<str(rd2);
return oss.str();
}
243,7 → 249,7
if(rd1.type()!=Operand::Register) return decodeWord(w);
if(rd2.type()!=Operand::Direct||rd2.value()!=0) return decodeWord(w);
return "call "+rd1.str();
return "call "+str(rd1);
}
 
std::string Disassembler::decodeCjmpxx(Word w) {
302,9 → 308,9
if(rd1.type()!=Operand::Register) return decodeWord(w);
if(rd2.type()!=Operand::Direct||rd2.value()!=0) return decodeWord(w);
if(rd1.value()==253) return "iret";
if(rd1.value()==254) return "ret";
return "jmp "+rd1.str();
if(rd1.value()==253&&_preferAliases) return "iret";
if(rd1.value()==254&&_preferAliases) return "ret";
return "jmp "+str(rd1);
}
 
std::string Disassembler::decodeLc(Word w,bool &valid,Word &operand) {
321,9 → 327,17
if(!b) return decodeWord(w);
valid=true;
return "lc "+dst.str()+", 0x"+hex(operand);
return "lc "+str(dst)+", 0x"+hex(operand);
}
 
std::string Disassembler::decodeLcs(Word w) {
auto dst=decodeDstOperand(w);
auto operand=w&0xFFFF;
operand|=(w>>8)&0x001F0000;
if(operand&0x00100000) operand|=0xFFE00000;
return "lcs "+str(dst)+", 0x"+hex(operand);
}
 
std::string Disassembler::decodeLsb(Word w) {
std::ostringstream oss;
334,7 → 348,7
if(rd1.type()!=Operand::Register) return decodeWord(w);
if(rd2.type()!=Operand::Direct||rd2.value()!=0) return decodeWord(w);
return "lsb "+dst.str()+", "+rd1.str();
return "lsb "+str(dst)+", "+str(rd1);
}
 
std::string Disassembler::decodeLub(Word w) {
347,7 → 361,7
if(rd1.type()!=Operand::Register) return decodeWord(w);
if(rd2.type()!=Operand::Direct||rd2.value()!=0) return decodeWord(w);
return "lub "+dst.str()+", "+rd1.str();
return "lub "+str(dst)+", "+str(rd1);
}
 
std::string Disassembler::decodeLw(Word w) {
360,7 → 374,7
if(rd1.type()!=Operand::Register) return decodeWord(w);
if(rd2.type()!=Operand::Direct||rd2.value()!=0) return decodeWord(w);
return "lw "+dst.str()+", "+rd1.str();
return "lw "+str(dst)+", "+str(rd1);
}
 
std::string Disassembler::decodeMods(Word w) {
398,7 → 412,7
if(dst.value()!=0) return decodeWord(w);
if(rd1.type()!=Operand::Register) return decodeWord(w);
return "sb "+rd1.str()+", "+rd2.str();
return "sb "+str(rd1)+", "+str(rd2);
}
 
std::string Disassembler::decodeSl(Word w) {
420,7 → 434,18
}
 
std::string Disassembler::decodeSub(Word w) {
return decodeSimpleInstruction("sub",w);
std::ostringstream oss;
auto dst=decodeDstOperand(w);
auto rd1=decodeRd1Operand(w);
auto rd2=decodeRd2Operand(w);
if(rd1.type()==Operand::Direct&&rd1.value()==0&&_preferAliases)
oss<<"neg "<<str(dst)<<", "<<str(rd2);
else
oss<<"sub "<<str(dst)<<", "<<str(rd1)<<", "<<str(rd2);
return oss.str();
}
 
std::string Disassembler::decodeSw(Word w) {
433,7 → 458,7
if(dst.value()!=0) return decodeWord(w);
if(rd1.type()!=Operand::Register) return decodeWord(w);
return "sw "+rd1.str()+", "+rd2.str();
return "sw "+str(rd1)+", "+str(rd2);
}
 
std::string Disassembler::decodeXor(Word w) {
443,10 → 468,10
auto rd1=decodeRd1Operand(w);
auto rd2=decodeRd2Operand(w);
if(rd2.type()==Operand::Direct&&rd2.value()==-1)
oss<<"not "<<dst.str()<<", "<<rd1.str();
if(rd2.type()==Operand::Direct&&rd2.value()==-1&&_preferAliases)
oss<<"not "<<str(dst)<<", "<<str(rd1);
else
oss<<"xor "<<dst.str()<<", "<<rd1.str()<<", "<<rd2.str();
oss<<"xor "<<str(dst)<<", "<<str(rd1)<<", "<<str(rd2);
return oss.str();
}
/tools/src/lxp32dump/disassembler.h
27,15 → 27,14
int _value;
public:
Operand(Type t,int value);
Type type() const;
int value() const;
std::string str() const;
};
std::istream &_is;
std::ostream &_os;
Format _fmt;
bool _preferAliases;
int _lineNumber;
Word _pos;
public:
42,6 → 41,7
Disassembler(std::istream &is,std::ostream &os);
void setFormat(Format fmt);
void setBase(Word base);
void setPreferAliases(bool b);
void dump();
template <typename T> static std::string hex(const T &w) {
58,11 → 58,12
}
private:
bool getWord(Word &w);
std::string str(const Operand &op);
static Operand decodeRd1Operand(Word w);
static Operand decodeRd2Operand(Word w);
static Operand decodeDstOperand(Word w);
static std::string decodeSimpleInstruction(const std::string &op,Word w);
std::string decodeSimpleInstruction(const std::string &op,Word w);
std::string decodeAdd(Word w);
std::string decodeAnd(Word w);
std::string decodeCall(Word w);
72,6 → 73,7
std::string decodeHlt(Word w);
std::string decodeJmp(Word w);
std::string decodeLc(Word w,bool &valid,Word &operand);
std::string decodeLcs(Word w);
std::string decodeLsb(Word w);
std::string decodeLub(Word w);
std::string decodeLw(Word w);
/tools/src/lxp32dump/main.cpp
30,6 → 30,7
os<<" -b <addr> Base address (for comments only)"<<std::endl;
os<<" -f <fmt> Input format (bin, textio, dec, hex), default: autodetect"<<std::endl;
os<<" -h, --help Display a short help message"<<std::endl;
os<<" -na Do not use instruction and register aliases"<<std::endl;
os<<" -o <file> Output file name, default: standard output"<<std::endl;
os<<" -- Do not interpret subsequent arguments as options"<<std::endl;
}
64,12 → 65,13
std::string inputFileName,outputFileName;
std::cerr<<"LXP32 Platform Disassembler"<<std::endl;
std::cerr<<"Copyright (c) 2016 by Alex I. Kuznetsov"<<std::endl;
std::cerr<<"Copyright (c) 2016-2019 by Alex I. Kuznetsov"<<std::endl;
Disassembler::Format fmt=Disassembler::Bin;
bool noMoreOptions=false;
bool formatSpecified=false;
Disassembler::Word base=0;
bool noAliases=false;
if(argc<=1) {
displayUsage(std::cout,argv[0]);
111,6 → 113,9
displayUsage(std::cout,argv[0]);
return 0;
}
else if(!strcmp(argv[i],"-na")) {
noAliases=true;
}
else if(!strcmp(argv[i],"-o")) {
if(++i==argc) {
displayUsage(std::cerr,argv[0]);
175,6 → 180,7
Disassembler disasm(in,*os);
disasm.setFormat(fmt);
disasm.setBase(base);
disasm.setPreferAliases(!noAliases);
try {
disasm.dump();
/verify/common_pkg/common_pkg.vhd
4,10 → 4,6
-- Part of the LXP32 verification environment
--
-- Copyright (c) 2016 by Alex I. Kuznetsov
--
-- Note: the "rand" function declared in this package implements
-- a linear congruent pseudo-random number generator as defined in
-- the ISO/IEC 9899:1999 standard.
---------------------------------------------------------------------
 
library ieee;
15,10 → 11,16
use ieee.numeric_std.all;
 
package common_pkg is
shared variable rand_state: unsigned(31 downto 0):=to_unsigned(1,32);
type rng_state_type is record
seed1: positive;
seed2: positive;
end record;
 
-- Generate a pseudo-random value of integer type from [a;b] range
-- Output is stored in x
procedure rand(variable st: inout rng_state_type; a,b: integer; variable x: out integer);
impure function rand return integer;
impure function rand(a: integer; b: integer) return integer;
-- Convert std_logic_vector to a hexadecimal string (similar to
-- the "to_hstring" function from VHDL-2008
function hex_string(x: std_logic_vector) return string;
end package;
/verify/common_pkg/common_pkg_body.vhd
6,26 → 6,20
-- Copyright (c) 2016 by Alex I. Kuznetsov
---------------------------------------------------------------------
 
use std.textio.all;
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
 
package body common_pkg is
impure function rand return integer is
variable r: unsigned(63 downto 0);
procedure rand(variable st: inout rng_state_type; a,b: integer; variable x: out integer) is
variable r: real;
begin
r:=rand_state*to_unsigned(1103515245,32)+12345;
rand_state:=r(rand_state'range);
return to_integer(rand_state(30 downto 16));
end function;
impure function rand(a: integer; b: integer) return integer is
begin
assert a<=b report "Invalid range" severity failure;
return (rand mod (b-a+1))+a;
end function;
uniform(st.seed1,st.seed2,r);
r:=r*real(b-a+1);
x:=a+integer(floor(r));
end procedure;
function hex_string(x: std_logic_vector) return string is
variable xx: std_logic_vector(x'length-1 downto 0);
/verify/icache/run/ghdl/Makefile
41,7 → 41,7
$(WAVE_VCD): compile.stamp
ghdl -r $(GHDL_FLAGS) $(TB_MOD) --vcd=$(WAVE_VCD)
 
compile.stamp: $(LXP32_RTL) $(TB_SRC)
ghdl -a $(GHDL_FLAGS) $(LXP32_RTL) $(TB_SRC)
compile.stamp: $(LXP32_RTL) $(COMMON_SRC) $(TB_SRC)
ghdl -a $(GHDL_FLAGS) $(LXP32_RTL) $(COMMON_SRC) $(TB_SRC)
ghdl -e $(GHDL_FLAGS) $(TB_MOD)
echo > compile.stamp
/verify/icache/run/vsim/Makefile
30,8 → 30,8
# Normal targets
########################
 
compile.stamp: $(LXP32_RTL) $(TB_SRC) | work
vcom $(VCOMFLAGS) $(LXP32_RTL) $(TB_SRC)
compile.stamp: $(LXP32_RTL) $(COMMON_SRC) $(TB_SRC) | work
vcom $(VCOMFLAGS) $(LXP32_RTL) $(COMMON_SRC) $(TB_SRC)
echo > compile.stamp
 
work:
/verify/icache/run/xsim/Makefile
38,7 → 38,7
# Normal targets
########################
 
compile.stamp: $(LXP32_RTL) $(TB_SRC)
xvhdl$(BAT) $(LXP32_RTL) $(TB_SRC)
compile.stamp: $(LXP32_RTL) $(COMMON_SRC) $(TB_SRC)
xvhdl$(BAT) $(LXP32_RTL) $(COMMON_SRC) $(TB_SRC)
xelab$(BAT) work.tb -s tb_sim -debug typical
echo > compile.stamp
/verify/icache/src/make/sources.make
4,13 → 4,15
LXP32_RTL=$(LXP32_DIR)/lxp32_ram256x32.vhd\
$(LXP32_DIR)/lxp32_icache.vhd
 
# Common package
 
COMMON_PKG_DIR=../../../common_pkg
COMMON_SRC=$(COMMON_PKG_DIR)/common_pkg.vhd $(COMMON_PKG_DIR)/common_pkg_body.vhd
 
# Testbench sources
 
COMMON_PKG_DIR=../../../common_pkg
TB_DIR=../../src/tb
TB_SRC=$(COMMON_PKG_DIR)/common_pkg.vhd\
$(COMMON_PKG_DIR)/common_pkg_body.vhd\
$(TB_DIR)/tb_pkg.vhd\
TB_SRC=$(TB_DIR)/tb_pkg.vhd\
$(TB_DIR)/cpu_model.vhd\
$(TB_DIR)/ram_model.vhd\
$(TB_DIR)/tb.vhd
/verify/icache/src/tb/cpu_model.vhd
45,11 → 45,10
 
signal finish: std_logic:='0';
 
shared variable current_latency: integer:=1;
shared variable max_latency: integer:=-1;
shared variable total_latency: integer:=0;
shared variable total_requests: integer:=0;
shared variable spurious_misses: integer:=0;
signal current_latency: integer:=1;
signal max_latency: integer:=-1;
signal total_latency: integer:=0;
signal spurious_misses: integer:=0;
 
begin
 
59,16 → 58,21
variable size: integer;
variable addr: integer:=0;
variable delay: integer;
variable rng_state: rng_state_type;
variable r: integer;
variable total_requests: integer:=0;
begin
while b<=BLOCKS loop
if rand(1,10)=1 then -- insert large block occasionally
size:=rand(1,400);
rand(rng_state,1,10,r);
if r=1 then -- insert large block occasionally
rand(rng_state,1,400,size);
else -- small block
size:=rand(1,32);
rand(rng_state,1,32,size);
end if;
if rand(0,1)=0 then -- long jump
start:=rand(0,1024);
rand(rng_state,0,1,r);
if r=0 then -- long jump
rand(rng_state,0,1024,start);
addr:=start;
if VERBOSE then
report "Fetching block #"&integer'image(b)&" at address "&integer'image(addr)&
75,7 → 79,8
" of size "&integer'image(size);
end if;
else -- short jump
start:=addr+rand(0,20)-10;
rand(rng_state,-10,10,r);
start:=addr+r;
if start<0 then
start:=0;
end if;
93,7 → 98,7
wait until rising_edge(clk_i) and lli_busy_i='0';
re<='0';
addr:=addr+1;
delay:=rand(0,4);
rand(rng_state,0,4,delay);
if delay>0 then
for i in 1 to delay loop
wait until rising_edge(clk_i);
147,23 → 152,28
if rising_edge(clk_i) then
if lli_busy_i='0' then
if request='1' then
total_latency:=total_latency+current_latency;
total_latency<=total_latency+current_latency;
if current_latency>max_latency then
max_latency:=current_latency;
max_latency<=current_latency;
end if;
end if;
current_latency:=1;
current_latency<=1;
else
if lli_dat_i=(("00"&request_addr) xor xor_constant) and current_latency=1 then
spurious_misses:=spurious_misses+1;
spurious_misses<=spurious_misses+1;
end if;
current_latency:=current_latency+1;
current_latency<=current_latency+1;
end if;
end if;
end process;
 
assert not rising_edge(clk_i) or lli_busy_i='0' or request='1'
report "LLI busy signal asserted without a request"
severity failure;
process (clk_i) is
begin
if rising_edge(clk_i) then
assert lli_busy_i='0' or request='1'
report "LLI busy signal asserted without a request"
severity failure;
end if;
end process;
 
end architecture;
/verify/icache/src/tb/ram_model.vhd
51,6 → 51,7
end process;
 
process is
variable rng_state: rng_state_type;
variable delay: integer;
begin
wait until rising_edge(clk_i) and wbm_cyc_i='1' and wbm_stb_i='1';
58,7 → 59,7
-- Random delay before the first beat
if cycle='0' then
delay:=rand(0,3);
rand(rng_state,0,3,delay);
if delay>0 then
for i in 1 to delay loop
wait until rising_edge(clk_i) and wbm_cyc_i='1' and wbm_stb_i='1';
/verify/lxp32/run/ghdl/Makefile
13,7 → 13,7
 
.PHONY: all compile batch gui clean
 
.PRECIOUS: $(WAVE_OUT)
.PRECIOUS: $(WAVE_OUT) $(WAVE_VCD)
 
compile: compile.stamp $(FIRMWARE)
 
42,8 → 42,8
$(WAVE_VCD): compile.stamp $(FIRMWARE)
ghdl -r $(GHDL_FLAGS) $(TB_MOD) --vcd=$(WAVE_VCD)
 
compile.stamp: $(LXP32_RTL) $(PLATFORM_RTL) $(TB_SRC)
ghdl -a $(GHDL_FLAGS) $(LXP32_RTL) $(PLATFORM_RTL) $(TB_SRC)
compile.stamp: $(LXP32_RTL) $(COMMON_SRC) $(PLATFORM_RTL) $(TB_SRC)
ghdl -a $(GHDL_FLAGS) $(LXP32_RTL) $(COMMON_SRC) $(PLATFORM_RTL) $(TB_SRC)
ghdl -e $(GHDL_FLAGS) $(TB_MOD)
echo > compile.stamp
 
/verify/lxp32/run/vsim/Makefile
31,8 → 31,8
# Normal targets
########################
 
compile.stamp: $(LXP32_RTL) $(PLATFORM_RTL) $(TB_SRC) $(FIRMWARE) | work
vcom $(VCOMFLAGS) $(LXP32_RTL) $(PLATFORM_RTL) $(TB_SRC)
compile.stamp: $(LXP32_RTL) $(COMMON_SRC) $(PLATFORM_RTL) $(TB_SRC) $(FIRMWARE) | work
vcom $(VCOMFLAGS) $(LXP32_RTL) $(COMMON_SRC) $(PLATFORM_RTL) $(TB_SRC)
echo > compile.stamp
 
work:
/verify/lxp32/run/xsim/Makefile
39,8 → 39,8
# Normal targets
########################
 
compile.stamp: $(LXP32_RTL) $(PLATFORM_RTL) $(TB_SRC) $(FIRMWARE)
xvhdl$(BAT) $(LXP32_RTL) $(PLATFORM_RTL) $(TB_SRC)
compile.stamp: $(LXP32_RTL) $(COMMON_SRC) $(PLATFORM_RTL) $(TB_SRC) $(FIRMWARE)
xvhdl$(BAT) $(LXP32_RTL) $(COMMON_SRC) $(PLATFORM_RTL) $(TB_SRC)
xelab$(BAT) work.tb -s tb_sim -debug typical
echo > compile.stamp
 
/verify/lxp32/src/firmware/test001.asm
6,13 → 6,267
lc r100, 0x10000000 // test result output pointer
lc r101, halt
lc r102, bad_jump
lc r103, reg_is_nonzero
// All registers should be zero-initialized after reset
// Check that all registers are zero-initialized after reset
// Ignore r100-r103 which are already used
cjmpne r103, r0, 0
cjmpne r103, r1, 0
cjmpne r103, r2, 0
cjmpne r103, r3, 0
cjmpne r103, r4, 0
cjmpne r103, r5, 0
cjmpne r103, r6, 0
cjmpne r103, r7, 0
cjmpne r103, r8, 0
cjmpne r103, r9, 0
cjmpne r103, r10, 0
cjmpne r103, r11, 0
cjmpne r103, r12, 0
cjmpne r103, r13, 0
cjmpne r103, r14, 0
cjmpne r103, r15, 0
cjmpne r103, r16, 0
cjmpne r103, r17, 0
cjmpne r103, r18, 0
cjmpne r103, r19, 0
cjmpne r103, r20, 0
cjmpne r103, r21, 0
cjmpne r103, r22, 0
cjmpne r103, r23, 0
cjmpne r103, r24, 0
cjmpne r103, r25, 0
cjmpne r103, r26, 0
cjmpne r103, r27, 0
cjmpne r103, r28, 0
cjmpne r103, r29, 0
cjmpne r103, r30, 0
cjmpne r103, r31, 0
cjmpne r103, r32, 0
cjmpne r103, r33, 0
cjmpne r103, r34, 0
cjmpne r103, r35, 0
cjmpne r103, r36, 0
cjmpne r103, r37, 0
cjmpne r103, r38, 0
cjmpne r103, r39, 0
cjmpne r103, r40, 0
cjmpne r103, r41, 0
cjmpne r103, r42, 0
cjmpne r103, r43, 0
cjmpne r103, r44, 0
cjmpne r103, r45, 0
cjmpne r103, r46, 0
cjmpne r103, r47, 0
cjmpne r103, r48, 0
cjmpne r103, r49, 0
cjmpne r103, r50, 0
cjmpne r103, r51, 0
cjmpne r103, r52, 0
cjmpne r103, r53, 0
cjmpne r103, r54, 0
cjmpne r103, r55, 0
cjmpne r103, r56, 0
cjmpne r103, r57, 0
cjmpne r103, r58, 0
cjmpne r103, r59, 0
cjmpne r103, r60, 0
cjmpne r103, r61, 0
cjmpne r103, r62, 0
cjmpne r103, r63, 0
cjmpne r103, r64, 0
cjmpne r103, r65, 0
cjmpne r103, r66, 0
cjmpne r103, r67, 0
cjmpne r103, r68, 0
cjmpne r103, r69, 0
cjmpne r103, r70, 0
cjmpne r103, r71, 0
cjmpne r103, r72, 0
cjmpne r103, r73, 0
cjmpne r103, r74, 0
cjmpne r103, r75, 0
cjmpne r103, r76, 0
cjmpne r103, r77, 0
cjmpne r103, r78, 0
cjmpne r103, r79, 0
cjmpne r103, r80, 0
cjmpne r103, r81, 0
cjmpne r103, r82, 0
cjmpne r103, r83, 0
cjmpne r103, r84, 0
cjmpne r103, r85, 0
cjmpne r103, r86, 0
cjmpne r103, r87, 0
cjmpne r103, r88, 0
cjmpne r103, r89, 0
cjmpne r103, r90, 0
cjmpne r103, r91, 0
cjmpne r103, r92, 0
cjmpne r103, r93, 0
cjmpne r103, r94, 0
cjmpne r103, r95, 0
cjmpne r103, r96, 0
cjmpne r103, r97, 0
cjmpne r103, r98, 0
cjmpne r103, r99, 0
cjmpne r103, r104, 0
cjmpne r103, r105, 0
cjmpne r103, r106, 0
cjmpne r103, r107, 0
cjmpne r103, r108, 0
cjmpne r103, r109, 0
cjmpne r103, r110, 0
cjmpne r103, r111, 0
cjmpne r103, r112, 0
cjmpne r103, r113, 0
cjmpne r103, r114, 0
cjmpne r103, r115, 0
cjmpne r103, r116, 0
cjmpne r103, r117, 0
cjmpne r103, r118, 0
cjmpne r103, r119, 0
cjmpne r103, r120, 0
cjmpne r103, r121, 0
cjmpne r103, r122, 0
cjmpne r103, r123, 0
cjmpne r103, r124, 0
cjmpne r103, r125, 0
cjmpne r103, r126, 0
cjmpne r103, r127, 0
cjmpne r103, r128, 0
cjmpne r103, r129, 0
cjmpne r103, r130, 0
cjmpne r103, r131, 0
cjmpne r103, r132, 0
cjmpne r103, r133, 0
cjmpne r103, r134, 0
cjmpne r103, r135, 0
cjmpne r103, r136, 0
cjmpne r103, r137, 0
cjmpne r103, r138, 0
cjmpne r103, r139, 0
cjmpne r103, r140, 0
cjmpne r103, r141, 0
cjmpne r103, r142, 0
cjmpne r103, r143, 0
cjmpne r103, r144, 0
cjmpne r103, r145, 0
cjmpne r103, r146, 0
cjmpne r103, r147, 0
cjmpne r103, r148, 0
cjmpne r103, r149, 0
cjmpne r103, r150, 0
cjmpne r103, r151, 0
cjmpne r103, r152, 0
cjmpne r103, r153, 0
cjmpne r103, r154, 0
cjmpne r103, r155, 0
cjmpne r103, r156, 0
cjmpne r103, r157, 0
cjmpne r103, r158, 0
cjmpne r103, r159, 0
cjmpne r103, r160, 0
cjmpne r103, r161, 0
cjmpne r103, r162, 0
cjmpne r103, r163, 0
cjmpne r103, r164, 0
cjmpne r103, r165, 0
cjmpne r103, r166, 0
cjmpne r103, r167, 0
cjmpne r103, r168, 0
cjmpne r103, r169, 0
cjmpne r103, r170, 0
cjmpne r103, r171, 0
cjmpne r103, r172, 0
cjmpne r103, r173, 0
cjmpne r103, r174, 0
cjmpne r103, r175, 0
cjmpne r103, r176, 0
cjmpne r103, r177, 0
cjmpne r103, r178, 0
cjmpne r103, r179, 0
cjmpne r103, r180, 0
cjmpne r103, r181, 0
cjmpne r103, r182, 0
cjmpne r103, r183, 0
cjmpne r103, r184, 0
cjmpne r103, r185, 0
cjmpne r103, r186, 0
cjmpne r103, r187, 0
cjmpne r103, r188, 0
cjmpne r103, r189, 0
cjmpne r103, r190, 0
cjmpne r103, r191, 0
cjmpne r103, r192, 0
cjmpne r103, r193, 0
cjmpne r103, r194, 0
cjmpne r103, r195, 0
cjmpne r103, r196, 0
cjmpne r103, r197, 0
cjmpne r103, r198, 0
cjmpne r103, r199, 0
cjmpne r103, r200, 0
cjmpne r103, r201, 0
cjmpne r103, r202, 0
cjmpne r103, r203, 0
cjmpne r103, r204, 0
cjmpne r103, r205, 0
cjmpne r103, r206, 0
cjmpne r103, r207, 0
cjmpne r103, r208, 0
cjmpne r103, r209, 0
cjmpne r103, r210, 0
cjmpne r103, r211, 0
cjmpne r103, r212, 0
cjmpne r103, r213, 0
cjmpne r103, r214, 0
cjmpne r103, r215, 0
cjmpne r103, r216, 0
cjmpne r103, r217, 0
cjmpne r103, r218, 0
cjmpne r103, r219, 0
cjmpne r103, r220, 0
cjmpne r103, r221, 0
cjmpne r103, r222, 0
cjmpne r103, r223, 0
cjmpne r103, r224, 0
cjmpne r103, r225, 0
cjmpne r103, r226, 0
cjmpne r103, r227, 0
cjmpne r103, r228, 0
cjmpne r103, r229, 0
cjmpne r103, r230, 0
cjmpne r103, r231, 0
cjmpne r103, r232, 0
cjmpne r103, r233, 0
cjmpne r103, r234, 0
cjmpne r103, r235, 0
cjmpne r103, r236, 0
cjmpne r103, r237, 0
cjmpne r103, r238, 0
cjmpne r103, r239, 0
cjmpne r103, r240, 0
cjmpne r103, r241, 0
cjmpne r103, r242, 0
cjmpne r103, r243, 0
cjmpne r103, r244, 0
cjmpne r103, r245, 0
cjmpne r103, r246, 0
cjmpne r103, r247, 0
cjmpne r103, r248, 0
cjmpne r103, r249, 0
cjmpne r103, r250, 0
cjmpne r103, r251, 0
cjmpne r103, r252, 0
cjmpne r103, r253, 0
cjmpne r103, r254, 0
cjmpne r103, r255, 0
lc r0, jump0
add r1, r1, 1
cjmpe r0, r1, 1
jmp r0
sw r100, 2 // failure: r1 not initialized
reg_is_nonzero:
sw r100, 2 // failure: register is not initialized
jmp r101
// Test different jump conditions
174,7 → 428,7
// Copy itself to another portion of memory
mov r0, 0 // source pointer
lc r1, 0x00008000 // destination pointer
lc r2, end // size of block to copy, in bytes
lc r2, halt@2 // size of block to copy, in bytes
lc r32, copy_loop
copy_loop:
226,5 → 480,3
halt:
hlt
jmp r101
 
end:
/verify/lxp32/src/firmware/test017.asm
0,0 → 1,25
/*
* Test the new "lcs" instruction
*/
 
lc r100, 0x10000000 // test result output pointer
lcs r101, halt
lcs r102, failure
 
lc r0, 1000000
lc r1, -1000011
lcs r10, 1000000
lcs r11, -1000011
cjmpne r102, r0, r10 // failure
cjmpne r102, r1, r11 // failure
sw r100, 1
jmp r101 // halt
failure:
sw r100, 2
halt:
hlt
jmp r101 // halt
/verify/lxp32/src/firmware/test018.asm
0,0 → 1,1122
/*
* Additional interrupt test. The objective is to check that interrupt
* arrival at any time will not disrupt program flow.
*
* The main part of the program calculates CRC32 of a 16 kbyte block
* of data. The other part generates interrupts at random times using
* the C99 pseudorandom generator and the timer peripheral.
*/
 
lc r100, 0x10000000 // test result output pointer
lcs r101, halt
lcs r102, failure
lc r103, 0x20000000 // timer: number of pulses (0xFFFFFFFF - infinite)
lc r104, 0x20000004 // timer: delay between pulses (in cycles)
// Set up the interrupt handler
lcs r200, 0 // initialize counter
lc r201, 0x10000008 // output pointer
lc r202, 1103515245 // PRNG: multiplicative constant
lcs r203, 12345 // PRNG: additive constant
lcs r204, 32767 // PRNG: modulo
lcs r205, 1 // PRNG: current seed value
lcs iv0, timer_handler
mov cr, 1 // enable interrupt 0
sw r104, 100
sw r103, 1 // activate timer, one pulse
// Main routine
lc r16, 0x10000004 // output pointer
lcs r17, 0xFFFFFFFF // initial CRC value
lc r18, 0xEDB88320 // polynom
lcs r19, data // input pointer
lcs r20, 4096 // data block size in words
lcs r32, word_loop
lcs r33, bit_loop
lcs r34, dont_xor
mov r64, 0 // word counter
word_loop:
lw r0, r19
mov r65, 0 // bit counter
bit_loop:
and r1, r0, 1
and r2, r17, 1
sru r17, r17, 1
xor r3, r1, r2
cjmpe r34, r3, 0 // dont_xor
xor r17, r17, r18
dont_xor:
sru r0, r0, 1
add r65, r65, 1
cjmpul r33, r65, 32 // bit_loop
sw r16, r64
add r19, r19, 4
add r64, r64, 1
cjmpul r32, r64, r20 // word_loop
not r17, r17
sw r16, r17
// Check main routine result
lc r0, 0xF958DFE2
cjmpne r102, r0, r17
mov cr, 0 // disable interrupts
sw r103, 0 // deactivate timer
sw r100, 1
jmp r101
failure:
sw r100, 2
halt:
hlt
jmp r101
 
timer_handler:
// PRNG generator from C99 (ISO/IEC 9899:1999)
mul r205, r205, r202
add r205, r205, r203
sru r220, r205, 16
and r220, r220, r204 // r220 now contains the C99 pseudorandom number
and r221, r220, 0x1F
add r221, r221, 32 // r221 is now a pseudorandom number from the [32, 63] range
sw r104, r221 // set up the timer delay
sw r103, 1 // single shot
iret
.align
data:
.byte 0xD7, 0x64, 0xC8, 0xCC, 0xE9, 0x32, 0x55, 0xC4, 0x47, 0x8D, 0x7A, 0xA0, 0x5D, 0x83, 0xF3, 0xEA
.byte 0xA2, 0xB7, 0x24, 0x9B, 0x04, 0x3E, 0x23, 0xCD, 0x28, 0x66, 0x21, 0x1B, 0xFF, 0x37, 0x83, 0xD6
.byte 0x9C, 0x4B, 0xA3, 0x86, 0x7E, 0xF9, 0x4A, 0xC5, 0x86, 0xC5, 0x66, 0xE4, 0x48, 0x5A, 0xCE, 0xEB
.byte 0x11, 0xF3, 0x86, 0x16, 0x31, 0xA9, 0xE3, 0x59, 0x10, 0x05, 0x75, 0x10, 0x3C, 0xF8, 0xE6, 0xD9
.byte 0x44, 0x8A, 0x60, 0xC2, 0x83, 0xAA, 0x88, 0x0A, 0x70, 0xEE, 0xEE, 0xB8, 0x48, 0xBD, 0xA3, 0x5A
.byte 0xB0, 0x2A, 0x70, 0xE1, 0xD4, 0x54, 0x3A, 0xE4, 0x59, 0xAF, 0xF4, 0x96, 0xA8, 0xDB, 0x70, 0xEC
.byte 0x65, 0xD0, 0xAF, 0xE9, 0x7B, 0x37, 0xF3, 0xEB, 0x25, 0xE1, 0xA4, 0x6E, 0x9E, 0x47, 0xC9, 0x4E
.byte 0x72, 0x39, 0x30, 0x46, 0x8E, 0x6A, 0x2B, 0xE8, 0x1A, 0x20, 0x7E, 0xC2, 0xFC, 0xEF, 0xAF, 0x62
.byte 0xBF, 0x5E, 0x4B, 0x3B, 0x95, 0x3E, 0x27, 0xBB, 0x20, 0xCB, 0x2A, 0xBE, 0x13, 0xF3, 0x0D, 0x85
.byte 0x2D, 0x3D, 0xCC, 0xBB, 0xA8, 0xF7, 0xA3, 0xC2, 0x17, 0x22, 0x85, 0x14, 0x11, 0x34, 0x76, 0xD1
.byte 0x92, 0xC1, 0x0D, 0x28, 0xFF, 0x34, 0xE3, 0x20, 0xFF, 0x0D, 0xDE, 0x12, 0x01, 0xEC, 0x98, 0x2E
.byte 0x29, 0x64, 0xE9, 0xD1, 0x5B, 0x8D, 0x94, 0x73, 0xAF, 0x19, 0x87, 0xC1, 0x4D, 0xFE, 0x93, 0xE0
.byte 0xBF, 0xA1, 0x09, 0xBF, 0xD5, 0xEC, 0xDF, 0xD4, 0xFA, 0xBE, 0xE7, 0xFB, 0xAA, 0x7F, 0x29, 0xD4
.byte 0xE3, 0x13, 0xA6, 0x3F, 0xA1, 0x3A, 0xB3, 0x51, 0x54, 0x3B, 0x12, 0xA2, 0x39, 0xA6, 0x82, 0xF8
.byte 0x47, 0x8B, 0xB8, 0x1C, 0x78, 0x97, 0xF1, 0x73, 0x56, 0xD9, 0x6F, 0x00, 0x58, 0x99, 0xD5, 0x3B
.byte 0xAC, 0x7B, 0x7B, 0x4E, 0xB6, 0x2E, 0x9F, 0x0A, 0x69, 0xB2, 0xAC, 0xA3, 0x58, 0x2F, 0x9B, 0xA0
.byte 0xBB, 0x54, 0xBD, 0x33, 0xEB, 0xAF, 0xA7, 0x41, 0x88, 0x16, 0x42, 0xE0, 0xAF, 0x17, 0x1C, 0x5C
.byte 0x93, 0x97, 0xAA, 0x49, 0xC6, 0x49, 0x54, 0x30, 0xFB, 0x00, 0xD3, 0x54, 0x30, 0x6F, 0xF5, 0xEB
.byte 0xC3, 0xB2, 0x1F, 0xAF, 0x62, 0xC6, 0xF1, 0xEA, 0xDC, 0x34, 0xCB, 0x8C, 0x4C, 0xE7, 0xE8, 0xDF
.byte 0x7F, 0x93, 0x29, 0x46, 0xDD, 0x7E, 0x76, 0xD9, 0x7E, 0x4A, 0x2E, 0xAF, 0xBA, 0x23, 0x9A, 0x7E
.byte 0xD6, 0xB9, 0x2D, 0x38, 0x7F, 0x1F, 0x23, 0x5C, 0x53, 0xEE, 0xE8, 0x9F, 0xD6, 0xD1, 0x7E, 0x55
.byte 0x64, 0xA8, 0x9B, 0x42, 0x26, 0x12, 0x1B, 0xA5, 0x5D, 0x49, 0x54, 0x17, 0x6D, 0xEF, 0x95, 0x43
.byte 0xA8, 0xC3, 0x7C, 0x28, 0xE2, 0xA0, 0x84, 0x35, 0x8E, 0x6D, 0xD4, 0x64, 0x3E, 0x53, 0xBA, 0xA3
.byte 0xFC, 0x56, 0xE5, 0x22, 0x69, 0x01, 0xC8, 0xC6, 0x4B, 0x1D, 0xDD, 0xB8, 0x0C, 0x72, 0xFC, 0xB5
.byte 0x35, 0x79, 0xDD, 0x18, 0x19, 0x62, 0x4D, 0xA8, 0xCF, 0x21, 0x0D, 0x0D, 0x75, 0xC7, 0xB1, 0x71
.byte 0x1E, 0x96, 0x94, 0x87, 0x98, 0x5C, 0x4D, 0xE3, 0x7A, 0x2B, 0x9C, 0x86, 0x9E, 0x98, 0x3B, 0xD4
.byte 0x11, 0x19, 0xEC, 0x2B, 0x7B, 0x39, 0xD3, 0x4A, 0x5B, 0xE0, 0x58, 0xD0, 0xA8, 0x09, 0x41, 0xC7
.byte 0xA0, 0xD6, 0x4E, 0x38, 0x32, 0x9C, 0x1C, 0xAC, 0xC8, 0xB8, 0x33, 0x66, 0x50, 0x6F, 0x3B, 0x62
.byte 0x88, 0x27, 0x8E, 0x03, 0x61, 0x61, 0x4E, 0xBC, 0x42, 0xA6, 0x8D, 0xEB, 0xAF, 0xCF, 0xB2, 0x4F
.byte 0xA5, 0x01, 0x88, 0xD8, 0x9E, 0xA4, 0x84, 0x66, 0x5C, 0xB8, 0xCD, 0xAD, 0x27, 0x08, 0x10, 0xAF
.byte 0x30, 0x9E, 0xB3, 0x91, 0x00, 0x01, 0x4E, 0x42, 0xA7, 0xDB, 0x2E, 0x57, 0xAA, 0xE1, 0xA7, 0x50
.byte 0xE2, 0x2F, 0x28, 0x80, 0xD4, 0xAC, 0xE7, 0x30, 0x64, 0xB4, 0xDE, 0x8C, 0xBD, 0xEE, 0x3B, 0xED
.byte 0x8D, 0xEE, 0x7E, 0x8D, 0xF0, 0xCC, 0xD0, 0x98, 0xA8, 0xFE, 0xEF, 0x53, 0xDF, 0x96, 0xA3, 0xC2
.byte 0xC6, 0xCB, 0x43, 0x9A, 0x78, 0x2A, 0xCB, 0xDD, 0xDF, 0xAA, 0x69, 0x9C, 0x98, 0xA5, 0x89, 0x25
.byte 0x94, 0x08, 0xB3, 0x84, 0xD5, 0x83, 0x1C, 0x7D, 0x82, 0x0C, 0xD0, 0x62, 0xA3, 0x73, 0x24, 0x69
.byte 0x3F, 0x68, 0x04, 0xB7, 0x92, 0xD0, 0x95, 0x72, 0x7A, 0xFE, 0x0F, 0x13, 0xA4, 0x98, 0x38, 0x38
.byte 0xA1, 0xEC, 0xBC, 0x76, 0x70, 0xD9, 0xF3, 0xF2, 0xE6, 0xC4, 0x55, 0x89, 0x38, 0x7A, 0xF3, 0x77
.byte 0xE2, 0xF7, 0x2F, 0x75, 0xC7, 0xC4, 0xE7, 0x41, 0xC2, 0xF6, 0x54, 0x67, 0x8F, 0x8D, 0x9F, 0x30
.byte 0x7A, 0x5C, 0xA7, 0xEA, 0x35, 0x9B, 0xDD, 0x1C, 0x5F, 0x32, 0xA5, 0x97, 0xAD, 0x98, 0x0F, 0x8F
.byte 0x90, 0x3E, 0x04, 0x58, 0x02, 0xEC, 0x99, 0xC5, 0xE3, 0xEE, 0x2C, 0x72, 0x7C, 0xCB, 0xA3, 0xF7
.byte 0x27, 0x4A, 0xE1, 0x5D, 0xE6, 0xBF, 0x79, 0x45, 0xF2, 0x1F, 0xDD, 0x9F, 0xB7, 0xEC, 0x2F, 0x48
.byte 0x2A, 0x33, 0xA0, 0x2D, 0x20, 0x3A, 0xF2, 0x03, 0x29, 0x1E, 0x76, 0xA6, 0xEA, 0x19, 0x9D, 0x12
.byte 0x64, 0x7F, 0x6F, 0x4B, 0x3E, 0xE9, 0x90, 0x30, 0x08, 0x6E, 0xD0, 0xC0, 0x5B, 0xFF, 0x09, 0x86
.byte 0x33, 0xA9, 0xB3, 0x53, 0xE3, 0xA5, 0x57, 0x0C, 0xC4, 0xCD, 0xB2, 0xAE, 0xE7, 0x50, 0xC0, 0x4C
.byte 0xCF, 0x30, 0x97, 0x0D, 0x19, 0x28, 0x3E, 0x22, 0x96, 0x0E, 0xE3, 0xF2, 0x0E, 0xEC, 0x78, 0x41
.byte 0x96, 0x2B, 0x95, 0x79, 0xD0, 0xED, 0x86, 0x95, 0xBA, 0x39, 0x43, 0xA2, 0x89, 0x04, 0xEE, 0x58
.byte 0x34, 0x85, 0x66, 0x4E, 0xAE, 0xA5, 0x71, 0x44, 0xB4, 0x55, 0x36, 0xC2, 0x42, 0xAE, 0x04, 0xD8
.byte 0xDA, 0x99, 0x52, 0xAA, 0x86, 0xD9, 0x40, 0x41, 0x12, 0x83, 0xE3, 0x9C, 0x87, 0xD2, 0xF5, 0xBC
.byte 0x58, 0x5C, 0x0B, 0x06, 0x01, 0x7C, 0x4A, 0xB5, 0xD1, 0x81, 0x77, 0x14, 0x30, 0x7B, 0xEC, 0x0B
.byte 0x15, 0x3E, 0xB6, 0x9C, 0x17, 0xF6, 0xDE, 0x2A, 0x79, 0xC1, 0xC7, 0x01, 0x94, 0xBC, 0xBE, 0xEC
.byte 0x18, 0xC9, 0xF2, 0x19, 0x46, 0x3D, 0xCF, 0x18, 0xBF, 0x46, 0x2C, 0xF0, 0xC2, 0x18, 0xFB, 0xD8
.byte 0x57, 0xB1, 0x74, 0x6F, 0xA7, 0x52, 0x99, 0x21, 0x14, 0x60, 0x23, 0xA8, 0x1D, 0xE1, 0x95, 0x35
.byte 0xAB, 0x87, 0x4F, 0xF1, 0xC4, 0x1F, 0x09, 0x83, 0x66, 0x36, 0x73, 0x29, 0x4E, 0x6F, 0x01, 0xA6
.byte 0x20, 0x76, 0x15, 0xC7, 0xC9, 0xAF, 0xE9, 0xDE, 0x10, 0x0C, 0x86, 0x2D, 0xED, 0x1C, 0x63, 0x98
.byte 0xA3, 0xB3, 0x8A, 0x68, 0xD2, 0x93, 0xEB, 0x38, 0xCA, 0x5F, 0x61, 0x18, 0xCE, 0x63, 0xBF, 0xEF
.byte 0xD9, 0xD4, 0xB6, 0xA2, 0x84, 0x9F, 0x80, 0x94, 0xAB, 0x07, 0xC1, 0x99, 0x23, 0x24, 0x32, 0xC7
.byte 0xD8, 0xBC, 0x2F, 0xAA, 0x50, 0x1B, 0xE3, 0x1A, 0x7A, 0x45, 0x33, 0x49, 0xA8, 0xF2, 0x38, 0x81
.byte 0xC7, 0xEF, 0x24, 0x4B, 0x8F, 0xA4, 0xDF, 0x3B, 0xAC, 0xA1, 0xD5, 0xD0, 0xC5, 0x07, 0x97, 0x9E
.byte 0xC3, 0xC6, 0x48, 0x13, 0xE1, 0x2C, 0x2D, 0x5C, 0x71, 0x60, 0xA5, 0x19, 0x53, 0xDE, 0x9B, 0x1A
.byte 0xCE, 0xBF, 0x66, 0x5D, 0x64, 0x45, 0x99, 0x11, 0xE6, 0x6E, 0xE1, 0xAC, 0x75, 0x78, 0x4A, 0x39
.byte 0x3E, 0x93, 0x4D, 0x20, 0xBF, 0x7A, 0x7C, 0x31, 0xDB, 0x22, 0x4B, 0x2F, 0x00, 0xE6, 0x49, 0xCF
.byte 0xA6, 0xB0, 0x2C, 0x0B, 0xF5, 0xC6, 0x1C, 0xDC, 0x35, 0xFE, 0x89, 0xAA, 0x77, 0xD4, 0xE4, 0xB6
.byte 0x67, 0x31, 0xD6, 0x27, 0xAC, 0x52, 0x58, 0x88, 0x75, 0xA3, 0xB7, 0x75, 0x8A, 0x01, 0x44, 0x31
.byte 0xB1, 0x71, 0x3C, 0xA7, 0x38, 0x59, 0x83, 0x6D, 0x57, 0x0C, 0x18, 0xCF, 0xE1, 0xFC, 0x85, 0x48
.byte 0x2E, 0x5B, 0x70, 0xDA, 0xAE, 0xC9, 0x62, 0x23, 0x6D, 0x1A, 0x99, 0xF7, 0x1B, 0xDE, 0x28, 0xCD
.byte 0x50, 0x65, 0x74, 0x88, 0xBE, 0xF8, 0xF5, 0x16, 0x05, 0x0D, 0xE5, 0xE6, 0x0A, 0x6B, 0x2F, 0x38
.byte 0xC7, 0x9F, 0x12, 0x76, 0x68, 0x75, 0x9A, 0xD5, 0x90, 0x33, 0xCD, 0xAC, 0x12, 0xF6, 0x79, 0x62
.byte 0x5B, 0xEE, 0xEA, 0x1A, 0xE6, 0xE0, 0x31, 0xEB, 0xED, 0x16, 0xD2, 0xF7, 0x82, 0x01, 0x30, 0x49
.byte 0xA0, 0x43, 0xBF, 0x09, 0xB8, 0x59, 0xDF, 0x48, 0x8D, 0xAC, 0xF5, 0x9F, 0xA3, 0x6E, 0x02, 0xFE
.byte 0x5D, 0xEC, 0x19, 0x43, 0xCD, 0x4A, 0x2F, 0xBA, 0x61, 0x01, 0xB2, 0xE3, 0x02, 0xE2, 0x2D, 0xA3
.byte 0x25, 0xEC, 0xAC, 0xDE, 0x46, 0x8C, 0x27, 0xD4, 0x39, 0x1C, 0x73, 0xDC, 0x8B, 0x76, 0xDB, 0xE8
.byte 0x62, 0xF4, 0x2C, 0x30, 0x3F, 0x5C, 0xEA, 0xA0, 0x5D, 0x9D, 0x84, 0x60, 0x80, 0xB1, 0x04, 0xA6
.byte 0x9E, 0xB1, 0x85, 0xE5, 0x3D, 0xAC, 0xB9, 0x76, 0xC9, 0x2D, 0x53, 0x55, 0xA3, 0x2E, 0x3E, 0x06
.byte 0x23, 0x6A, 0x36, 0x62, 0xC7, 0x21, 0x03, 0x25, 0xBE, 0x87, 0x86, 0x3F, 0x39, 0x8A, 0xE5, 0xD8
.byte 0x3C, 0x6A, 0xBD, 0x7A, 0x17, 0x76, 0xF0, 0xE1, 0xA3, 0x44, 0x36, 0x47, 0x72, 0x75, 0x4D, 0x96
.byte 0xE0, 0x83, 0xF8, 0xA7, 0xA4, 0xFC, 0xCC, 0x63, 0x83, 0x52, 0xA2, 0xBD, 0xDD, 0x88, 0x95, 0x19
.byte 0xF3, 0x52, 0x93, 0x0B, 0xC9, 0x84, 0xEC, 0x6D, 0xC8, 0x23, 0xB4, 0x3B, 0x98, 0x02, 0xD1, 0x79
.byte 0x85, 0xCA, 0x20, 0x2A, 0xC6, 0xEC, 0x8E, 0x4A, 0x3F, 0x31, 0x08, 0x1C, 0xBA, 0x9D, 0x36, 0xAD
.byte 0xF0, 0xC9, 0xB8, 0xBA, 0x4E, 0xA5, 0x27, 0x17, 0xC8, 0xDC, 0x52, 0x61, 0xDE, 0x24, 0xDA, 0x63
.byte 0xEE, 0xFB, 0x8E, 0xB5, 0xE8, 0x1D, 0x00, 0x27, 0x4E, 0x08, 0x44, 0x08, 0xA5, 0x7A, 0xB6, 0x96
.byte 0x44, 0x6F, 0x50, 0x92, 0x14, 0x77, 0xA9, 0xDD, 0x53, 0xFC, 0x3F, 0x31, 0x20, 0x19, 0x95, 0x0F
.byte 0x15, 0x24, 0xC4, 0xFD, 0x41, 0xC4, 0x24, 0x90, 0xCC, 0x69, 0x99, 0x72, 0xE3, 0x4F, 0x09, 0x28
.byte 0xBF, 0x59, 0xBB, 0xD3, 0xD1, 0x64, 0xB1, 0x25, 0x61, 0xF0, 0x57, 0x81, 0x0A, 0xEC, 0x91, 0x1F
.byte 0x11, 0x56, 0x1C, 0x52, 0x1B, 0x41, 0xE3, 0xE8, 0xAB, 0x7C, 0x5A, 0x8F, 0xCC, 0x64, 0xB7, 0x8C
.byte 0xBD, 0x72, 0x5F, 0x8E, 0xD7, 0x11, 0xB4, 0x38, 0x01, 0x0B, 0xBA, 0x0B, 0xF8, 0x4B, 0x2B, 0x09
.byte 0xA2, 0x48, 0x5C, 0xBD, 0x89, 0x3F, 0xA5, 0x34, 0xBC, 0x00, 0xC3, 0x89, 0x64, 0x7B, 0x15, 0x22
.byte 0xED, 0x75, 0xB1, 0xC4, 0x86, 0x65, 0xFD, 0x88, 0x70, 0xB7, 0x94, 0x68, 0x03, 0xBF, 0x71, 0xA5
.byte 0x07, 0xCE, 0x63, 0x91, 0x0E, 0x08, 0xC6, 0xCA, 0x09, 0x8A, 0x54, 0x6D, 0x05, 0x69, 0x90, 0xF2
.byte 0xDF, 0x41, 0xB7, 0x66, 0xA6, 0xB4, 0xEE, 0x16, 0x6C, 0x83, 0x7F, 0x70, 0x43, 0xF1, 0x16, 0x4A
.byte 0xBF, 0x79, 0xDC, 0xCD, 0x82, 0xA2, 0x98, 0x8B, 0x2C, 0xED, 0xF9, 0x32, 0x57, 0x89, 0x24, 0x36
.byte 0xCA, 0xDC, 0x9C, 0x71, 0x91, 0x8B, 0x88, 0xFE, 0x0F, 0x07, 0x6E, 0x52, 0xF9, 0x84, 0x9C, 0xB8
.byte 0xFE, 0x79, 0x86, 0x80, 0x1B, 0x1F, 0x0B, 0x48, 0x0C, 0x05, 0x7A, 0x63, 0x8E, 0x9F, 0x9A, 0x59
.byte 0x7C, 0x37, 0xCB, 0x0D, 0xC3, 0x53, 0x0C, 0xD2, 0x5B, 0x7A, 0x24, 0x54, 0xFF, 0xC1, 0x0D, 0xFE
.byte 0x3A, 0x94, 0x7E, 0x56, 0xB3, 0x8A, 0x9F, 0xC0, 0x8F, 0x1A, 0x24, 0x1E, 0xB9, 0xBF, 0x78, 0x36
.byte 0xF6, 0x43, 0x44, 0xB9, 0x97, 0x50, 0x8C, 0xF2, 0xCB, 0xB0, 0x46, 0xCB, 0x72, 0x53, 0xC9, 0xAD
.byte 0xE8, 0x47, 0x04, 0x9B, 0xD1, 0xA3, 0x5C, 0x61, 0xBD, 0x81, 0x80, 0x77, 0x40, 0xF8, 0xAD, 0x37
.byte 0x3C, 0xF1, 0xF0, 0xD3, 0x42, 0x7D, 0xC5, 0x0D, 0x2D, 0x0C, 0xD8, 0xA0, 0x60, 0xA1, 0x4D, 0x48
.byte 0xE8, 0x51, 0xE4, 0xBA, 0xF4, 0x41, 0x1B, 0xB2, 0xC2, 0x9B, 0x2A, 0x03, 0x94, 0xD8, 0x3A, 0xD0
.byte 0xC9, 0x2A, 0xA4, 0x0B, 0xA7, 0x69, 0x19, 0xD5, 0x76, 0xF1, 0x75, 0xD6, 0x92, 0xC3, 0x1F, 0x7B
.byte 0x14, 0x03, 0x36, 0x09, 0x44, 0x52, 0xBC, 0x07, 0xEE, 0xE6, 0x0A, 0x82, 0xBE, 0x44, 0x53, 0x88
.byte 0x6F, 0xF7, 0x94, 0x17, 0x61, 0xAD, 0xED, 0xD8, 0x9F, 0x63, 0xAF, 0x32, 0x26, 0xCE, 0xAE, 0x3B
.byte 0xD2, 0xE4, 0x44, 0x17, 0x36, 0x00, 0x1E, 0x25, 0xE7, 0x28, 0xA8, 0xA5, 0x6D, 0xFB, 0x2E, 0xDC
.byte 0xF3, 0xC2, 0xF4, 0x55, 0x70, 0xE1, 0x2D, 0x0F, 0x44, 0xDC, 0x41, 0x6A, 0xAB, 0xEF, 0xA5, 0x7D
.byte 0xD4, 0xEA, 0x94, 0x0B, 0xEB, 0xB3, 0x30, 0xD2, 0xDC, 0xD9, 0x78, 0x49, 0xD5, 0xA6, 0x26, 0xC8
.byte 0x68, 0x1A, 0x1E, 0xD9, 0xFC, 0x4B, 0xE8, 0x40, 0x28, 0x2A, 0xAB, 0xD3, 0x19, 0x51, 0x51, 0xEE
.byte 0x3C, 0xE5, 0xF9, 0x27, 0x98, 0x2A, 0xFA, 0x74, 0x03, 0x72, 0xBE, 0xD8, 0x18, 0xE4, 0xA1, 0x81
.byte 0xFF, 0xBF, 0x5B, 0xFB, 0x0B, 0x43, 0x3C, 0x34, 0x6D, 0xE7, 0x07, 0x87, 0x39, 0x58, 0x75, 0x75
.byte 0x3E, 0x6F, 0x9C, 0xD7, 0x9A, 0x96, 0x4B, 0x9D, 0x08, 0x09, 0x76, 0x21, 0xEE, 0x17, 0xA3, 0xED
.byte 0xD7, 0xFE, 0xE8, 0xE2, 0x42, 0x24, 0x16, 0xB0, 0x0C, 0x1E, 0x37, 0x45, 0x77, 0xAD, 0xBA, 0xB6
.byte 0x1D, 0x56, 0x8D, 0xB7, 0xED, 0xD8, 0x55, 0xF6, 0xE2, 0xCB, 0x18, 0xD0, 0xE3, 0xBC, 0xBE, 0xBA
.byte 0xBB, 0xA7, 0x9D, 0xFD, 0xCB, 0xB4, 0xAD, 0xD8, 0xD2, 0xE5, 0x1D, 0x4A, 0x92, 0xD8, 0x00, 0xAF
.byte 0x2F, 0x8D, 0x67, 0x1C, 0x66, 0xBC, 0x13, 0x48, 0x87, 0x2B, 0x19, 0x6A, 0xE7, 0xD7, 0x24, 0xA3
.byte 0x7E, 0xC2, 0xA0, 0x4A, 0x76, 0x4E, 0x23, 0x49, 0x33, 0x41, 0x93, 0xC5, 0x19, 0x94, 0x75, 0x49
.byte 0x22, 0xDD, 0x66, 0x88, 0x99, 0x79, 0xD1, 0x21, 0xA5, 0xEB, 0x8B, 0x8D, 0xC3, 0xB0, 0x30, 0x42
.byte 0x72, 0xD0, 0x8C, 0xE9, 0x1E, 0xB0, 0x32, 0x52, 0xF1, 0xC5, 0x18, 0x0B, 0x5A, 0x8D, 0x54, 0x7C
.byte 0x6A, 0xBA, 0x04, 0x04, 0x34, 0xD6, 0x25, 0xD9, 0xC1, 0xB1, 0x66, 0x84, 0x62, 0x97, 0xC6, 0xD5
.byte 0x67, 0x53, 0xBE, 0x86, 0x03, 0xF0, 0xD8, 0xF5, 0xB6, 0xF0, 0x00, 0x10, 0x7E, 0x55, 0x8C, 0xE9
.byte 0x10, 0x91, 0xEE, 0x44, 0x67, 0x13, 0x1E, 0x29, 0xC5, 0x84, 0xAE, 0x27, 0x1B, 0x74, 0xFD, 0x83
.byte 0xC8, 0xBB, 0x0A, 0xCC, 0xAC, 0xE3, 0xC1, 0x62, 0xD4, 0xC2, 0x72, 0x53, 0x18, 0xFF, 0x3D, 0x28
.byte 0x90, 0x2B, 0x6D, 0xF8, 0x3F, 0x8B, 0x21, 0x04, 0x0F, 0xCF, 0x2C, 0x2B, 0x44, 0x29, 0xAF, 0x0D
.byte 0xE5, 0xB9, 0xD9, 0x91, 0x9D, 0x9B, 0xF3, 0x71, 0x5E, 0x66, 0xC5, 0x76, 0x65, 0x02, 0x9F, 0xF6
.byte 0x2D, 0x0C, 0xEF, 0x6D, 0x97, 0x11, 0x72, 0xA7, 0xE1, 0x9E, 0xD2, 0x25, 0xC8, 0x81, 0x33, 0xAD
.byte 0x3B, 0x0C, 0x3E, 0xD9, 0xA8, 0x32, 0x4B, 0x06, 0x98, 0x10, 0x7D, 0xFE, 0x12, 0x1C, 0xF5, 0x40
.byte 0x28, 0xE4, 0xAE, 0xBF, 0xF6, 0x20, 0x66, 0xD7, 0xBE, 0x39, 0xFD, 0x87, 0xBB, 0x30, 0x34, 0xF7
.byte 0x3C, 0x73, 0xD0, 0xE5, 0xA5, 0x1B, 0xEB, 0x3D, 0x2C, 0x68, 0x3C, 0x3F, 0x85, 0x31, 0x80, 0xAD
.byte 0x16, 0x2E, 0x6D, 0x0C, 0x4E, 0xD3, 0xE3, 0x0D, 0x0D, 0xE0, 0x94, 0xC8, 0x10, 0xC9, 0xBF, 0x4D
.byte 0x3C, 0x90, 0x32, 0xE2, 0xAC, 0x1E, 0x1F, 0xD8, 0x87, 0x5B, 0x18, 0x0C, 0x8D, 0x98, 0xB9, 0xA3
.byte 0xC6, 0x27, 0xAF, 0x15, 0xFA, 0x92, 0x22, 0x08, 0x73, 0xB7, 0xD0, 0x84, 0x81, 0x90, 0xD1, 0xBE
.byte 0x21, 0x04, 0xA0, 0xCD, 0x23, 0xC0, 0xA6, 0xAA, 0x1B, 0xBE, 0xB7, 0xA9, 0x56, 0x71, 0x4C, 0x1D
.byte 0x98, 0xFB, 0x32, 0x93, 0x8E, 0x55, 0x9B, 0x01, 0x0C, 0x6C, 0x85, 0x8E, 0xFD, 0x57, 0x4C, 0x1E
.byte 0x5C, 0xEC, 0xEC, 0x7F, 0xAC, 0x92, 0x2A, 0xC8, 0x51, 0xE2, 0x71, 0xA7, 0x53, 0xBE, 0xC5, 0xEB
.byte 0xBA, 0xF7, 0x7E, 0x48, 0x4C, 0x1A, 0x49, 0x59, 0x86, 0xCF, 0xE7, 0x83, 0x27, 0x33, 0xA2, 0x83
.byte 0x20, 0x8E, 0x03, 0xCC, 0x21, 0x2D, 0x95, 0x72, 0x0F, 0x07, 0x1A, 0x63, 0xC5, 0xDF, 0x4E, 0x7F
.byte 0xD7, 0xCD, 0xC7, 0x24, 0xE7, 0x11, 0x7D, 0x6E, 0xE1, 0x65, 0xF2, 0x08, 0x99, 0x94, 0x8B, 0xB9
.byte 0x23, 0x8E, 0x86, 0x44, 0xBC, 0x1C, 0xB6, 0xCC, 0x23, 0xD1, 0x2F, 0xE9, 0xB0, 0x7E, 0x68, 0x87
.byte 0x4C, 0x30, 0xAB, 0x33, 0x42, 0x29, 0xA2, 0x23, 0x8E, 0x94, 0x2C, 0x28, 0x29, 0xB8, 0xE1, 0x4C
.byte 0x47, 0x68, 0x91, 0x03, 0x84, 0x47, 0xD0, 0xA8, 0x18, 0x00, 0x91, 0xC9, 0x7F, 0xF9, 0x51, 0xCB
.byte 0x2A, 0xFC, 0xFE, 0x6C, 0x26, 0xA1, 0x90, 0xB4, 0x35, 0xBC, 0xDC, 0x5E, 0x74, 0xBE, 0xAB, 0xBC
.byte 0x26, 0x3C, 0xC0, 0xAB, 0x84, 0x90, 0x53, 0x9D, 0x91, 0xE4, 0x66, 0x10, 0xDE, 0xB8, 0xDB, 0x08
.byte 0xB4, 0xDA, 0x75, 0xDA, 0x7B, 0x05, 0x8F, 0xB1, 0xC2, 0x6C, 0x10, 0x37, 0x2B, 0xBB, 0xF3, 0x52
.byte 0xF8, 0xB3, 0xFD, 0x7C, 0x43, 0x51, 0x19, 0xD5, 0x35, 0x80, 0xE5, 0x14, 0x38, 0xC0, 0x1C, 0xED
.byte 0x9B, 0x91, 0xC8, 0x16, 0x97, 0x58, 0xC7, 0x59, 0xC5, 0xD7, 0x90, 0xF0, 0x93, 0x83, 0x42, 0x8B
.byte 0x36, 0x40, 0x08, 0x7A, 0x91, 0x22, 0x4F, 0xC7, 0xA3, 0x34, 0xDC, 0xDB, 0xF5, 0xF8, 0xC9, 0x90
.byte 0x8A, 0x92, 0xA7, 0x21, 0xEA, 0x6E, 0x7B, 0xB0, 0x46, 0x0B, 0xA0, 0xDA, 0x8E, 0xE3, 0x65, 0xC5
.byte 0x24, 0x6E, 0x3F, 0xB5, 0x90, 0x8F, 0x7D, 0x33, 0xC3, 0x59, 0x0F, 0xB9, 0x52, 0xD8, 0x49, 0xDD
.byte 0x6B, 0xF0, 0xFF, 0x56, 0x5F, 0x7A, 0x06, 0xA6, 0x85, 0xA7, 0x80, 0x14, 0x8A, 0xE6, 0xDA, 0xAE
.byte 0x54, 0x19, 0x64, 0xE4, 0xA9, 0xE2, 0x18, 0x6C, 0x3C, 0x27, 0x26, 0x8F, 0x00, 0x70, 0x6C, 0x6B
.byte 0x61, 0x6B, 0xC1, 0xC0, 0xE5, 0xC7, 0x67, 0x6B, 0x6F, 0xE8, 0x80, 0xF9, 0xCE, 0x5A, 0xA8, 0x23
.byte 0x73, 0x0D, 0x08, 0x1C, 0xF0, 0x20, 0x89, 0x2C, 0x47, 0xB0, 0xBC, 0x47, 0x20, 0x28, 0xB3, 0x81
.byte 0x94, 0x74, 0x41, 0x79, 0x3C, 0xA9, 0xE5, 0xAB, 0x91, 0x65, 0xA5, 0x60, 0xBF, 0x4E, 0x84, 0x33
.byte 0x5B, 0x8C, 0x50, 0x4C, 0xAC, 0xDA, 0x79, 0xF4, 0x8A, 0x35, 0x3C, 0xAA, 0x5D, 0xEF, 0x2B, 0xF2
.byte 0x64, 0x6D, 0x6C, 0xA0, 0x17, 0x51, 0x4C, 0xA8, 0xB6, 0xF1, 0x09, 0x76, 0x3F, 0x8D, 0xA9, 0x9B
.byte 0x1A, 0xFA, 0xE7, 0xC7, 0xD4, 0x60, 0xBB, 0x5E, 0x96, 0xF8, 0x09, 0xF4, 0xE7, 0x34, 0xE6, 0x4C
.byte 0xA2, 0x52, 0xED, 0xB9, 0xA3, 0x39, 0x62, 0x5A, 0x2A, 0x6B, 0xD0, 0x6A, 0xF8, 0x7A, 0x05, 0x12
.byte 0x74, 0xED, 0xD9, 0x48, 0x4E, 0x95, 0xA7, 0xE4, 0x8D, 0xB0, 0xD8, 0x75, 0xE5, 0xBE, 0xC2, 0x87
.byte 0x10, 0xAF, 0x41, 0xB4, 0xE8, 0xA3, 0x0E, 0x13, 0x0E, 0xDF, 0x7D, 0x07, 0x59, 0x83, 0x1A, 0xCD
.byte 0x70, 0xF4, 0x16, 0xBE, 0x89, 0xBE, 0xA3, 0x17, 0x6E, 0x7B, 0x8D, 0x54, 0x39, 0x4F, 0xDB, 0x4A
.byte 0xFE, 0x1C, 0xFE, 0xE7, 0xC0, 0x0D, 0xFA, 0xCE, 0xEC, 0x77, 0xD5, 0x46, 0xFA, 0xF0, 0x14, 0x6B
.byte 0xE4, 0x2A, 0x29, 0x6E, 0xE9, 0xCC, 0x85, 0x57, 0x48, 0x13, 0xAC, 0x82, 0x63, 0x88, 0xCC, 0x62
.byte 0xA5, 0xCB, 0x49, 0x65, 0xD9, 0x43, 0x33, 0xC5, 0xBB, 0x09, 0x0B, 0xB6, 0xF9, 0x1F, 0x21, 0xDD
.byte 0x4A, 0x4B, 0x4B, 0x33, 0x18, 0xD1, 0x8B, 0x60, 0xE4, 0x37, 0xE3, 0x48, 0xBF, 0xAF, 0xAA, 0x65
.byte 0x7B, 0xF3, 0xCA, 0x54, 0x37, 0xFE, 0x1A, 0xF2, 0x07, 0x25, 0xA9, 0x01, 0x45, 0xCA, 0xDF, 0x8F
.byte 0x16, 0x2B, 0xC3, 0x2E, 0xFD, 0x4E, 0x8F, 0xE2, 0x86, 0x72, 0x2A, 0x46, 0x22, 0xD4, 0xAB, 0x9D
.byte 0xC7, 0x75, 0xF2, 0xFE, 0x73, 0x0C, 0xF1, 0x7B, 0x32, 0x9A, 0x7D, 0x77, 0x65, 0x5C, 0x07, 0x7B
.byte 0x88, 0xCA, 0xAA, 0x85, 0x19, 0x39, 0x67, 0x9F, 0xAB, 0x91, 0xE6, 0xCD, 0x65, 0x91, 0x6B, 0x2C
.byte 0x06, 0x5D, 0x2B, 0x7A, 0x6A, 0x1D, 0xF6, 0x9C, 0xB7, 0x73, 0x14, 0x1D, 0xD0, 0x1B, 0x98, 0x58
.byte 0xE6, 0x42, 0xDD, 0xFF, 0x7C, 0x44, 0x9F, 0x27, 0xD5, 0x85, 0xF5, 0x3A, 0x16, 0x61, 0x67, 0x1D
.byte 0xBF, 0x93, 0x98, 0x2A, 0xB0, 0x8E, 0xC6, 0x68, 0x02, 0xDA, 0x85, 0xD2, 0xF5, 0x1E, 0x2A, 0xDB
.byte 0x61, 0x07, 0xDB, 0xDD, 0x4B, 0x7A, 0x05, 0x21, 0xFF, 0xFB, 0x5C, 0x16, 0x5D, 0xC4, 0x34, 0x1D
.byte 0x57, 0xCC, 0x47, 0x08, 0x5B, 0x0D, 0x71, 0x5D, 0xE8, 0xF7, 0x2F, 0xDE, 0x16, 0x5A, 0xBA, 0x77
.byte 0x61, 0x95, 0x55, 0xAD, 0x10, 0x5A, 0xCF, 0x10, 0x56, 0x2B, 0x26, 0xB3, 0xF0, 0x5A, 0xD1, 0x48
.byte 0x27, 0x18, 0x50, 0x82, 0x25, 0xC2, 0xDF, 0x0E, 0xB9, 0x0F, 0xEC, 0xD0, 0x69, 0xA6, 0x47, 0xCB
.byte 0x3C, 0x9D, 0x79, 0x4C, 0xF8, 0x48, 0x5C, 0x4E, 0x74, 0x83, 0x02, 0x64, 0xDD, 0xD3, 0xAC, 0x05
.byte 0xEB, 0xFD, 0x87, 0x11, 0xC0, 0x66, 0x20, 0x7A, 0x76, 0x0C, 0x4A, 0xDF, 0xB3, 0x92, 0xAB, 0xEF
.byte 0x2F, 0x24, 0x3B, 0x27, 0x6D, 0x98, 0x76, 0xE1, 0x1B, 0x78, 0x46, 0xF9, 0x4C, 0xF3, 0xFE, 0x38
.byte 0xF1, 0x85, 0x4A, 0xB1, 0xEC, 0x6A, 0x2C, 0x62, 0x77, 0x76, 0x42, 0x2A, 0x09, 0xED, 0x19, 0x38
.byte 0x11, 0x54, 0x60, 0x7E, 0xED, 0xD6, 0x60, 0x08, 0x4F, 0xA7, 0x02, 0x9C, 0x9B, 0x00, 0xD4, 0x8C
.byte 0x86, 0x1F, 0x3E, 0x73, 0x8A, 0x6A, 0xD5, 0x01, 0xE1, 0x18, 0x2B, 0xEA, 0x05, 0x44, 0x23, 0x16
.byte 0x99, 0x83, 0x95, 0x86, 0x59, 0xF6, 0x8F, 0xA9, 0x9D, 0x92, 0x45, 0x38, 0x93, 0x1A, 0xC5, 0x19
.byte 0x39, 0x03, 0x8D, 0xC3, 0x6E, 0x63, 0xC5, 0x50, 0x7B, 0xF0, 0x3B, 0x80, 0x35, 0x5E, 0x97, 0xCE
.byte 0xE2, 0x2C, 0x55, 0x3C, 0x23, 0xE5, 0xE5, 0xC0, 0x77, 0x2B, 0xF9, 0x0B, 0x45, 0xBE, 0x25, 0x7F
.byte 0xC2, 0xB2, 0x42, 0x31, 0x15, 0x07, 0x81, 0x90, 0xF8, 0xBC, 0x10, 0x2D, 0x1B, 0xA7, 0xFC, 0xFD
.byte 0xD4, 0x52, 0x3A, 0xF7, 0x38, 0x1F, 0xB8, 0xB0, 0x4A, 0xB1, 0xBB, 0x90, 0x70, 0xE0, 0x0F, 0x33
.byte 0x92, 0x51, 0x64, 0xA8, 0x59, 0xE6, 0x38, 0x52, 0xA3, 0x49, 0x7F, 0xBE, 0xF1, 0x7C, 0xBC, 0xC6
.byte 0xCF, 0xF6, 0xBD, 0x07, 0x16, 0x76, 0xB7, 0x60, 0x28, 0x73, 0xF1, 0x98, 0x53, 0x00, 0xCC, 0xE6
.byte 0x52, 0x30, 0x8E, 0xAC, 0x16, 0xC7, 0xFE, 0xBA, 0x10, 0x7E, 0x78, 0x01, 0xFA, 0x35, 0xC7, 0xCA
.byte 0x2B, 0x85, 0xD1, 0x41, 0xFB, 0x89, 0xA2, 0x24, 0xFC, 0x93, 0xBC, 0x50, 0x94, 0x89, 0x36, 0xE6
.byte 0xB9, 0xC5, 0x92, 0xD0, 0x8C, 0x90, 0x8A, 0x9D, 0x0F, 0x03, 0x9F, 0x0A, 0x38, 0x67, 0xD4, 0x64
.byte 0xED, 0xA6, 0xA6, 0xE8, 0x2F, 0x49, 0x0D, 0x2C, 0xDD, 0xCA, 0x7C, 0x71, 0x53, 0xB3, 0x57, 0x0C
.byte 0x79, 0xE9, 0xDD, 0x05, 0x7A, 0x68, 0xA3, 0x89, 0x6B, 0x42, 0x93, 0xA4, 0xA9, 0x67, 0x09, 0x96
.byte 0x0D, 0xAF, 0x7F, 0x3D, 0xF8, 0x8C, 0x6A, 0xD5, 0x57, 0xE6, 0x47, 0xAA, 0x9A, 0x9E, 0xB6, 0x14
.byte 0x88, 0x94, 0x1A, 0x03, 0xFD, 0xBD, 0x8D, 0x69, 0xFF, 0x20, 0x0D, 0xA9, 0x88, 0x16, 0x40, 0x96
.byte 0xC6, 0xC0, 0xD4, 0xBE, 0x4D, 0x3E, 0x94, 0xA4, 0x25, 0xDB, 0x4E, 0xC0, 0x7A, 0x05, 0xD4, 0x03
.byte 0x9A, 0xEE, 0x06, 0x97, 0xAB, 0x93, 0x00, 0xAB, 0xB4, 0x0D, 0x55, 0x3D, 0x24, 0x96, 0xD4, 0xEB
.byte 0x56, 0xA8, 0xA9, 0xA4, 0xE7, 0x3E, 0x48, 0x0D, 0x1A, 0x97, 0xCD, 0x94, 0x9C, 0xA1, 0x97, 0x36
.byte 0x90, 0x9D, 0xCE, 0x3C, 0x31, 0xCE, 0xE7, 0xE6, 0xDC, 0x3D, 0x23, 0x00, 0xD3, 0xF8, 0xEB, 0x29
.byte 0xA0, 0x95, 0xCD, 0x88, 0xD4, 0x16, 0x95, 0xEE, 0xAD, 0x62, 0x82, 0x4A, 0x04, 0x1A, 0x81, 0x94
.byte 0xB8, 0x4F, 0xD1, 0xE9, 0x1D, 0xB8, 0xCF, 0xF9, 0xF6, 0xF3, 0xFA, 0xC9, 0xEB, 0xE6, 0xF3, 0x8C
.byte 0x7C, 0xC1, 0x14, 0x50, 0xD7, 0xAA, 0x3F, 0x85, 0x0D, 0xC1, 0xCF, 0x12, 0xDB, 0x51, 0xA7, 0x93
.byte 0xA0, 0x78, 0x7D, 0xBD, 0x31, 0x4D, 0xB7, 0x27, 0x40, 0xB2, 0xF0, 0x2C, 0x99, 0xE4, 0xB8, 0x15
.byte 0xA5, 0xCD, 0x66, 0x7D, 0x78, 0xA5, 0x02, 0x85, 0x67, 0xD2, 0x97, 0x43, 0x23, 0x3E, 0xD7, 0xC4
.byte 0xB7, 0x55, 0x82, 0xE8, 0xA2, 0x39, 0x0F, 0xE3, 0xEC, 0xFF, 0x0F, 0x85, 0xE3, 0xC8, 0x9B, 0x89
.byte 0x96, 0x02, 0x06, 0x0E, 0xA8, 0x09, 0x93, 0x10, 0xDC, 0x2B, 0x53, 0xFF, 0x6A, 0x2B, 0xC4, 0x21
.byte 0x80, 0x46, 0x09, 0x22, 0x80, 0x19, 0x06, 0x6C, 0x18, 0x15, 0xF2, 0xFC, 0xDD, 0x8E, 0x86, 0x74
.byte 0x91, 0x8C, 0x82, 0x3A, 0x95, 0x16, 0x4A, 0x72, 0x42, 0x9E, 0x71, 0xAC, 0xC9, 0x35, 0xCE, 0x49
.byte 0x7C, 0xD8, 0x6C, 0xFC, 0xF1, 0x72, 0x69, 0x0A, 0x87, 0x5C, 0x06, 0x65, 0xEA, 0x8C, 0xD9, 0x7C
.byte 0x19, 0x5C, 0xB6, 0xAF, 0x72, 0x00, 0x21, 0xB4, 0x9E, 0x93, 0x61, 0x67, 0xC9, 0x2F, 0xB1, 0x45
.byte 0x08, 0x1D, 0x42, 0xF9, 0x8F, 0xAB, 0x03, 0x17, 0x07, 0x0A, 0x7D, 0xF2, 0x97, 0x57, 0x6E, 0xB0
.byte 0xB3, 0x24, 0x60, 0x26, 0x24, 0x81, 0xDB, 0xC2, 0x15, 0x3C, 0x2A, 0xDE, 0x6C, 0xDB, 0x24, 0x74
.byte 0xF9, 0x66, 0x6D, 0x89, 0x11, 0x71, 0xA1, 0x19, 0x7B, 0x1F, 0x0B, 0x12, 0x76, 0x79, 0xC3, 0x2A
.byte 0x9D, 0x23, 0x51, 0xC2, 0xA5, 0x2C, 0x85, 0xBA, 0x68, 0xAF, 0x98, 0xD5, 0x8B, 0xBC, 0x49, 0x85
.byte 0x23, 0xB7, 0x0F, 0x34, 0x29, 0xB0, 0x4D, 0xA4, 0xCF, 0x59, 0xB7, 0x46, 0xD2, 0x7B, 0x71, 0x70
.byte 0x9E, 0xC2, 0x32, 0x43, 0xEE, 0xB7, 0xFE, 0x57, 0x67, 0x96, 0x2D, 0xF3, 0x53, 0x76, 0x78, 0x76
.byte 0x2E, 0x87, 0xAB, 0x57, 0x38, 0xF9, 0xFC, 0x08, 0x52, 0xB3, 0x4E, 0x24, 0x2E, 0xC0, 0x95, 0xCD
.byte 0x82, 0xC7, 0x11, 0x71, 0x7E, 0x0F, 0xC9, 0xE6, 0xA6, 0xF6, 0xD9, 0xFA, 0x6D, 0x52, 0x71, 0x9C
.byte 0xDA, 0x1D, 0xF3, 0x13, 0x16, 0xF0, 0x1B, 0x68, 0xA3, 0x6A, 0x8D, 0xD2, 0x2A, 0x22, 0xA0, 0xAD
.byte 0xEA, 0xB2, 0x1E, 0x69, 0xC2, 0xE8, 0x4F, 0x69, 0xDF, 0x29, 0x63, 0x4C, 0x7C, 0xD5, 0xE8, 0x56
.byte 0xF2, 0xDC, 0x69, 0x08, 0xCC, 0x85, 0x71, 0x70, 0xEF, 0xFF, 0x43, 0x19, 0x22, 0xE4, 0xC6, 0x0C
.byte 0x96, 0xE5, 0x75, 0x59, 0xCE, 0xC5, 0xC2, 0xAD, 0xEE, 0x26, 0xF9, 0x6A, 0xFB, 0xE2, 0xC1, 0xED
.byte 0xBF, 0x2B, 0xF6, 0x8C, 0xB0, 0x67, 0xFD, 0x9F, 0x67, 0x40, 0xB9, 0x89, 0x25, 0x7F, 0x95, 0xBB
.byte 0x65, 0x0B, 0x14, 0x33, 0xD0, 0xD7, 0xE0, 0xBE, 0xFD, 0xDA, 0x29, 0xF8, 0xBD, 0xEA, 0xE6, 0x7D
.byte 0x15, 0xDC, 0x09, 0xC6, 0x44, 0x06, 0x66, 0xAB, 0x47, 0x1F, 0x34, 0x6C, 0x9F, 0xCA, 0x28, 0x04
.byte 0xD5, 0x3D, 0x38, 0xA5, 0x14, 0x19, 0x64, 0x11, 0xF4, 0x8D, 0x0A, 0xB2, 0x78, 0xF0, 0x2F, 0x8E
.byte 0xCC, 0x38, 0x54, 0x10, 0x3F, 0xBA, 0xBC, 0x86, 0xD9, 0xF1, 0xF3, 0x79, 0xBB, 0x1B, 0x7D, 0x91
.byte 0x59, 0xB6, 0x36, 0x6D, 0xCF, 0x9B, 0x7F, 0xC4, 0x28, 0x89, 0x76, 0xA0, 0x79, 0xA5, 0x2E, 0x46
.byte 0xDE, 0x83, 0x57, 0x1D, 0x3D, 0x13, 0xA4, 0x17, 0x04, 0x98, 0x90, 0xC0, 0xB3, 0x0E, 0x51, 0x0D
.byte 0xC4, 0x88, 0x7A, 0x94, 0x23, 0xFA, 0x58, 0x4C, 0x84, 0xCE, 0xEC, 0xFD, 0x74, 0x1B, 0x44, 0x52
.byte 0x9E, 0x9B, 0x70, 0xDC, 0xAF, 0x14, 0xF3, 0xB4, 0xAD, 0x84, 0x75, 0x61, 0x92, 0xC6, 0x6E, 0x56
.byte 0x4F, 0xE9, 0xEB, 0x73, 0xE3, 0x43, 0xBF, 0x67, 0x12, 0xAC, 0x65, 0x86, 0xC8, 0xAA, 0xD8, 0x66
.byte 0x45, 0x48, 0x43, 0xF5, 0x5D, 0x36, 0xA9, 0x0A, 0xBA, 0x1E, 0x6B, 0x4D, 0xE5, 0xDA, 0xA4, 0x35
.byte 0xC3, 0x8F, 0xA8, 0xA7, 0xD3, 0x68, 0x0E, 0xE5, 0x15, 0x74, 0x6B, 0xDD, 0x1E, 0x44, 0x44, 0x64
.byte 0x8D, 0x87, 0x59, 0xEB, 0xBE, 0x03, 0xF6, 0x79, 0x22, 0x62, 0xC6, 0x07, 0x3C, 0x6A, 0x3D, 0xFF
.byte 0xFA, 0xE5, 0xA6, 0xCD, 0x4E, 0xB5, 0xB2, 0x63, 0x29, 0x1E, 0x41, 0x48, 0x63, 0x86, 0xAC, 0xF0
.byte 0x0E, 0x05, 0xDC, 0xCD, 0x09, 0xD2, 0x46, 0x2B, 0x34, 0x0D, 0x32, 0x70, 0x78, 0x6F, 0x70, 0x72
.byte 0x55, 0x17, 0x3F, 0xA4, 0xCC, 0xF2, 0x08, 0xF6, 0x11, 0x4A, 0x3E, 0x74, 0xD0, 0xEA, 0x65, 0xDF
.byte 0xF0, 0x41, 0xAC, 0xF9, 0x13, 0xF2, 0x24, 0x48, 0xFF, 0x57, 0xB9, 0x77, 0xC7, 0x29, 0xEA, 0x1D
.byte 0x40, 0x29, 0xC1, 0x0D, 0x1B, 0xCA, 0x03, 0x2D, 0x14, 0x41, 0xA1, 0xE5, 0x2C, 0x06, 0xC4, 0x1C
.byte 0x48, 0x70, 0x16, 0x5C, 0x62, 0x3B, 0xA4, 0x62, 0x93, 0x5E, 0xDA, 0x5A, 0x87, 0xC4, 0x78, 0xC8
.byte 0xEE, 0x3A, 0xD6, 0x0A, 0x04, 0xD9, 0x37, 0x18, 0x1B, 0xD8, 0xFD, 0x48, 0xDF, 0xC1, 0x65, 0x27
.byte 0x32, 0x7B, 0x83, 0x94, 0xB7, 0x28, 0xF7, 0x4A, 0x86, 0xD2, 0xA5, 0x0E, 0x96, 0x1D, 0xD7, 0x85
.byte 0x57, 0xAD, 0x8F, 0x5C, 0x87, 0xC6, 0x75, 0xA3, 0x9F, 0x73, 0xEC, 0x7F, 0x35, 0x51, 0xA6, 0x67
.byte 0xCD, 0x2A, 0xFC, 0x84, 0x53, 0xF3, 0xCE, 0xDA, 0xC5, 0x73, 0xE8, 0x5C, 0x91, 0xC0, 0xE1, 0xE8
.byte 0x6E, 0x70, 0x45, 0xF6, 0x37, 0xBA, 0x9A, 0xD7, 0x2D, 0x86, 0x56, 0x62, 0xD7, 0xFD, 0xCA, 0xA4
.byte 0x28, 0xC6, 0x29, 0x7B, 0xB9, 0xF7, 0x55, 0x7E, 0x6B, 0x3E, 0xDB, 0xFC, 0xFE, 0xBC, 0xE5, 0x6D
.byte 0x2D, 0x2A, 0x63, 0x64, 0xE5, 0xFD, 0x3B, 0x12, 0x84, 0x92, 0x75, 0x5B, 0x8F, 0x3F, 0x00, 0xB7
.byte 0x05, 0x2A, 0x32, 0xBF, 0x22, 0x88, 0x3E, 0x8D, 0xC6, 0x19, 0x8A, 0xC5, 0xD5, 0x70, 0x32, 0x03
.byte 0x9A, 0x96, 0x67, 0x80, 0x94, 0xA3, 0x93, 0x18, 0x35, 0x08, 0x74, 0xC4, 0x48, 0x74, 0x7C, 0x4E
.byte 0x9F, 0xAF, 0x0D, 0xC1, 0x37, 0x4B, 0x4F, 0xFE, 0x65, 0xD9, 0xC4, 0x3B, 0x49, 0xF7, 0x3E, 0xE4
.byte 0x8D, 0xA5, 0x64, 0x22, 0x49, 0xF7, 0x3A, 0x7E, 0x00, 0xAE, 0x43, 0x49, 0x23, 0xC0, 0x97, 0xC2
.byte 0x6F, 0xA4, 0x83, 0xA7, 0xF0, 0xD2, 0xA6, 0x55, 0xAC, 0x6A, 0x90, 0xF6, 0x61, 0xCF, 0xDA, 0xEF
.byte 0x74, 0x3F, 0x11, 0xBD, 0x37, 0x4C, 0x3C, 0x38, 0xFA, 0x80, 0x81, 0x1E, 0x40, 0x18, 0xE0, 0xAF
.byte 0xBD, 0x64, 0x57, 0xAE, 0x37, 0xFD, 0x04, 0xE4, 0x67, 0x95, 0xDA, 0xC9, 0x64, 0xB5, 0xB9, 0xD8
.byte 0xF5, 0xCB, 0x96, 0x2C, 0x17, 0xD3, 0x64, 0x12, 0x54, 0xE6, 0x30, 0x94, 0xFE, 0x11, 0x44, 0xBC
.byte 0x76, 0x9B, 0x6A, 0xAE, 0x99, 0x6E, 0x92, 0x00, 0x03, 0x6D, 0xCA, 0x67, 0x22, 0x84, 0x40, 0x17
.byte 0x4F, 0xD7, 0x44, 0x67, 0xAB, 0xA8, 0x79, 0xFF, 0x8E, 0xAA, 0x94, 0x8D, 0xBC, 0xD8, 0x49, 0x32
.byte 0x74, 0xB4, 0xE0, 0x0D, 0x22, 0x73, 0x0E, 0x26, 0xE0, 0xD9, 0x8E, 0x02, 0x5D, 0xCE, 0x1A, 0xAC
.byte 0xA6, 0x5E, 0x14, 0x51, 0x07, 0x8D, 0x51, 0x96, 0x38, 0xE5, 0x23, 0xF4, 0xBE, 0x6D, 0x26, 0x32
.byte 0x21, 0x07, 0x40, 0x44, 0x7A, 0x4E, 0x6A, 0x5A, 0x28, 0xF8, 0x5D, 0x85, 0xC7, 0x77, 0x32, 0x6E
.byte 0xD5, 0x46, 0xC0, 0xDC, 0xD4, 0x11, 0x72, 0x0C, 0xF6, 0x96, 0x00, 0xB4, 0x03, 0x27, 0xE7, 0x25
.byte 0x2F, 0x28, 0x69, 0xA9, 0x76, 0xD3, 0x04, 0x9F, 0xCC, 0x61, 0x24, 0x94, 0xD9, 0x56, 0x02, 0xAE
.byte 0x9C, 0xC2, 0x8B, 0x70, 0xD4, 0xFE, 0x7D, 0xCB, 0x94, 0x7D, 0x7F, 0x98, 0xA5, 0x67, 0xBD, 0xD4
.byte 0x8F, 0x26, 0x7E, 0x06, 0xFA, 0x83, 0xA5, 0xC7, 0xE5, 0xCA, 0x5B, 0xBE, 0x20, 0x5E, 0x6D, 0xBD
.byte 0x21, 0xF8, 0x2E, 0xF5, 0xF6, 0xAB, 0xC0, 0x8B, 0x29, 0x40, 0x23, 0xCF, 0xA8, 0xE0, 0xA3, 0x37
.byte 0x07, 0x22, 0x3E, 0x02, 0xA5, 0xE3, 0xC9, 0x8A, 0xAD, 0x25, 0x49, 0xCE, 0x83, 0xB6, 0x8C, 0xA4
.byte 0xAE, 0xBA, 0x99, 0xA5, 0x65, 0x5A, 0x30, 0x8F, 0x9A, 0x54, 0x5E, 0x42, 0x35, 0x02, 0x7A, 0x3C
.byte 0x24, 0xB8, 0x3E, 0xCA, 0x9C, 0x08, 0x55, 0x4A, 0x2D, 0x9E, 0x19, 0xB0, 0x54, 0xA5, 0x55, 0x02
.byte 0x5F, 0xEE, 0xA8, 0xC5, 0x49, 0xD8, 0x54, 0xE4, 0x2C, 0xB3, 0x27, 0x61, 0xB5, 0xA1, 0x9E, 0xDA
.byte 0x5A, 0xDD, 0xA4, 0xF7, 0xE5, 0xFA, 0x41, 0x13, 0x98, 0x5B, 0xC3, 0xED, 0x00, 0x18, 0xF0, 0x60
.byte 0x07, 0x98, 0x25, 0x50, 0x71, 0x7A, 0x35, 0x9E, 0x2D, 0x5C, 0x00, 0xE3, 0xFE, 0x9E, 0xBD, 0x58
.byte 0x7C, 0x62, 0x50, 0x62, 0x5C, 0x92, 0x75, 0xF5, 0xED, 0x39, 0xE2, 0xEE, 0x51, 0xD2, 0x4E, 0x59
.byte 0x6B, 0x74, 0xAA, 0xDC, 0xEE, 0xDF, 0x7B, 0x1C, 0x3B, 0x7B, 0xFF, 0x3A, 0x1A, 0xBC, 0x93, 0x96
.byte 0x1E, 0xE3, 0xF8, 0x7B, 0x75, 0x6E, 0x71, 0x63, 0xA7, 0x53, 0x51, 0xF9, 0x26, 0x9F, 0x52, 0x92
.byte 0x13, 0xFC, 0x6F, 0x02, 0xDC, 0xEA, 0x1E, 0x17, 0x65, 0x1D, 0x52, 0x7F, 0xD9, 0xE5, 0x16, 0xF8
.byte 0xC8, 0x0F, 0x74, 0x3D, 0x7D, 0xE5, 0xA0, 0x24, 0x39, 0xF2, 0x1D, 0x5F, 0x91, 0x70, 0xF2, 0xA5
.byte 0x6C, 0x61, 0xA7, 0x48, 0x4B, 0xC5, 0x60, 0xB0, 0xE2, 0xB2, 0x30, 0xBC, 0x97, 0x46, 0xB4, 0x60
.byte 0x55, 0x29, 0x9E, 0xD3, 0x0E, 0x3F, 0xF7, 0x47, 0x31, 0x15, 0xA7, 0xC2, 0x85, 0x99, 0x67, 0xF2
.byte 0xFB, 0x0E, 0x3A, 0x46, 0xD4, 0x9B, 0xF7, 0xB6, 0x4E, 0x28, 0x73, 0xE6, 0x6E, 0x27, 0x46, 0xC4
.byte 0x51, 0xE4, 0x97, 0x5F, 0x23, 0x8F, 0xA7, 0x54, 0xA4, 0x4E, 0x17, 0x29, 0xE8, 0x7F, 0x1B, 0xE4
.byte 0x8E, 0x56, 0x2A, 0x62, 0xF2, 0x22, 0x19, 0x40, 0x4A, 0x8C, 0x26, 0xB9, 0xB4, 0x6D, 0x7D, 0x05
.byte 0x51, 0x14, 0x64, 0x75, 0xA4, 0x0C, 0xC9, 0x48, 0x5B, 0xE1, 0x72, 0x44, 0x60, 0x8D, 0x28, 0xEE
.byte 0xE4, 0x53, 0x50, 0xD6, 0x75, 0x69, 0x16, 0xC0, 0xF6, 0x3D, 0x79, 0xAA, 0xAA, 0xF6, 0xAF, 0xFC
.byte 0x0B, 0x14, 0x71, 0xAF, 0x21, 0x3B, 0xF8, 0x7C, 0x1C, 0x6A, 0xC0, 0x7C, 0xF8, 0xE8, 0x6A, 0xDC
.byte 0x3B, 0xBB, 0xB3, 0xB1, 0x25, 0xCA, 0x71, 0x1B, 0x07, 0xEB, 0xC6, 0xB2, 0xE1, 0x76, 0xAE, 0xED
.byte 0x8A, 0x1F, 0x9D, 0xAB, 0x5A, 0x95, 0x28, 0x76, 0x00, 0xE8, 0xF3, 0xF8, 0xD1, 0x5E, 0xD5, 0x0D
.byte 0x1A, 0x88, 0xBE, 0x3F, 0x52, 0x30, 0x5B, 0x5A, 0x1B, 0x22, 0x0C, 0xFD, 0x98, 0xBB, 0xEB, 0x23
.byte 0xDB, 0x88, 0xCF, 0x36, 0x1E, 0xF7, 0xAD, 0x1E, 0xE0, 0xA0, 0x17, 0xB1, 0xFE, 0xEC, 0xBE, 0x18
.byte 0x74, 0x7D, 0x58, 0xC7, 0xAD, 0xB4, 0x21, 0xC9, 0xD6, 0x2E, 0xC7, 0x6E, 0xEA, 0xB2, 0x91, 0xC5
.byte 0x3B, 0x61, 0xFB, 0x59, 0x58, 0xA8, 0x78, 0x38, 0x49, 0x8F, 0xE9, 0x48, 0x7B, 0xA8, 0x61, 0xF0
.byte 0x25, 0xBA, 0xB7, 0xD3, 0x6E, 0xD9, 0x9D, 0x45, 0x08, 0x64, 0xB4, 0xF2, 0x16, 0x46, 0xB7, 0x51
.byte 0xA7, 0xB3, 0xAB, 0xFF, 0x5C, 0x23, 0x38, 0xA6, 0xB2, 0x22, 0xEE, 0x2E, 0xCA, 0x4F, 0x1E, 0xF0
.byte 0x09, 0xD5, 0xC4, 0x78, 0xAF, 0x62, 0xBD, 0xB7, 0xC6, 0x72, 0xA9, 0xDD, 0xB8, 0x61, 0x2F, 0x5F
.byte 0x15, 0xDA, 0x5F, 0x71, 0xFE, 0x97, 0x17, 0xB1, 0xB9, 0x06, 0xDF, 0x84, 0x56, 0xFE, 0x75, 0x60
.byte 0xD3, 0x3A, 0xD8, 0x83, 0x9C, 0x96, 0x3A, 0x63, 0x08, 0xE3, 0x40, 0xC1, 0x45, 0x6F, 0x20, 0x5A
.byte 0x4A, 0x7F, 0xCC, 0x49, 0x17, 0xE4, 0xFA, 0xD1, 0xEA, 0xDA, 0x56, 0x40, 0xD8, 0xCB, 0xA0, 0xAC
.byte 0x06, 0x79, 0x2F, 0xA3, 0x10, 0x69, 0x06, 0x19, 0x4D, 0x47, 0xDA, 0x92, 0xB7, 0xFB, 0xED, 0x02
.byte 0x7B, 0xB9, 0x4B, 0x93, 0x9D, 0x45, 0x64, 0x88, 0x20, 0xBA, 0xC9, 0xF8, 0x86, 0x6A, 0xA5, 0x8D
.byte 0xE4, 0xD5, 0x30, 0xF4, 0x3E, 0x37, 0x0E, 0x8C, 0x7E, 0xE9, 0x1F, 0x35, 0xE5, 0x0C, 0x37, 0x60
.byte 0xC6, 0x82, 0xF3, 0x64, 0xC8, 0x58, 0xED, 0xE9, 0x13, 0xB6, 0xE2, 0x99, 0x21, 0x87, 0x27, 0x05
.byte 0x5C, 0x57, 0xFA, 0x9B, 0x8E, 0x09, 0x28, 0x0C, 0xF2, 0x47, 0x42, 0xD7, 0x54, 0x7A, 0x38, 0x1B
.byte 0xFD, 0x2C, 0x7F, 0xC5, 0x84, 0x6D, 0xAF, 0x98, 0x23, 0x91, 0x32, 0x45, 0x18, 0x59, 0x4A, 0x75
.byte 0xB0, 0x44, 0x11, 0x3F, 0x4D, 0x39, 0x4C, 0x40, 0x81, 0x8E, 0x18, 0xD5, 0x09, 0x51, 0xF1, 0x06
.byte 0x7D, 0x71, 0xCC, 0x02, 0xDE, 0x7B, 0x9A, 0x02, 0x0C, 0xCC, 0x47, 0x25, 0x26, 0x91, 0x9A, 0xD6
.byte 0xD6, 0xAB, 0x16, 0x24, 0xE4, 0x62, 0x65, 0x66, 0xF1, 0x7D, 0x3B, 0xFA, 0xCE, 0x2C, 0x00, 0x4C
.byte 0x9D, 0xCC, 0x4F, 0x7C, 0x48, 0xEA, 0x7E, 0x54, 0xB7, 0xC5, 0x79, 0xDD, 0x57, 0x14, 0xB4, 0x2D
.byte 0xC0, 0xCA, 0x51, 0xA4, 0x2D, 0xB6, 0x0A, 0x1E, 0x34, 0x46, 0x19, 0x03, 0x73, 0x1A, 0x4F, 0x11
.byte 0xE7, 0x9E, 0x8D, 0x2F, 0x88, 0x0B, 0x84, 0x3F, 0xD0, 0xFD, 0x1D, 0x27, 0x12, 0xD1, 0x55, 0xD2
.byte 0x9B, 0xA7, 0x77, 0xC8, 0x5E, 0x82, 0xE7, 0x92, 0xC8, 0x00, 0x95, 0x3C, 0x1A, 0xE5, 0x4D, 0x01
.byte 0x84, 0xDA, 0x31, 0x0D, 0xE6, 0xB5, 0x4D, 0xB7, 0xB2, 0x6A, 0xDE, 0xC5, 0x3B, 0x34, 0x97, 0xD6
.byte 0xDB, 0x0E, 0x9E, 0x39, 0x90, 0x85, 0xCC, 0x59, 0x86, 0x62, 0x95, 0xA0, 0x47, 0xE3, 0xA2, 0xCB
.byte 0xBD, 0xD3, 0xD9, 0xA4, 0x88, 0x26, 0x5B, 0x3B, 0x90, 0x3A, 0x00, 0xCB, 0x6E, 0x97, 0xA1, 0x4A
.byte 0xA6, 0x40, 0x84, 0x36, 0xC6, 0x50, 0x8F, 0x4D, 0xB3, 0x25, 0xED, 0xFA, 0x08, 0x90, 0xC6, 0xC6
.byte 0x64, 0x9F, 0x6A, 0xEC, 0xC5, 0xC5, 0x28, 0x55, 0x00, 0x29, 0x21, 0x6E, 0xC1, 0xC3, 0xB9, 0x67
.byte 0x04, 0x3D, 0x9D, 0xCA, 0x8E, 0x2D, 0x17, 0x41, 0x52, 0x05, 0x3C, 0x5A, 0x96, 0x02, 0x21, 0xFA
.byte 0xA2, 0x8B, 0xE6, 0x68, 0x51, 0x0F, 0xBE, 0x51, 0x38, 0xDF, 0xC0, 0xF9, 0xA2, 0x79, 0x60, 0xA6
.byte 0xB7, 0xFE, 0x71, 0x45, 0x2B, 0x89, 0x86, 0x7E, 0x8E, 0xC3, 0xD9, 0x25, 0xC5, 0xFA, 0x1F, 0x68
.byte 0x85, 0x05, 0xD0, 0xD7, 0x15, 0x8E, 0x28, 0x4D, 0x6E, 0xE9, 0x47, 0x10, 0x63, 0xA8, 0xB7, 0x1A
.byte 0xA6, 0x29, 0x60, 0xD2, 0xB2, 0xE7, 0x51, 0x41, 0xAA, 0x2A, 0x66, 0x70, 0x24, 0x85, 0xD8, 0xAA
.byte 0x8B, 0xA9, 0x81, 0xA0, 0x37, 0xAA, 0xEE, 0xA6, 0x94, 0x35, 0xB7, 0xF7, 0xDE, 0x6E, 0x12, 0x84
.byte 0x97, 0x72, 0x57, 0x4A, 0x5A, 0xA8, 0x8B, 0x04, 0xD3, 0xF1, 0x74, 0xF8, 0x77, 0x4D, 0xA3, 0x02
.byte 0xF6, 0x25, 0xA3, 0x2E, 0xCF, 0x91, 0xD4, 0x64, 0xC7, 0x8B, 0x5C, 0xA5, 0xFA, 0x6E, 0x2A, 0x91
.byte 0xE1, 0x82, 0xDB, 0x3B, 0x2B, 0x67, 0x40, 0xFE, 0x59, 0xB4, 0xF6, 0xD0, 0x01, 0x9A, 0xD3, 0xF8
.byte 0xBF, 0x76, 0x26, 0x8E, 0x08, 0xFA, 0xF3, 0xCF, 0x86, 0x4F, 0x75, 0x80, 0xBE, 0x9F, 0x11, 0x9F
.byte 0x22, 0xED, 0xDB, 0x4D, 0x55, 0x1B, 0x4B, 0xAE, 0xCF, 0x42, 0x7E, 0xD1, 0xDC, 0x51, 0xC9, 0x9B
.byte 0xC8, 0xF0, 0x2A, 0xD0, 0xEA, 0x1E, 0xA0, 0x71, 0x6D, 0x15, 0xF1, 0x2B, 0xB5, 0x03, 0xCB, 0xD7
.byte 0xF0, 0xA6, 0x24, 0x46, 0xC1, 0x70, 0xF4, 0x91, 0xB3, 0x73, 0x62, 0x90, 0xC5, 0x2C, 0x2C, 0x8D
.byte 0x1C, 0x57, 0x5E, 0x07, 0x75, 0xFE, 0x78, 0xE3, 0x14, 0x69, 0x0E, 0xC9, 0x6C, 0xD9, 0xA0, 0x5D
.byte 0x80, 0xC5, 0xA3, 0x41, 0x36, 0x98, 0xD2, 0xE9, 0x0B, 0x35, 0x79, 0xD0, 0x62, 0xA6, 0x5D, 0x7E
.byte 0xFD, 0xBC, 0x86, 0x73, 0xBA, 0xFE, 0x56, 0xCE, 0x68, 0x64, 0x98, 0xD5, 0x3E, 0x39, 0x33, 0xBF
.byte 0xFE, 0xD7, 0x00, 0x34, 0x6F, 0xD3, 0x1E, 0x7A, 0x09, 0x98, 0x4B, 0x6B, 0x3E, 0xA8, 0xEA, 0x3C
.byte 0x64, 0x70, 0xAF, 0x1F, 0x6E, 0x05, 0xEE, 0xD7, 0x6A, 0x86, 0xAC, 0xA9, 0xBF, 0xDF, 0x68, 0xBE
.byte 0xB7, 0x68, 0xF3, 0x26, 0x3C, 0x11, 0xA1, 0x45, 0xAA, 0xEC, 0xB0, 0xE9, 0x95, 0x9B, 0x25, 0xF9
.byte 0x0B, 0xD4, 0x19, 0x7A, 0xDA, 0x07, 0x51, 0x44, 0x8E, 0xFE, 0xED, 0x4E, 0xDE, 0x55, 0x0D, 0x95
.byte 0xBE, 0x00, 0xBB, 0xFB, 0x12, 0x5D, 0x40, 0xBC, 0x49, 0xF1, 0xA6, 0xDE, 0x8C, 0xCB, 0xD8, 0x98
.byte 0xA0, 0xF1, 0x12, 0x7A, 0xF9, 0x63, 0xBE, 0x88, 0x61, 0xAC, 0xD6, 0x40, 0x01, 0xE3, 0xD5, 0xC0
.byte 0xE4, 0x91, 0xBB, 0xF6, 0xEE, 0xFC, 0xB3, 0x37, 0xED, 0x59, 0x16, 0x7A, 0x25, 0xEE, 0x12, 0xC5
.byte 0xE0, 0x24, 0x3F, 0xD9, 0x88, 0xFE, 0x62, 0xEA, 0xAA, 0x38, 0x2A, 0xAC, 0x1C, 0x00, 0x6C, 0x00
.byte 0x91, 0x27, 0xF6, 0x7F, 0x24, 0xAA, 0xB7, 0x12, 0x04, 0xCD, 0x8C, 0x29, 0xBB, 0x9F, 0xEE, 0x9C
.byte 0xC4, 0x2E, 0x76, 0x4D, 0x2C, 0xD8, 0x37, 0xD6, 0x10, 0x62, 0x82, 0x2C, 0x63, 0xEF, 0x2C, 0xF4
.byte 0x17, 0x23, 0x74, 0x3B, 0xCE, 0x2C, 0x4D, 0xD2, 0xF9, 0xDA, 0xFC, 0xB5, 0x79, 0xEA, 0x51, 0x3E
.byte 0x19, 0xC7, 0x8B, 0x45, 0x9F, 0xC3, 0x1C, 0xB0, 0x26, 0x9F, 0xDD, 0x89, 0x8F, 0x0A, 0x7E, 0xA6
.byte 0x2D, 0xF2, 0xE1, 0xFC, 0x1E, 0x2F, 0xCE, 0x18, 0x09, 0xCB, 0xCD, 0x83, 0xB6, 0x1F, 0xC1, 0xCF
.byte 0xE7, 0x4D, 0x15, 0x87, 0x10, 0x31, 0x37, 0x37, 0xD1, 0x14, 0xC0, 0x60, 0x1F, 0x3E, 0x06, 0x4C
.byte 0x31, 0xE8, 0x49, 0x50, 0x17, 0x18, 0x68, 0x21, 0xE3, 0x36, 0xA5, 0x99, 0x55, 0x66, 0x68, 0x3D
.byte 0xB4, 0x7D, 0xC4, 0xC5, 0xAF, 0xFB, 0xFC, 0x80, 0x10, 0xBC, 0xE0, 0x2F, 0xFB, 0xE7, 0x7C, 0x2C
.byte 0xD0, 0xC5, 0x7D, 0xE7, 0xDD, 0xE5, 0x09, 0xC0, 0x1C, 0xAE, 0x5A, 0x72, 0x15, 0xC2, 0xAF, 0xC9
.byte 0x3F, 0x73, 0x8E, 0xEF, 0x6F, 0x8B, 0x6F, 0x80, 0x47, 0x50, 0xAF, 0x43, 0x37, 0x2C, 0x6F, 0x07
.byte 0xF2, 0xED, 0xEF, 0xD0, 0xD2, 0xF9, 0x91, 0xEF, 0xA7, 0xEB, 0x61, 0xBD, 0xAD, 0x10, 0x87, 0xED
.byte 0x84, 0x16, 0xDC, 0xF3, 0xA1, 0x4C, 0x73, 0xE8, 0x9C, 0x23, 0x2B, 0xD4, 0x4F, 0x9B, 0xDC, 0x42
.byte 0x88, 0xCB, 0x12, 0x5B, 0xC5, 0xA3, 0x4B, 0x6D, 0x8E, 0xAC, 0x2A, 0x3C, 0xBD, 0xB1, 0x29, 0x41
.byte 0xC7, 0x06, 0x34, 0x68, 0x52, 0xA8, 0x51, 0xEE, 0xCB, 0x7D, 0xC2, 0x1B, 0x19, 0x9E, 0x5D, 0xA2
.byte 0x6A, 0x70, 0xFE, 0x2F, 0x13, 0x49, 0x9C, 0xA2, 0xF5, 0xC7, 0xDF, 0xB2, 0x79, 0x08, 0xF3, 0x41
.byte 0x0E, 0x28, 0xA9, 0x61, 0xD0, 0xFB, 0x4F, 0x9B, 0x79, 0x12, 0xB7, 0x92, 0xB1, 0x15, 0x35, 0x1C
.byte 0x85, 0x33, 0x4C, 0x99, 0x7C, 0xE9, 0x3B, 0x72, 0xB1, 0x1A, 0x24, 0x2A, 0x23, 0x18, 0x6B, 0x32
.byte 0x41, 0x15, 0x93, 0x11, 0x10, 0xE3, 0xAD, 0x8A, 0xF6, 0x64, 0x1C, 0xA8, 0x7A, 0x51, 0xC4, 0xFF
.byte 0x85, 0x11, 0x98, 0x02, 0xFB, 0xD4, 0x74, 0xAC, 0xEF, 0x99, 0xD6, 0x12, 0xB2, 0x41, 0x45, 0xF3
.byte 0x56, 0xD8, 0x04, 0x67, 0xBC, 0xB2, 0xF1, 0xB3, 0x17, 0x0E, 0x5B, 0x91, 0x60, 0x20, 0x90, 0xE5
.byte 0x31, 0x29, 0xE7, 0x2C, 0xFD, 0x5C, 0xD9, 0xEC, 0xF5, 0xAF, 0xFF, 0xA7, 0xF0, 0x44, 0x9A, 0x47
.byte 0x1D, 0x9F, 0xAF, 0xD9, 0x52, 0xA0, 0x8C, 0x69, 0xAF, 0xE8, 0xFB, 0x0F, 0x08, 0x8C, 0xF5, 0x3A
.byte 0xB5, 0xDD, 0x67, 0xB3, 0x39, 0x40, 0x9F, 0x2E, 0xEF, 0x9E, 0xD6, 0xE0, 0xE3, 0x71, 0x28, 0x00
.byte 0x11, 0xD7, 0xDA, 0x63, 0x78, 0x67, 0xCD, 0x27, 0x4F, 0xC9, 0x36, 0x58, 0x55, 0x2C, 0x92, 0x0B
.byte 0x09, 0xF9, 0xBE, 0x42, 0x39, 0x5E, 0x71, 0x29, 0xFD, 0x48, 0x09, 0xE0, 0xB9, 0x31, 0xE0, 0xCA
.byte 0x09, 0xBB, 0x2E, 0x81, 0x22, 0xFC, 0xA8, 0x72, 0xC5, 0xDF, 0xCA, 0x1A, 0x0B, 0x5C, 0x25, 0x14
.byte 0x56, 0xE4, 0x57, 0x90, 0x42, 0xC9, 0xB9, 0x3F, 0x11, 0xC3, 0x1F, 0xCA, 0xF5, 0x00, 0x95, 0xFE
.byte 0xBC, 0xC4, 0x7F, 0xDF, 0xC0, 0x27, 0x51, 0x85, 0x07, 0x1B, 0xA0, 0x12, 0x78, 0xC6, 0x27, 0xCE
.byte 0xAA, 0x7E, 0x5E, 0xEC, 0x48, 0x18, 0x2C, 0x59, 0xDB, 0x4C, 0x24, 0xD0, 0x4D, 0xBA, 0xCF, 0x09
.byte 0x7E, 0x4E, 0xE8, 0x3E, 0x76, 0x3A, 0xC4, 0x7E, 0x55, 0x64, 0x90, 0xCE, 0x2A, 0xB8, 0x9C, 0xD4
.byte 0x37, 0xFB, 0xC1, 0x7F, 0x14, 0xEE, 0xD8, 0xEF, 0x3A, 0xFD, 0xC0, 0x88, 0xB7, 0x90, 0x92, 0x36
.byte 0xDE, 0x7A, 0x75, 0x55, 0xB5, 0x39, 0xD3, 0x0A, 0x9E, 0x64, 0xD9, 0xC8, 0x1C, 0x76, 0x9D, 0x53
.byte 0x71, 0x5F, 0xD2, 0x86, 0x4D, 0xAB, 0x76, 0x88, 0xA9, 0x36, 0x11, 0x61, 0xC6, 0xA3, 0x97, 0xA5
.byte 0x1E, 0x0D, 0xFB, 0xD3, 0x46, 0xCF, 0xDE, 0xE5, 0x34, 0xB7, 0xAD, 0x50, 0x2D, 0x4B, 0xA4, 0x9F
.byte 0xAA, 0x77, 0x25, 0xF8, 0x22, 0x9B, 0x80, 0xCC, 0xD2, 0x91, 0x2D, 0x99, 0x35, 0xC5, 0x3F, 0x53
.byte 0xD2, 0x3B, 0x26, 0x19, 0x0A, 0x04, 0xFE, 0x3E, 0xBB, 0xAC, 0x8F, 0xE9, 0xF7, 0x33, 0x88, 0xA1
.byte 0xAA, 0xAE, 0x9A, 0xCD, 0x49, 0x1A, 0x99, 0x1C, 0xAC, 0xC6, 0xB5, 0xE1, 0x8B, 0xF5, 0x34, 0x5E
.byte 0x30, 0x5B, 0x77, 0x3B, 0x5F, 0x76, 0x79, 0x1B, 0x22, 0x09, 0x04, 0x19, 0x3C, 0x8D, 0xBB, 0xE7
.byte 0x3B, 0x55, 0xB5, 0x85, 0x70, 0x4E, 0xA1, 0x1D, 0x15, 0x57, 0xFE, 0xA1, 0x4C, 0x33, 0xFF, 0x7C
.byte 0x8F, 0x77, 0xB7, 0xEF, 0xED, 0x31, 0x0A, 0x0F, 0x3A, 0x0F, 0x29, 0x77, 0x9D, 0xE4, 0x5F, 0xD8
.byte 0x39, 0x14, 0x5E, 0xAA, 0x62, 0xFF, 0xC7, 0x77, 0x56, 0xC5, 0x18, 0xA2, 0xF9, 0x18, 0x1F, 0x88
.byte 0x8F, 0xD6, 0x78, 0x7C, 0x07, 0x82, 0x8C, 0x42, 0x92, 0xB5, 0xBA, 0x30, 0x99, 0x19, 0x09, 0xD3
.byte 0x2D, 0x67, 0x7D, 0x90, 0x66, 0x44, 0x08, 0xBD, 0x0A, 0x21, 0x60, 0x04, 0x39, 0x7F, 0x8D, 0xC8
.byte 0x56, 0x05, 0x45, 0x5D, 0x88, 0xD1, 0xA0, 0x1B, 0x86, 0x5A, 0x4B, 0x1F, 0x74, 0x54, 0xF3, 0xA1
.byte 0xBB, 0x70, 0x31, 0x22, 0xB4, 0x3A, 0xE0, 0xBF, 0x5B, 0x40, 0xC3, 0x94, 0xC0, 0x50, 0x5D, 0x16
.byte 0x55, 0xA2, 0x74, 0xDD, 0x74, 0x15, 0xF8, 0xFA, 0x6F, 0x44, 0x1A, 0xE3, 0x98, 0x0D, 0x85, 0x54
.byte 0x7D, 0xB7, 0x77, 0x32, 0xF1, 0x58, 0xF1, 0x4C, 0x98, 0xB4, 0xE1, 0x59, 0x05, 0x3F, 0x70, 0x5A
.byte 0xE1, 0xE4, 0x38, 0x55, 0xF9, 0x31, 0x50, 0x69, 0x75, 0x6A, 0x4D, 0x0E, 0x77, 0xD2, 0x63, 0xF4
.byte 0x89, 0xDA, 0x26, 0x7B, 0x32, 0x18, 0xC8, 0xCB, 0xCC, 0xA9, 0x25, 0xD1, 0xE8, 0x95, 0x2C, 0xCA
.byte 0x79, 0x65, 0x20, 0x73, 0x96, 0x70, 0xDC, 0x0C, 0xDA, 0x2A, 0x1B, 0x51, 0xFC, 0x7E, 0x46, 0x86
.byte 0x59, 0x6D, 0x01, 0x8C, 0x85, 0xC9, 0x57, 0x52, 0x73, 0x7D, 0x24, 0x5C, 0x12, 0x51, 0x26, 0x8C
.byte 0xB6, 0x46, 0xFF, 0x4D, 0xB7, 0xDC, 0x5A, 0x91, 0x06, 0x75, 0xE3, 0x03, 0xF4, 0x2A, 0x89, 0x4D
.byte 0x97, 0x8B, 0xD9, 0x1D, 0x54, 0x31, 0x70, 0xC8, 0xAE, 0x95, 0x24, 0xC0, 0xE6, 0x4B, 0x4C, 0x9D
.byte 0x91, 0x4C, 0xEB, 0x49, 0x29, 0x45, 0xDA, 0x2F, 0xBB, 0xBE, 0x33, 0xAF, 0xE8, 0xBC, 0xFC, 0x80
.byte 0x48, 0xD6, 0x9E, 0x9D, 0x07, 0x0F, 0x65, 0xB5, 0xA4, 0x89, 0x75, 0x8B, 0xD4, 0xC2, 0x28, 0x66
.byte 0x0E, 0x13, 0xAF, 0x38, 0x59, 0x8A, 0x67, 0x14, 0x49, 0x9B, 0xC4, 0x32, 0x57, 0xC0, 0xB3, 0x9F
.byte 0x97, 0x51, 0x3C, 0x9E, 0x60, 0xA2, 0x53, 0x05, 0x2C, 0xC9, 0x90, 0x01, 0x8C, 0xB8, 0x68, 0x9B
.byte 0xCC, 0x18, 0xD3, 0x26, 0xA3, 0x3A, 0x3A, 0xEC, 0xD5, 0xFF, 0x1E, 0x2D, 0xC0, 0xD1, 0xCD, 0x57
.byte 0x23, 0x0A, 0xF5, 0x84, 0xAD, 0x49, 0x89, 0xD9, 0x12, 0x19, 0xDA, 0x9E, 0xD2, 0x42, 0x39, 0x9E
.byte 0x5B, 0x0C, 0xC4, 0xFE, 0x47, 0xFF, 0xEA, 0x1D, 0xFE, 0x09, 0x4B, 0xBE, 0xDB, 0x19, 0x15, 0xFE
.byte 0x24, 0x0A, 0x83, 0xD1, 0x54, 0x0C, 0xAA, 0x66, 0x26, 0x85, 0x05, 0xF8, 0xC8, 0x3F, 0x96, 0x23
.byte 0x4C, 0x5B, 0x21, 0x93, 0x5A, 0x0C, 0xB1, 0x58, 0x15, 0xFD, 0x17, 0xF1, 0x16, 0x2C, 0xF0, 0x3A
.byte 0x37, 0x73, 0x0C, 0x8B, 0x7F, 0xB6, 0xF2, 0xA6, 0x3C, 0xF8, 0x9E, 0x05, 0x37, 0x34, 0x29, 0x83
.byte 0x8F, 0x4A, 0x17, 0xEA, 0x57, 0xC8, 0x42, 0x6D, 0xC5, 0x5A, 0x5E, 0xDC, 0x87, 0x4E, 0x17, 0xBF
.byte 0xC1, 0x23, 0x4B, 0x41, 0xDA, 0x3D, 0xE7, 0x16, 0x35, 0x85, 0x1B, 0x6D, 0xBA, 0x45, 0xF0, 0x4A
.byte 0x8F, 0x07, 0x34, 0xE7, 0xD0, 0x77, 0x54, 0x96, 0xD1, 0xB2, 0x72, 0x58, 0x01, 0x89, 0x17, 0xC2
.byte 0xAC, 0x62, 0x04, 0x86, 0xA0, 0xEB, 0x9D, 0xD5, 0x71, 0xB9, 0x42, 0x2C, 0xFE, 0x33, 0x76, 0x8E
.byte 0x3A, 0xAA, 0x75, 0x0B, 0x21, 0xCA, 0xA1, 0xF2, 0x7C, 0x13, 0x4A, 0x7D, 0x9D, 0x62, 0x40, 0x4A
.byte 0xC4, 0x44, 0xD1, 0x64, 0x30, 0x6E, 0x3A, 0xA2, 0x28, 0x7D, 0xCE, 0x26, 0xB0, 0x44, 0xB4, 0xEB
.byte 0xEE, 0x2A, 0xF6, 0x10, 0xF4, 0x97, 0x02, 0x71, 0xAB, 0x4D, 0xEF, 0x49, 0xAF, 0x30, 0x93, 0x74
.byte 0x75, 0x65, 0xD8, 0xA5, 0xD3, 0x13, 0x48, 0xFB, 0x90, 0x16, 0x22, 0x41, 0x5A, 0xD7, 0x2C, 0x49
.byte 0x01, 0x23, 0x59, 0xF6, 0xBB, 0x5C, 0x68, 0x67, 0xA9, 0x57, 0xB0, 0x59, 0x88, 0x44, 0xCD, 0xFD
.byte 0xA9, 0xA6, 0xA2, 0x7D, 0xB9, 0xEB, 0x79, 0x49, 0x01, 0x9B, 0x8B, 0x5C, 0x72, 0xB7, 0xA6, 0x74
.byte 0xDA, 0x00, 0x6A, 0x95, 0x5C, 0xD2, 0xFC, 0x06, 0x2A, 0xAD, 0x5F, 0xB2, 0xF2, 0x2D, 0xAF, 0x9B
.byte 0xD3, 0x52, 0x19, 0x8D, 0x3E, 0x92, 0xD7, 0x3F, 0x2D, 0x62, 0x9C, 0x9F, 0x19, 0x42, 0x13, 0xF4
.byte 0x42, 0x7E, 0x8A, 0x9F, 0x51, 0x87, 0xA6, 0x7B, 0x34, 0x06, 0x2E, 0x27, 0x33, 0xDE, 0xC2, 0x07
.byte 0x31, 0xDB, 0x94, 0x6F, 0x6D, 0x6B, 0xAF, 0x9B, 0xCD, 0x4B, 0x3B, 0xE7, 0x8D, 0x4E, 0xDB, 0xD0
.byte 0xCD, 0x65, 0x70, 0x1E, 0xED, 0x16, 0x9A, 0x22, 0x1C, 0xC8, 0x49, 0x50, 0xA7, 0x0B, 0x57, 0xD8
.byte 0xE7, 0xEB, 0x48, 0x55, 0x57, 0xF7, 0xF0, 0x24, 0x42, 0x2B, 0x0B, 0xD0, 0x7A, 0xE7, 0xA0, 0x47
.byte 0x4D, 0x11, 0x66, 0x3A, 0x27, 0x00, 0x5C, 0x44, 0xC8, 0xA5, 0x94, 0x6F, 0xB1, 0xEB, 0x48, 0x99
.byte 0xD7, 0x90, 0xEE, 0x2E, 0x87, 0xDF, 0x53, 0xCA, 0x0B, 0x5F, 0x9A, 0x86, 0x46, 0x3B, 0xCD, 0x93
.byte 0x4C, 0x34, 0xCE, 0x74, 0x34, 0x2A, 0xB8, 0xFC, 0xD0, 0x4C, 0x6C, 0x81, 0x38, 0xB5, 0x1A, 0x0F
.byte 0x45, 0x09, 0x3E, 0xCD, 0xE8, 0x92, 0x97, 0xF4, 0xF1, 0x32, 0x7A, 0x38, 0x6E, 0x48, 0xCC, 0xBB
.byte 0x7C, 0x9A, 0x2F, 0xB0, 0xC4, 0xE7, 0xAD, 0x94, 0x34, 0x1A, 0x16, 0x6C, 0xCF, 0x30, 0x7C, 0x15
.byte 0x39, 0xBB, 0xE2, 0x22, 0x4D, 0x7A, 0x16, 0x3F, 0xAD, 0x90, 0x77, 0x1B, 0xD8, 0x43, 0xD6, 0x54
.byte 0xDD, 0x06, 0x05, 0xA2, 0xEE, 0xB2, 0x37, 0x22, 0xCC, 0x4D, 0x8F, 0x9C, 0x7E, 0x0C, 0xB1, 0xB8
.byte 0xC8, 0x94, 0xDA, 0x15, 0x0E, 0xF1, 0x55, 0xBC, 0x81, 0xCC, 0xD7, 0x5A, 0x10, 0xAE, 0xAF, 0xEE
.byte 0xB4, 0xB4, 0x91, 0xA3, 0x67, 0xC9, 0xC5, 0x34, 0x17, 0x55, 0xD0, 0x95, 0x62, 0x81, 0x4E, 0x2A
.byte 0x15, 0x28, 0x40, 0x24, 0x19, 0x95, 0xE0, 0x9B, 0x62, 0xB8, 0xF6, 0x73, 0x66, 0xA5, 0x61, 0x1B
.byte 0x5A, 0xF3, 0xBE, 0xC2, 0xBC, 0x84, 0xF7, 0xD3, 0xDA, 0xC7, 0x68, 0x3C, 0x49, 0xB6, 0x67, 0x5E
.byte 0xDF, 0xA7, 0x83, 0xF9, 0x3D, 0x64, 0x95, 0x9F, 0x1C, 0x8B, 0x12, 0x83, 0x31, 0x74, 0x9F, 0x8C
.byte 0x67, 0x5E, 0x4F, 0x23, 0xE3, 0x46, 0xF7, 0xBD, 0x0D, 0x5F, 0xFA, 0x57, 0x16, 0x62, 0xB6, 0xF6
.byte 0x09, 0x39, 0xF0, 0x47, 0x9D, 0x85, 0xE7, 0xBA, 0x11, 0xF9, 0x3D, 0x43, 0x6E, 0xDC, 0xCF, 0xD6
.byte 0x3A, 0x1F, 0xFA, 0x1D, 0x65, 0xF1, 0xDB, 0x73, 0x51, 0xD6, 0xCA, 0x68, 0x38, 0x80, 0x5E, 0x41
.byte 0xBA, 0x4F, 0x89, 0x57, 0xD4, 0x70, 0x11, 0xE5, 0x69, 0x4F, 0x28, 0xD8, 0x2C, 0xF8, 0xAF, 0x66
.byte 0x18, 0xA9, 0x84, 0x7D, 0x9B, 0x60, 0xF1, 0xEC, 0x36, 0xBB, 0x55, 0x6E, 0x3C, 0xB4, 0xB0, 0xF6
.byte 0x03, 0x39, 0x4E, 0xD7, 0xA9, 0x60, 0xBD, 0x13, 0xAF, 0xE6, 0xEB, 0xDB, 0xDF, 0x9B, 0x42, 0xF7
.byte 0x44, 0xC7, 0x75, 0xDF, 0x27, 0x66, 0xCC, 0x5D, 0x22, 0x22, 0xCC, 0x5E, 0xD6, 0x7C, 0x55, 0xD9
.byte 0xB5, 0xA4, 0xB1, 0x5F, 0x04, 0x6F, 0x72, 0xB4, 0x56, 0x5E, 0x90, 0x35, 0xF9, 0xD3, 0x2D, 0x3E
.byte 0x9B, 0xA3, 0x1D, 0xC2, 0x09, 0xEA, 0x20, 0x2C, 0x0C, 0xED, 0x8B, 0xE3, 0x69, 0xE0, 0xBD, 0x1F
.byte 0x85, 0x6E, 0x7E, 0x89, 0xDE, 0xF0, 0x3E, 0x34, 0x4E, 0xCF, 0x6A, 0x48, 0xA2, 0x97, 0x86, 0x3D
.byte 0x3A, 0xA4, 0x00, 0x44, 0x8F, 0x21, 0x71, 0x9B, 0x0E, 0xFC, 0x7F, 0x77, 0xDD, 0x3C, 0x97, 0x62
.byte 0xAB, 0x15, 0xEC, 0x89, 0x06, 0x2A, 0xBD, 0x55, 0xF9, 0x27, 0x9D, 0x9C, 0xBF, 0x23, 0xDA, 0xFA
.byte 0xC7, 0xDA, 0x3F, 0x56, 0xFB, 0xB0, 0xF2, 0x09, 0xAC, 0x72, 0x81, 0x89, 0xAE, 0x18, 0xEC, 0x59
.byte 0x2D, 0xD8, 0xE3, 0x33, 0x03, 0xA0, 0x89, 0xFD, 0xC8, 0x26, 0x99, 0x88, 0x4A, 0x74, 0x82, 0x12
.byte 0x4E, 0xC2, 0x68, 0x4A, 0x72, 0x5B, 0x53, 0x1E, 0xCE, 0xD4, 0xA8, 0x7C, 0xED, 0x94, 0xD6, 0x1A
.byte 0x6D, 0xB9, 0x4E, 0x71, 0x5A, 0xD7, 0x6E, 0x22, 0xFE, 0x08, 0xAB, 0x48, 0x7C, 0x2E, 0x5A, 0xCA
.byte 0xF0, 0xC3, 0x14, 0x62, 0x1F, 0x68, 0x81, 0xED, 0x3D, 0x29, 0x69, 0x2A, 0xBE, 0x40, 0x45, 0x2C
.byte 0xF9, 0x94, 0x9D, 0x53, 0x6C, 0x0B, 0x76, 0x6A, 0x13, 0x21, 0xB3, 0x90, 0x50, 0x0D, 0x5A, 0x40
.byte 0xD1, 0x6F, 0xA2, 0xF0, 0xD8, 0x23, 0xDD, 0x15, 0x4D, 0x47, 0x40, 0x0C, 0x87, 0x85, 0x38, 0x81
.byte 0x1A, 0xD5, 0xD4, 0x86, 0xE1, 0x4B, 0xF1, 0xF4, 0x6D, 0xA4, 0x85, 0xBD, 0xB2, 0xE0, 0xFD, 0x83
.byte 0x4F, 0xA0, 0x73, 0x28, 0xC3, 0x51, 0x3D, 0x11, 0x98, 0x7E, 0x1D, 0x20, 0x04, 0x55, 0xA1, 0x1E
.byte 0x2B, 0x76, 0xA5, 0x0C, 0xC1, 0x96, 0x01, 0x2E, 0x3B, 0x86, 0xEC, 0xED, 0x66, 0xE9, 0x70, 0xB6
.byte 0x8A, 0xE4, 0xDE, 0x4E, 0x35, 0x1C, 0x5F, 0xCE, 0x9A, 0x7C, 0xEE, 0x9E, 0xD2, 0x8F, 0xBC, 0xFD
.byte 0x05, 0x62, 0x09, 0xC7, 0xF8, 0x0A, 0xF6, 0x34, 0x90, 0xE2, 0x21, 0xF7, 0xCC, 0x92, 0xAD, 0x56
.byte 0x77, 0x8B, 0xA4, 0xAC, 0xA7, 0x03, 0x7A, 0x42, 0x80, 0x69, 0xE0, 0x52, 0xF8, 0x9D, 0x50, 0xFE
.byte 0xFF, 0x59, 0xC5, 0xF8, 0x64, 0xBB, 0x2C, 0xF5, 0x9E, 0x4E, 0xEC, 0x6A, 0xE0, 0x99, 0xC1, 0x57
.byte 0x25, 0x65, 0x04, 0xCD, 0x69, 0x7F, 0x0F, 0xEA, 0xE8, 0xEF, 0x3D, 0xE1, 0x8D, 0x8D, 0xE0, 0x8C
.byte 0xE6, 0xA5, 0x85, 0x4B, 0x61, 0xB1, 0x40, 0xFF, 0xFF, 0x2C, 0x6A, 0xE0, 0xC6, 0x2B, 0x38, 0xEB
.byte 0x91, 0x3C, 0xB8, 0xFA, 0xBC, 0xC7, 0xE5, 0xA4, 0xB7, 0x22, 0x86, 0x44, 0xAF, 0x66, 0xD1, 0x96
.byte 0x0C, 0x56, 0xE1, 0x6E, 0x08, 0x21, 0x6D, 0x08, 0x4E, 0xD8, 0xE8, 0x14, 0x03, 0x20, 0x00, 0x94
.byte 0x5D, 0xB8, 0x8F, 0x19, 0x80, 0x75, 0xBE, 0x38, 0x97, 0x45, 0x7D, 0x46, 0xAC, 0x4F, 0xDD, 0xB8
.byte 0xA5, 0xBE, 0x26, 0xAE, 0xE0, 0x94, 0xB6, 0x2F, 0x6C, 0x9F, 0x43, 0x70, 0xC0, 0x44, 0x05, 0x1D
.byte 0xFD, 0x95, 0x37, 0x7E, 0x0A, 0xF6, 0xB6, 0xA1, 0x3B, 0x33, 0xE8, 0xE7, 0x82, 0xC5, 0xA0, 0x28
.byte 0x83, 0xC7, 0xD7, 0x64, 0x5C, 0x8D, 0x93, 0xC9, 0x2C, 0xD7, 0x3A, 0xED, 0x1B, 0x3F, 0x0A, 0x19
.byte 0xD4, 0x42, 0x97, 0xDF, 0x38, 0x4D, 0x80, 0x74, 0x81, 0x69, 0x5C, 0x04, 0x2E, 0xFD, 0x2D, 0xB2
.byte 0xC4, 0x04, 0x16, 0x21, 0x92, 0xAA, 0xEB, 0xBF, 0x81, 0x25, 0xAC, 0x9D, 0x64, 0xB6, 0xB6, 0x39
.byte 0xF9, 0x4E, 0x19, 0x31, 0x9B, 0x99, 0xA6, 0x1D, 0x03, 0x02, 0x21, 0x31, 0x00, 0x4E, 0xE4, 0xC5
.byte 0x52, 0xFA, 0xE6, 0xE4, 0xA5, 0xD1, 0xA3, 0x26, 0xF6, 0x4F, 0xC4, 0x5B, 0x06, 0x7B, 0x95, 0x00
.byte 0xC9, 0xAE, 0x31, 0x65, 0x48, 0xD8, 0x82, 0x4B, 0xDB, 0xA3, 0x7D, 0xDB, 0xF2, 0x61, 0xA0, 0x45
.byte 0x5C, 0x86, 0x2A, 0x01, 0x58, 0xCD, 0x28, 0x4F, 0x1D, 0xEC, 0xAA, 0x24, 0x68, 0x40, 0x24, 0x31
.byte 0xEE, 0x56, 0x96, 0x36, 0x2E, 0x19, 0x82, 0x0A, 0xBD, 0xFF, 0xE5, 0xAF, 0x60, 0x85, 0xF4, 0xBC
.byte 0x0C, 0x1E, 0xBD, 0x64, 0xEC, 0xE6, 0xB4, 0x0A, 0xD2, 0x5E, 0x2F, 0x3B, 0x9E, 0x53, 0x6C, 0x8D
.byte 0xAA, 0x03, 0xC4, 0xD9, 0x1C, 0x46, 0xE3, 0xDA, 0x45, 0xC9, 0x89, 0xA6, 0x4E, 0x7E, 0x62, 0x5B
.byte 0x9D, 0x20, 0xC0, 0x8A, 0x06, 0x74, 0x94, 0xD9, 0xD3, 0xC4, 0x14, 0x72, 0x18, 0x81, 0xFF, 0xC2
.byte 0x85, 0xC3, 0x9C, 0xA2, 0x0A, 0x80, 0x7C, 0x4F, 0x49, 0x06, 0xF6, 0x98, 0x84, 0x58, 0xF3, 0x22
.byte 0x79, 0xB4, 0xAC, 0x80, 0x28, 0x41, 0x5A, 0xFC, 0x05, 0x6F, 0x6E, 0x1D, 0xF0, 0x6E, 0xE0, 0x76
.byte 0x32, 0x7C, 0x18, 0x3C, 0xFC, 0x95, 0x8C, 0x46, 0x9B, 0x82, 0xDE, 0x20, 0xDB, 0xD2, 0x42, 0x55
.byte 0x86, 0xEE, 0xD6, 0xAE, 0x2F, 0x30, 0xAB, 0x34, 0x9F, 0x19, 0x52, 0x90, 0x88, 0x32, 0x07, 0xBA
.byte 0xAF, 0x1F, 0xF7, 0xAC, 0xB5, 0x84, 0xF2, 0x50, 0x06, 0xD0, 0x70, 0xE2, 0xA2, 0xB2, 0x38, 0x28
.byte 0xA1, 0x0E, 0xD7, 0xD0, 0x3F, 0x82, 0x05, 0xDE, 0x9C, 0x58, 0x6F, 0x24, 0x8B, 0x76, 0xDE, 0x3A
.byte 0x96, 0xD5, 0xE6, 0x4B, 0x59, 0xD8, 0x9B, 0x60, 0xA8, 0x0C, 0x43, 0x4B, 0xBE, 0x7B, 0x73, 0x60
.byte 0x8A, 0x4B, 0x31, 0xC9, 0xCD, 0x36, 0xA8, 0x69, 0x8F, 0x17, 0x8D, 0x1A, 0x8E, 0x6C, 0x54, 0x24
.byte 0x42, 0x3A, 0x6F, 0x9C, 0x13, 0x0B, 0xFD, 0xBC, 0x17, 0x40, 0x07, 0xD6, 0xBC, 0x7B, 0x36, 0x46
.byte 0xC7, 0x67, 0x10, 0x94, 0x9E, 0xB8, 0xFE, 0x2D, 0xCF, 0x8C, 0x47, 0x5D, 0xF8, 0x9B, 0x81, 0x3B
.byte 0xD6, 0xF1, 0xD7, 0xEA, 0xFC, 0xD4, 0xA6, 0x14, 0x15, 0xAE, 0xEA, 0xD2, 0x2A, 0x21, 0x18, 0xF1
.byte 0x89, 0x28, 0x86, 0x27, 0xE0, 0x84, 0x55, 0xB0, 0x11, 0x9C, 0x0D, 0x0A, 0x38, 0x8F, 0x45, 0x0F
.byte 0x81, 0x1D, 0xF9, 0x7D, 0xF2, 0xA0, 0x91, 0x07, 0x4F, 0x7C, 0xD9, 0x79, 0x9E, 0xF2, 0x6A, 0x27
.byte 0x1B, 0xF0, 0x4F, 0xFB, 0x75, 0xA4, 0xAC, 0x86, 0x41, 0xB9, 0x91, 0x7A, 0x49, 0xD6, 0x89, 0xCA
.byte 0xF3, 0x83, 0x48, 0xE5, 0x24, 0xDA, 0xED, 0x73, 0x56, 0xC7, 0xEC, 0xF5, 0xB9, 0x57, 0x1C, 0xD4
.byte 0x48, 0x6B, 0xD0, 0xBE, 0x10, 0x7C, 0x45, 0x51, 0x36, 0xD6, 0xCB, 0x80, 0xAD, 0x55, 0x4A, 0xA0
.byte 0xD9, 0x93, 0x86, 0xFD, 0x6D, 0x74, 0x71, 0xC4, 0x3B, 0x5D, 0xB9, 0xF4, 0xB5, 0xD5, 0xC9, 0xFE
.byte 0x41, 0x99, 0xBC, 0x51, 0x16, 0x01, 0xA3, 0x4D, 0xD8, 0x6E, 0xCD, 0x85, 0xC3, 0x17, 0x26, 0x9D
.byte 0xAB, 0xAC, 0x9A, 0x18, 0x21, 0x0B, 0xDC, 0x5C, 0x69, 0x96, 0x51, 0x1E, 0x6C, 0x1B, 0x1C, 0xAD
.byte 0xB5, 0xD9, 0xFF, 0xCB, 0xDB, 0xA2, 0x18, 0xB3, 0x11, 0xE5, 0x38, 0xD4, 0xFD, 0x5E, 0x71, 0xA8
.byte 0x0B, 0x0C, 0xC1, 0x2C, 0x18, 0x9E, 0x89, 0x81, 0x34, 0xDA, 0xA0, 0xA0, 0xF5, 0xBD, 0x4E, 0xAB
.byte 0x96, 0x4D, 0x76, 0x71, 0xF0, 0x8F, 0x24, 0x01, 0x74, 0x5D, 0xD5, 0x72, 0xBB, 0x47, 0x1B, 0xC7
.byte 0x54, 0xDC, 0xF3, 0x6C, 0x7A, 0x7C, 0xED, 0xAE, 0x57, 0x8E, 0x4F, 0x4D, 0x4B, 0x9D, 0xF8, 0xE2
.byte 0xEA, 0x6F, 0x53, 0xDA, 0xFE, 0x78, 0xDB, 0x73, 0xD6, 0xB1, 0xE5, 0x92, 0xF9, 0x00, 0x59, 0x4E
.byte 0xDD, 0x4C, 0xBA, 0x57, 0xC9, 0xA8, 0x06, 0x20, 0x36, 0x55, 0x6E, 0x81, 0xF2, 0x67, 0x64, 0xDD
.byte 0xD6, 0xB8, 0xB8, 0xD4, 0x30, 0x94, 0x47, 0x07, 0x46, 0x2D, 0x99, 0x40, 0x2D, 0xF2, 0x8E, 0x0B
.byte 0x3E, 0x49, 0x62, 0x08, 0xF1, 0x69, 0x29, 0x27, 0xBE, 0x97, 0xA9, 0xB1, 0xFE, 0x0D, 0x8F, 0xD5
.byte 0xC5, 0x48, 0xA9, 0xF6, 0xDD, 0xF1, 0xFE, 0x24, 0x1E, 0x97, 0x64, 0x4C, 0x89, 0xF3, 0x57, 0xC8
.byte 0x3C, 0xBA, 0xD1, 0x2D, 0x23, 0xFA, 0x55, 0xE2, 0x92, 0xFF, 0x94, 0x91, 0x0D, 0x24, 0x66, 0xD3
.byte 0x6C, 0x10, 0xCA, 0x4A, 0x01, 0xC8, 0x6E, 0x1F, 0x60, 0xD2, 0x6B, 0xE9, 0xC5, 0xC2, 0xB2, 0x01
.byte 0x7C, 0x83, 0x2F, 0xA0, 0x7D, 0x85, 0x82, 0x10, 0x85, 0x16, 0xA1, 0x92, 0x3A, 0x08, 0x66, 0xA7
.byte 0x18, 0x30, 0xF1, 0x19, 0xF9, 0x5F, 0x38, 0x59, 0x32, 0xA3, 0x43, 0xF7, 0x66, 0xF5, 0xF9, 0xE2
.byte 0x78, 0x29, 0x83, 0xF6, 0xAF, 0x05, 0x06, 0x34, 0x1C, 0xA8, 0xC6, 0x57, 0xB0, 0x2D, 0xFF, 0xC8
.byte 0x5D, 0xF0, 0xE1, 0x57, 0x50, 0x19, 0xB0, 0x82, 0xBD, 0xF3, 0x7A, 0x23, 0xE9, 0x74, 0x06, 0x62
.byte 0x9D, 0x89, 0x59, 0x4D, 0x8F, 0x60, 0x81, 0xAC, 0x08, 0x48, 0x03, 0xB9, 0x75, 0x02, 0x81, 0xD2
.byte 0xF3, 0x63, 0x2A, 0x44, 0x7D, 0xDB, 0xC6, 0x3B, 0xCF, 0x41, 0x5E, 0xB8, 0xB5, 0x65, 0x1B, 0x53
.byte 0xEF, 0x74, 0xA0, 0x7F, 0xD4, 0x22, 0x2B, 0xDD, 0x6A, 0x2F, 0x96, 0xDF, 0x32, 0x18, 0xB2, 0x25
.byte 0x7B, 0xDC, 0x6A, 0xF9, 0xB7, 0x31, 0x34, 0x86, 0x72, 0x93, 0x3F, 0x28, 0xF9, 0x5A, 0x7C, 0xE8
.byte 0xCE, 0x1D, 0x67, 0xA3, 0x3F, 0x93, 0x80, 0xA9, 0xC2, 0x17, 0x88, 0xF4, 0x2F, 0x3A, 0x1A, 0xAB
.byte 0x17, 0x84, 0xA4, 0xCF, 0xB5, 0xD9, 0x56, 0x28, 0x6C, 0x95, 0x50, 0x65, 0xF0, 0xCD, 0x4E, 0xBF
.byte 0xEA, 0xB6, 0x62, 0x29, 0x49, 0xE3, 0xD3, 0x0B, 0xFA, 0x5C, 0xFF, 0x2A, 0x97, 0x1A, 0xD5, 0xAE
.byte 0x9E, 0x7A, 0x7D, 0x53, 0x54, 0xD4, 0x7B, 0xC0, 0x69, 0xCC, 0x26, 0x59, 0x99, 0x74, 0x18, 0x83
.byte 0x2A, 0x7B, 0xAD, 0x74, 0x5E, 0x81, 0x7F, 0x59, 0xDD, 0x7F, 0x83, 0x74, 0x99, 0x59, 0x23, 0x38
.byte 0xD4, 0xA1, 0x8B, 0x28, 0x75, 0x07, 0xE9, 0xDF, 0xD4, 0x10, 0x38, 0x6D, 0x84, 0x51, 0xF1, 0xAF
.byte 0xCC, 0x9E, 0x23, 0x2B, 0x20, 0xA3, 0x84, 0xFD, 0x23, 0x08, 0x72, 0xBD, 0x61, 0x95, 0xF5, 0x36
.byte 0x37, 0x81, 0x5F, 0xAC, 0x89, 0x48, 0x8B, 0x5D, 0x58, 0xC4, 0xCA, 0xDD, 0x15, 0xBB, 0x8D, 0xE2
.byte 0x5A, 0xB1, 0x0D, 0x7A, 0x54, 0x92, 0x78, 0x78, 0x9A, 0xEA, 0x35, 0xFC, 0x80, 0x2B, 0x32, 0xB7
.byte 0xAC, 0x91, 0x64, 0x35, 0xDA, 0xF0, 0x93, 0x32, 0xB4, 0x5D, 0x10, 0xCA, 0x19, 0x9D, 0xAD, 0x74
.byte 0x4E, 0xBB, 0xEE, 0xA3, 0x4D, 0x67, 0x1C, 0xE8, 0x52, 0x51, 0xE4, 0xD2, 0x7D, 0x16, 0x8A, 0x2A
.byte 0xA8, 0xEF, 0x60, 0x82, 0xDF, 0xF3, 0xB5, 0x94, 0x50, 0xC5, 0x5F, 0x6A, 0x63, 0x0C, 0xDE, 0xB1
.byte 0xC7, 0xCC, 0x55, 0x15, 0x34, 0x71, 0xFD, 0x86, 0xC3, 0xE1, 0x59, 0x40, 0xF8, 0xE4, 0x6B, 0xA1
.byte 0xD3, 0xCB, 0x24, 0xB3, 0xBE, 0xD9, 0x48, 0x0F, 0x9F, 0xA7, 0x79, 0x02, 0xB4, 0x57, 0xB4, 0x7C
.byte 0x24, 0x09, 0x91, 0x58, 0x7B, 0x8F, 0xDF, 0x3F, 0x71, 0x38, 0x80, 0x69, 0x1C, 0xEB, 0x0B, 0xF0
.byte 0xB6, 0x2F, 0xA3, 0x74, 0x09, 0xEB, 0x83, 0xA8, 0x92, 0xFD, 0xAB, 0x47, 0x54, 0x5F, 0xC3, 0x78
.byte 0x69, 0x54, 0xD0, 0xE4, 0xE4, 0xAF, 0x23, 0x55, 0xE8, 0xA3, 0xBF, 0x04, 0x8E, 0xCA, 0xF5, 0x45
.byte 0xFA, 0x98, 0xB9, 0x03, 0x84, 0x3D, 0xAB, 0x17, 0x3A, 0x56, 0x5E, 0x8F, 0xB6, 0x21, 0x07, 0x1F
.byte 0x76, 0xD8, 0x04, 0x5A, 0x88, 0x27, 0xAF, 0x70, 0xCB, 0x6F, 0x75, 0x5A, 0x39, 0x6A, 0x9F, 0x33
.byte 0x03, 0x59, 0x37, 0x87, 0x96, 0xE3, 0x9E, 0xD1, 0x3A, 0xFC, 0x60, 0xF0, 0x1E, 0x68, 0x10, 0x94
.byte 0x40, 0x14, 0xEF, 0xC9, 0x3B, 0x9F, 0x39, 0x07, 0x0E, 0xAE, 0x61, 0x48, 0x19, 0x00, 0x7C, 0x1C
.byte 0x59, 0xB3, 0xA3, 0xF0, 0x97, 0x42, 0xC2, 0xD1, 0x3E, 0x23, 0xC1, 0x5D, 0x8B, 0xD2, 0xF2, 0xCC
.byte 0xE6, 0xE1, 0x95, 0x22, 0x81, 0xCF, 0x29, 0x90, 0x7E, 0x8A, 0xD8, 0x97, 0x8A, 0x55, 0xB4, 0xE4
.byte 0x09, 0x57, 0xD4, 0xA0, 0x9A, 0x97, 0x71, 0xD8, 0xBA, 0x33, 0x36, 0x46, 0x05, 0x28, 0x12, 0xEB
.byte 0x09, 0xA8, 0x0D, 0x8B, 0x77, 0x36, 0x1B, 0xF5, 0xC1, 0xF3, 0x8C, 0x4B, 0x49, 0x41, 0x30, 0x52
.byte 0x99, 0x05, 0xF2, 0x33, 0x9C, 0x64, 0x0C, 0x56, 0x98, 0x42, 0x9C, 0x9D, 0x6A, 0xAF, 0x89, 0x74
.byte 0x57, 0x97, 0xFF, 0xCF, 0xCE, 0x1A, 0xC4, 0x8F, 0x0E, 0x51, 0xDB, 0x57, 0x92, 0x0B, 0xA9, 0x2B
.byte 0x10, 0x9C, 0x5F, 0xAD, 0x01, 0x6B, 0x03, 0x99, 0xAD, 0xA0, 0x36, 0x17, 0x50, 0xC0, 0x8C, 0xA8
.byte 0x57, 0x8B, 0x77, 0x26, 0xA5, 0x3C, 0xB5, 0xB3, 0x8D, 0x91, 0x0B, 0x20, 0x9C, 0xB5, 0x4C, 0xAD
.byte 0x51, 0xAB, 0x5B, 0x52, 0x17, 0x5E, 0xEC, 0xC4, 0xFF, 0x23, 0xDC, 0x50, 0xE3, 0x68, 0xF8, 0x3B
.byte 0xF3, 0x70, 0x61, 0x99, 0xAC, 0x16, 0x4C, 0x39, 0xA8, 0x58, 0x5A, 0x45, 0x0D, 0xA6, 0xF2, 0x5E
.byte 0x52, 0x4D, 0xB1, 0x69, 0xAC, 0x9D, 0x2E, 0xAC, 0xC0, 0x0A, 0xFC, 0xA4, 0x73, 0xF5, 0xDF, 0x67
.byte 0x65, 0x41, 0x00, 0x11, 0x58, 0x4D, 0x4B, 0x00, 0xA5, 0xA5, 0x45, 0xB2, 0x4C, 0x38, 0x11, 0x9E
.byte 0x86, 0xC3, 0x07, 0x33, 0x61, 0x35, 0xDF, 0x22, 0x40, 0xDC, 0xC6, 0xB4, 0xD2, 0xA6, 0x1B, 0x37
.byte 0xE7, 0x1C, 0x49, 0x40, 0x69, 0x94, 0x40, 0x0F, 0x39, 0x85, 0xC2, 0x85, 0xBD, 0xD4, 0x24, 0x44
.byte 0x97, 0x2B, 0x77, 0xF8, 0x61, 0x56, 0x1B, 0xA2, 0x33, 0xE2, 0x56, 0x05, 0x89, 0x71, 0x3D, 0x71
.byte 0x8D, 0x86, 0xB1, 0xF7, 0x1A, 0xF1, 0x06, 0x54, 0x77, 0xC9, 0xDA, 0x34, 0x9D, 0xFE, 0x79, 0x34
.byte 0x2A, 0xF0, 0x2D, 0x8C, 0x47, 0x49, 0x2E, 0x7A, 0x2B, 0x84, 0x80, 0xB4, 0xF5, 0xBD, 0x25, 0x83
.byte 0x43, 0xD6, 0x7A, 0x5E, 0xC8, 0x81, 0xB2, 0x3F, 0x4A, 0x8C, 0x74, 0xE8, 0x8B, 0xED, 0x1C, 0xB5
.byte 0xDD, 0x4A, 0x41, 0x24, 0x93, 0x70, 0x9F, 0xBF, 0xF4, 0x20, 0x73, 0xEA, 0xDD, 0x99, 0x6D, 0x21
.byte 0x6F, 0xE8, 0x7F, 0x37, 0x69, 0x32, 0x77, 0xB4, 0xBE, 0xEB, 0x9D, 0x4A, 0xD8, 0xB9, 0x00, 0xB6
.byte 0x04, 0x42, 0xDB, 0x98, 0xB2, 0x7B, 0x57, 0xA6, 0x9B, 0xCA, 0x90, 0x78, 0x63, 0xFE, 0x9A, 0xD3
.byte 0xE6, 0x19, 0x0B, 0x50, 0x4C, 0x83, 0x05, 0x0B, 0x6E, 0xA2, 0x55, 0x47, 0x5C, 0x55, 0xFE, 0x60
.byte 0x97, 0xD9, 0xF8, 0x4A, 0x54, 0x50, 0xF0, 0xEF, 0x1B, 0x81, 0x68, 0x7E, 0x7F, 0x02, 0x52, 0x65
.byte 0x1C, 0x5E, 0xB5, 0x68, 0xE1, 0xBA, 0x73, 0x50, 0x5C, 0xC9, 0x97, 0xB8, 0x1E, 0x96, 0x19, 0xB6
.byte 0x6F, 0x12, 0x00, 0xC4, 0x62, 0xF1, 0xB4, 0x7D, 0x72, 0x1D, 0xFC, 0xF2, 0x20, 0x4F, 0x57, 0x3C
.byte 0xAD, 0x0D, 0xA5, 0x8F, 0xC8, 0x19, 0xDF, 0x24, 0xE3, 0x77, 0xDD, 0x02, 0x0D, 0xF7, 0xB8, 0x7D
.byte 0x09, 0xB9, 0x41, 0x6C, 0xAB, 0xF6, 0xEA, 0x1D, 0x13, 0xE6, 0x10, 0x33, 0x36, 0x67, 0x70, 0xE4
.byte 0x75, 0x16, 0x73, 0x3D, 0x30, 0x53, 0x62, 0x13, 0xCA, 0x40, 0x15, 0xD8, 0x37, 0xCE, 0x55, 0x41
.byte 0x88, 0x97, 0xAD, 0x33, 0x8D, 0x98, 0x51, 0xA1, 0x7F, 0x61, 0xD5, 0xB5, 0xC9, 0x45, 0x99, 0x3E
.byte 0x5C, 0x0C, 0x7C, 0x8C, 0x60, 0xDE, 0xA0, 0x2A, 0x1E, 0xB6, 0x02, 0x55, 0x84, 0x57, 0x97, 0x0D
.byte 0xEF, 0x44, 0x40, 0x7C, 0xDD, 0x91, 0x1E, 0x5C, 0xF3, 0xF3, 0x11, 0xBC, 0x39, 0xAA, 0xFB, 0x95
.byte 0xB7, 0x77, 0x22, 0x17, 0x55, 0xC2, 0x42, 0x74, 0x79, 0x44, 0xC9, 0xFE, 0x9C, 0x61, 0x0B, 0x8B
.byte 0xA6, 0x4B, 0x08, 0x83, 0xDD, 0x27, 0xDF, 0xD1, 0x1A, 0xF0, 0x8E, 0x53, 0x9B, 0x89, 0xE9, 0x53
.byte 0x00, 0x0B, 0x6B, 0x56, 0xCE, 0xAD, 0xCA, 0x47, 0xF2, 0x94, 0x45, 0x8E, 0xF5, 0x50, 0x1A, 0x9B
.byte 0x9C, 0x23, 0x1E, 0x7A, 0x4A, 0xFE, 0x4B, 0x65, 0xEE, 0xD9, 0xB8, 0x8A, 0x63, 0xA2, 0xDD, 0x63
.byte 0xAD, 0x48, 0xBA, 0x7B, 0xF5, 0x85, 0xC3, 0xE7, 0x19, 0x08, 0x76, 0x0F, 0x59, 0x91, 0xAB, 0xF5
.byte 0xB4, 0xC9, 0x70, 0xFF, 0xC8, 0xBC, 0x64, 0xB6, 0x95, 0x1D, 0x41, 0xF9, 0xBF, 0x1E, 0x5C, 0x6D
.byte 0x67, 0x17, 0xE9, 0x5D, 0x9C, 0xAC, 0x45, 0xB6, 0xB4, 0xBB, 0xC5, 0x0E, 0x4D, 0x70, 0x04, 0x02
.byte 0x3A, 0x74, 0x01, 0x02, 0x30, 0x66, 0xB9, 0xC6, 0x83, 0xFA, 0xBF, 0x43, 0x19, 0x1C, 0xB0, 0x81
.byte 0x34, 0x9A, 0xDE, 0xD0, 0x46, 0x23, 0x86, 0xFB, 0xDF, 0x4C, 0x09, 0x2D, 0xBC, 0x0D, 0x2F, 0xF7
.byte 0x82, 0x30, 0xFA, 0xB2, 0x96, 0xB3, 0x79, 0x1A, 0xAE, 0x39, 0x5D, 0xC8, 0x55, 0x0E, 0x49, 0x89
.byte 0xA8, 0x28, 0x5A, 0xEF, 0x4C, 0xE1, 0xEA, 0x2B, 0x2D, 0xF4, 0x58, 0xEA, 0x02, 0x88, 0xE1, 0x84
.byte 0xB8, 0xDB, 0x37, 0x4F, 0x8F, 0xB0, 0x69, 0x3E, 0xE9, 0xC7, 0x07, 0x3F, 0xD5, 0x51, 0xC9, 0x7E
.byte 0x79, 0x23, 0x6D, 0xC5, 0x04, 0x58, 0xF1, 0x31, 0x4D, 0x4A, 0x1C, 0x4F, 0xD2, 0xFE, 0xD3, 0x8B
.byte 0xD9, 0x0B, 0xDA, 0x69, 0xBC, 0x43, 0xA8, 0xA5, 0x0A, 0xAF, 0xE5, 0xE0, 0x00, 0xAE, 0x5E, 0x7A
.byte 0xD2, 0xCC, 0x40, 0xD6, 0x25, 0x31, 0x08, 0x72, 0x7C, 0x25, 0xC1, 0x4E, 0x23, 0x95, 0xD9, 0xFD
.byte 0xA0, 0xB4, 0x66, 0x5C, 0xF7, 0x0F, 0x02, 0x02, 0xBF, 0xE7, 0xE3, 0xC0, 0x96, 0x41, 0x3A, 0x69
.byte 0x0E, 0x7A, 0x3F, 0x33, 0xAC, 0x48, 0xA5, 0x28, 0x6D, 0x66, 0x77, 0x91, 0xFC, 0x51, 0x8E, 0x9C
.byte 0x05, 0xF5, 0xF8, 0xFD, 0x04, 0xFB, 0x00, 0xC4, 0xE3, 0xE3, 0x84, 0x79, 0x25, 0xBF, 0xE2, 0x33
.byte 0x39, 0x22, 0x66, 0xE6, 0x6B, 0x0C, 0x0E, 0xD9, 0x73, 0x86, 0x6A, 0x6F, 0xD7, 0xF8, 0x0B, 0xDD
.byte 0xEE, 0x04, 0xDA, 0xF2, 0xFF, 0xDB, 0xB6, 0xE2, 0xBE, 0x3B, 0x5C, 0xE3, 0xFA, 0x3F, 0x17, 0x33
.byte 0x62, 0x7E, 0x1A, 0xCD, 0x8A, 0x29, 0xA7, 0xFE, 0xAF, 0x11, 0x6D, 0x87, 0x0A, 0x79, 0x64, 0xF8
.byte 0x7D, 0x3F, 0xEB, 0x7D, 0x1A, 0xA2, 0x60, 0xD9, 0xDD, 0xBC, 0xBC, 0xD7, 0xFC, 0xD4, 0x0B, 0x5E
.byte 0x52, 0x25, 0x2C, 0xDC, 0x4F, 0xD4, 0xDA, 0xFE, 0xE6, 0x48, 0x85, 0xF1, 0xC1, 0xEA, 0xEA, 0x3F
.byte 0x2A, 0xD5, 0xBC, 0x44, 0x78, 0x1C, 0x1E, 0x55, 0xD9, 0xDB, 0x2D, 0xD6, 0xAF, 0x38, 0x35, 0x01
.byte 0x5E, 0x62, 0xDE, 0xAD, 0x36, 0xB9, 0xAC, 0x1D, 0x01, 0x32, 0x0E, 0xC2, 0x1C, 0xF8, 0x01, 0x46
.byte 0xCD, 0xBE, 0x8B, 0x45, 0xDB, 0xA9, 0x9B, 0xB4, 0x84, 0xC8, 0x8B, 0x34, 0x01, 0xC0, 0x35, 0x5F
.byte 0x22, 0x13, 0x0D, 0x59, 0xCC, 0xB9, 0x76, 0xCD, 0xEC, 0x84, 0x90, 0x09, 0x7C, 0x92, 0x50, 0x4A
.byte 0x50, 0xDB, 0x90, 0x2B, 0x85, 0x2C, 0xE0, 0x0A, 0xF4, 0x6B, 0x3E, 0xF6, 0x2C, 0x74, 0x56, 0x4E
.byte 0x87, 0x63, 0xA8, 0x54, 0x1D, 0x1E, 0x21, 0x0A, 0xA2, 0xB2, 0x13, 0x1F, 0x44, 0x63, 0x6A, 0x95
.byte 0x3F, 0xFB, 0xC1, 0xC4, 0x27, 0xA1, 0xCF, 0x1C, 0x0D, 0x0E, 0x12, 0x39, 0x82, 0x68, 0x88, 0x0A
.byte 0xCC, 0x30, 0x5E, 0xEA, 0x4F, 0x80, 0xF4, 0xF2, 0x32, 0x07, 0x11, 0x77, 0x6A, 0x7C, 0x0D, 0xA9
.byte 0x77, 0xCE, 0x6E, 0x9E, 0x70, 0x3E, 0xBB, 0x7E, 0x4C, 0xCD, 0xB8, 0xCF, 0x36, 0x40, 0xD9, 0x03
.byte 0x71, 0x38, 0xED, 0xC0, 0xB8, 0xE2, 0xB2, 0xEB, 0xE9, 0xC4, 0x63, 0x54, 0x41, 0x70, 0xFE, 0xB8
.byte 0x3F, 0x6D, 0x57, 0xAF, 0xAB, 0x12, 0x2D, 0xF8, 0xE0, 0xE5, 0xC8, 0x16, 0x26, 0xA1, 0x1A, 0x98
.byte 0xDA, 0x07, 0x58, 0x92, 0xE9, 0x0B, 0x7E, 0xD3, 0xD0, 0xE1, 0x28, 0x11, 0x52, 0x26, 0xCA, 0x91
.byte 0x93, 0x21, 0x41, 0x3F, 0x34, 0x6E, 0x37, 0x14, 0x54, 0xFF, 0x2B, 0x7B, 0xA1, 0x45, 0x13, 0x7B
.byte 0x4D, 0x6C, 0x0E, 0x37, 0x77, 0x8D, 0x0A, 0x47, 0x6F, 0x32, 0x59, 0xC1, 0x59, 0x23, 0x53, 0xEC
.byte 0x44, 0x94, 0x2C, 0x79, 0x02, 0x63, 0x8E, 0x57, 0x63, 0xB9, 0xD3, 0x04, 0xFF, 0xE6, 0x80, 0x4C
.byte 0x52, 0x8F, 0x83, 0xCA, 0x1C, 0x8E, 0x12, 0x8B, 0xC1, 0x6B, 0x4D, 0x1A, 0x8E, 0xA0, 0x07, 0xD3
.byte 0x34, 0x33, 0x4D, 0x37, 0x97, 0xDB, 0x8F, 0xFA, 0x95, 0x62, 0xFF, 0x94, 0x48, 0x80, 0xE1, 0x9B
.byte 0x0F, 0x65, 0x65, 0x2C, 0xF3, 0x77, 0xB7, 0xB4, 0xE2, 0x05, 0xCF, 0x71, 0xA5, 0xD6, 0x45, 0xD9
.byte 0x0A, 0x92, 0x11, 0xA1, 0x6D, 0xA0, 0x9C, 0x02, 0x02, 0x9B, 0x97, 0x4B, 0x1C, 0x78, 0xE6, 0x2B
.byte 0xDD, 0x4B, 0x57, 0xD1, 0xC3, 0x0F, 0x86, 0xA5, 0x14, 0x55, 0x17, 0xB9, 0x2C, 0x5D, 0x93, 0x37
.byte 0xEF, 0xA4, 0xD9, 0x5D, 0x45, 0x75, 0x60, 0x47, 0x11, 0xF7, 0x93, 0x2D, 0x70, 0x79, 0x59, 0x4E
.byte 0xC5, 0xB0, 0x1F, 0x88, 0xC0, 0xA6, 0x2E, 0xD4, 0xFC, 0x45, 0x8E, 0x29, 0xA2, 0x22, 0x60, 0x92
.byte 0xC7, 0x39, 0xEF, 0x0C, 0xAE, 0x50, 0x54, 0xC0, 0x48, 0xE7, 0xED, 0xB8, 0x60, 0x46, 0x06, 0x25
.byte 0xF7, 0x26, 0xAD, 0xB7, 0xCD, 0xDC, 0x8C, 0xC9, 0x21, 0x1A, 0xF2, 0xC4, 0x3D, 0x52, 0x56, 0x04
.byte 0x8C, 0x46, 0x10, 0x3A, 0x96, 0x65, 0xFA, 0xDE, 0x4C, 0xE8, 0x97, 0xAD, 0x2E, 0x9E, 0xD3, 0x26
.byte 0xC4, 0x81, 0xDD, 0x92, 0x5D, 0x69, 0x5B, 0x7E, 0x84, 0x4D, 0x43, 0xC1, 0xA0, 0x9A, 0xC6, 0x2C
.byte 0xE0, 0xD6, 0x67, 0x77, 0x3B, 0x62, 0x55, 0x88, 0x4A, 0xEC, 0x35, 0x79, 0x8A, 0x09, 0x9F, 0x4F
.byte 0x8A, 0x7D, 0xE1, 0xE7, 0xE7, 0x3D, 0x66, 0x6C, 0x8B, 0xAA, 0x2D, 0x2B, 0x44, 0xF3, 0x57, 0x24
.byte 0xCA, 0xBF, 0x9B, 0x06, 0x21, 0xF1, 0x8F, 0x6B, 0xDE, 0xC4, 0xE5, 0x69, 0xCE, 0x85, 0xB9, 0x58
.byte 0x02, 0x9B, 0x40, 0xE9, 0xD8, 0xA7, 0x55, 0x63, 0x51, 0x83, 0x8E, 0x95, 0x77, 0xE6, 0xBA, 0x42
.byte 0xA5, 0x56, 0x49, 0xC7, 0x47, 0xD8, 0x32, 0x25, 0x9D, 0x18, 0x8E, 0x6B, 0x9D, 0x48, 0xC4, 0x9F
.byte 0xE3, 0x04, 0x89, 0xBB, 0xAB, 0xDF, 0x1F, 0xFD, 0x62, 0xAD, 0x92, 0xDA, 0x94, 0x4D, 0x1C, 0x3A
.byte 0xA3, 0x65, 0x01, 0xEA, 0x3E, 0x34, 0x10, 0xDB, 0x4C, 0x9F, 0x46, 0xE9, 0xE7, 0x0A, 0x89, 0xCA
.byte 0x0F, 0x13, 0x86, 0xBA, 0xF2, 0xA5, 0xB8, 0x55, 0x53, 0x4A, 0x2F, 0xE7, 0x98, 0x4C, 0x22, 0x3B
.byte 0xB2, 0x23, 0x26, 0xF0, 0x58, 0x36, 0xCB, 0xA4, 0xD6, 0x12, 0x8E, 0xBD, 0x1D, 0x18, 0x88, 0x2C
.byte 0x2B, 0x0E, 0xE7, 0x1D, 0xB4, 0x9F, 0x72, 0x07, 0xEA, 0xA2, 0xEF, 0x82, 0xEE, 0x11, 0xBD, 0xA1
.byte 0x35, 0xE3, 0x91, 0x8D, 0x1A, 0x5D, 0x32, 0xF0, 0x70, 0xC1, 0xAE, 0x8D, 0xD9, 0x36, 0xB9, 0x04
.byte 0x45, 0xA0, 0x22, 0xF9, 0x3F, 0x95, 0x01, 0x2A, 0x37, 0xF0, 0xAC, 0x26, 0x02, 0x69, 0xC8, 0x38
.byte 0x4D, 0x59, 0xC6, 0x67, 0xB7, 0xF9, 0x57, 0x27, 0xBA, 0x05, 0xB5, 0x93, 0x3C, 0x6E, 0x98, 0x82
.byte 0x0F, 0xBA, 0x7B, 0x4F, 0x50, 0x7D, 0x79, 0x88, 0x6E, 0x25, 0xAE, 0x70, 0x8F, 0x76, 0xA9, 0xDC
.byte 0xD0, 0x6F, 0x43, 0x88, 0x69, 0x9B, 0xB0, 0x23, 0xA1, 0x65, 0xB7, 0xDD, 0xD4, 0x4F, 0x5F, 0xE3
.byte 0x0A, 0xDB, 0x32, 0x5A, 0x58, 0xAC, 0xE2, 0xC6, 0xD2, 0x91, 0x37, 0x61, 0x08, 0xE1, 0x3D, 0xD9
.byte 0x50, 0x81, 0x61, 0xBA, 0x1C, 0x11, 0xDD, 0xBD, 0x76, 0x94, 0x9B, 0x4A, 0xE4, 0xFA, 0x2E, 0xEE
.byte 0xD6, 0x61, 0x49, 0x2E, 0x0D, 0x2C, 0xF5, 0xE0, 0xBE, 0x2C, 0x41, 0xC6, 0x0D, 0x7F, 0xA0, 0x5E
.byte 0x00, 0x01, 0x18, 0x1D, 0x13, 0xF6, 0xDB, 0x8A, 0x8A, 0x76, 0xD5, 0x6E, 0x71, 0x03, 0x5D, 0x47
.byte 0x64, 0xA7, 0x75, 0x72, 0xD4, 0x6B, 0x53, 0x92, 0x97, 0x94, 0x59, 0xA5, 0x13, 0xF9, 0x04, 0x14
.byte 0xFB, 0x1D, 0x31, 0x0E, 0x13, 0x0C, 0x98, 0x9E, 0x83, 0x6D, 0x0D, 0xF4, 0x71, 0x6B, 0x3B, 0xD6
.byte 0x12, 0xB1, 0x49, 0xE6, 0x1C, 0x9C, 0x79, 0xB4, 0x30, 0xD2, 0x5A, 0x44, 0xCC, 0x5E, 0x59, 0xC7
.byte 0x7C, 0x8A, 0xD6, 0x8F, 0x97, 0x6F, 0x2E, 0x1A, 0xDD, 0x3B, 0x0E, 0x4E, 0xA6, 0x4A, 0x25, 0xB9
.byte 0xFB, 0x6E, 0xA0, 0x18, 0x0A, 0x19, 0xCC, 0x3B, 0xEC, 0x26, 0x80, 0xB9, 0x85, 0xD9, 0x80, 0x01
.byte 0x64, 0x57, 0x91, 0xFB, 0xC6, 0xBF, 0x16, 0xA3, 0xFB, 0x25, 0xF2, 0xA1, 0x6F, 0x17, 0x5B, 0x6B
.byte 0x86, 0xFB, 0x83, 0x91, 0x15, 0x50, 0xCC, 0x01, 0x77, 0x4D, 0xBA, 0xFC, 0x27, 0x3B, 0xFE, 0x8B
.byte 0x93, 0x90, 0x87, 0x59, 0x4F, 0x9E, 0xFD, 0x4A, 0xC3, 0xEF, 0xEC, 0x33, 0x07, 0x48, 0x9E, 0x8D
.byte 0x43, 0x22, 0x1E, 0x59, 0x73, 0xEB, 0x5B, 0xEA, 0x38, 0x16, 0xE7, 0x5F, 0x51, 0xE6, 0xEB, 0xE5
.byte 0x76, 0x72, 0x3E, 0xC5, 0x10, 0x3B, 0x10, 0xD4, 0x2B, 0xFC, 0x07, 0x32, 0x44, 0xA6, 0xC0, 0x88
.byte 0xC9, 0xDE, 0xE1, 0x3C, 0xCA, 0x3C, 0x27, 0x03, 0x53, 0x0E, 0x62, 0xA4, 0xF4, 0x4E, 0x89, 0x6A
.byte 0xC1, 0xC8, 0x30, 0xD1, 0x04, 0x40, 0xA6, 0x30, 0x3D, 0xAD, 0x62, 0x82, 0x54, 0x23, 0x0B, 0x1E
.byte 0x01, 0xED, 0x5A, 0xCB, 0x29, 0x81, 0xCE, 0x7C, 0x90, 0x31, 0x21, 0x85, 0x80, 0xAB, 0xF0, 0x41
.byte 0x74, 0x20, 0x12, 0x78, 0x61, 0xB9, 0xA8, 0x9F, 0x66, 0x0B, 0x21, 0xBB, 0x2E, 0x2C, 0xD9, 0x30
.byte 0x19, 0x34, 0xFC, 0x43, 0xB6, 0xCB, 0xC0, 0x46, 0xFD, 0xE2, 0xCC, 0x7D, 0x8E, 0xBC, 0xBE, 0x02
.byte 0xDD, 0xD1, 0x7B, 0x3E, 0x8A, 0x24, 0xDD, 0xF1, 0x30, 0xFF, 0xAD, 0x5F, 0x2C, 0x86, 0x90, 0x46
.byte 0xBB, 0x8D, 0x8A, 0x71, 0x58, 0x4A, 0xB8, 0x56, 0x2D, 0x84, 0xD3, 0xBC, 0x40, 0x92, 0xBF, 0x1D
.byte 0x64, 0x3A, 0x5C, 0xEF, 0x5F, 0x3A, 0xE0, 0x90, 0x39, 0x8E, 0xF0, 0x65, 0x14, 0x80, 0xAC, 0xCF
.byte 0x0D, 0x36, 0x40, 0x66, 0x81, 0xF9, 0xBC, 0xAE, 0x7D, 0x90, 0x6B, 0xBE, 0x23, 0x2A, 0xDC, 0x88
.byte 0x65, 0x38, 0x77, 0xC5, 0x72, 0x58, 0x55, 0xAC, 0xE6, 0x45, 0x11, 0xFB, 0xC6, 0xBE, 0xCA, 0xD3
.byte 0xF4, 0x0B, 0x3A, 0x75, 0x04, 0xF7, 0x24, 0x82, 0x87, 0x8F, 0x40, 0xAB, 0xB9, 0x1D, 0x33, 0x1F
.byte 0x55, 0xAB, 0xE4, 0xC8, 0x03, 0x39, 0x74, 0xEA, 0x7F, 0x86, 0xE5, 0x45, 0x44, 0xAF, 0x19, 0x38
.byte 0xBB, 0x53, 0xAE, 0xC0, 0x4A, 0xD2, 0x43, 0xD2, 0x62, 0x84, 0x7E, 0x1C, 0xA1, 0xB2, 0x3B, 0xF6
.byte 0x5D, 0x1F, 0xBE, 0x60, 0x59, 0x33, 0x4A, 0xD9, 0xB9, 0x30, 0x1E, 0xFE, 0xE0, 0x38, 0x37, 0x9B
.byte 0x8C, 0xE5, 0x5C, 0xD6, 0xB7, 0x9F, 0xA9, 0x1A, 0x23, 0x28, 0x36, 0xC4, 0xDA, 0x71, 0xBB, 0x37
.byte 0x91, 0x7A, 0x98, 0xEB, 0xAD, 0xE2, 0xC4, 0x67, 0x13, 0xE3, 0x66, 0xF3, 0x1B, 0x9D, 0x8E, 0xA7
.byte 0x82, 0xEB, 0x7E, 0x3A, 0x8B, 0x28, 0x54, 0xAF, 0x50, 0x8B, 0x73, 0x2A, 0xFC, 0x2F, 0x61, 0x8E
.byte 0xA9, 0xF9, 0x79, 0x57, 0xDC, 0x3D, 0xBF, 0xEF, 0x20, 0x25, 0xE2, 0x3C, 0xC3, 0x71, 0xE3, 0x45
.byte 0x5D, 0x62, 0x80, 0xE8, 0x8A, 0xD4, 0x97, 0xDB, 0x5F, 0x0B, 0x05, 0x5C, 0x3B, 0x67, 0xEA, 0xE4
.byte 0x61, 0x64, 0x3C, 0x3D, 0xA1, 0xFC, 0x2D, 0xC2, 0x22, 0x10, 0xFF, 0xE5, 0x82, 0xE2, 0x2A, 0xDF
.byte 0x45, 0xAA, 0xC7, 0xD0, 0x7F, 0x5F, 0xAB, 0xDF, 0x6B, 0xB0, 0x3C, 0xA6, 0x17, 0x27, 0x8B, 0x78
.byte 0x8B, 0xC7, 0xB6, 0x2D, 0xC4, 0xE4, 0xEF, 0xE6, 0xF4, 0xEF, 0xCB, 0x77, 0xD1, 0xF6, 0x56, 0x17
.byte 0xA1, 0x1E, 0xE7, 0x21, 0x7D, 0x92, 0x01, 0xE9, 0x43, 0x3D, 0x8F, 0x5B, 0x64, 0x1A, 0xD4, 0xF0
.byte 0xE2, 0x8A, 0x1D, 0xA6, 0x6E, 0x0D, 0x8C, 0x63, 0xFC, 0x58, 0xDA, 0xCE, 0x4F, 0x31, 0xE5, 0xF0
.byte 0x4F, 0xCD, 0x12, 0xCD, 0x5F, 0x13, 0xB6, 0xA3, 0x50, 0x45, 0xFE, 0xB5, 0x60, 0xD2, 0xA5, 0x42
.byte 0x5C, 0xC3, 0xE8, 0xCB, 0xD0, 0x75, 0x2F, 0xCC, 0xCE, 0x0A, 0x9A, 0x1D, 0x3B, 0x80, 0x0E, 0x8B
.byte 0x4D, 0x21, 0x58, 0xAD, 0x34, 0x0F, 0x50, 0x85, 0x55, 0x4E, 0x3B, 0xB5, 0x20, 0xE1, 0xF8, 0x7D
.byte 0xA4, 0xE1, 0x49, 0x74, 0x57, 0x79, 0x41, 0x25, 0x83, 0xDB, 0x43, 0xBF, 0x5C, 0x52, 0x4A, 0xA9
.byte 0x73, 0xA3, 0x57, 0xA8, 0xB2, 0xA7, 0x2E, 0x08, 0xF6, 0x69, 0xBE, 0x17, 0x4A, 0xB6, 0x95, 0xEE
.byte 0x98, 0xDE, 0x63, 0xEF, 0x57, 0xA4, 0x15, 0xDB, 0x80, 0x59, 0x9A, 0xDC, 0xAC, 0xE5, 0x86, 0x20
.byte 0x88, 0xDD, 0xC8, 0x3B, 0x85, 0xF7, 0x43, 0x7C, 0x60, 0x02, 0x93, 0xAB, 0xB9, 0x28, 0x9A, 0x51
.byte 0x07, 0xFD, 0x40, 0x5F, 0xA2, 0x56, 0x3A, 0x22, 0xAF, 0xD5, 0xFE, 0x5B, 0xBA, 0x85, 0x7B, 0x43
.byte 0x63, 0x44, 0x7E, 0xE8, 0x3B, 0xC2, 0x65, 0x9C, 0xC5, 0xF8, 0x48, 0x7E, 0x21, 0xE2, 0xCF, 0x28
.byte 0xE0, 0x10, 0x87, 0x82, 0x67, 0xC2, 0xA4, 0x16, 0x98, 0xA3, 0x72, 0x53, 0x29, 0xEE, 0x96, 0x8C
.byte 0x32, 0x15, 0x75, 0x6E, 0xD7, 0xDA, 0x0B, 0x9C, 0xD3, 0x53, 0x1B, 0xF4, 0x35, 0xEB, 0x1C, 0x15
.byte 0xFC, 0xA4, 0x98, 0x63, 0x67, 0x3D, 0x7A, 0xFF, 0xE0, 0xEC, 0x52, 0x0A, 0xDA, 0xE9, 0x96, 0x0D
.byte 0xFE, 0x0B, 0x7C, 0xD5, 0xE6, 0x87, 0x72, 0xB9, 0xDA, 0x8E, 0xAD, 0x0F, 0x79, 0xCA, 0x25, 0x75
.byte 0x6E, 0xBE, 0xD8, 0xD5, 0xFB, 0x52, 0xD5, 0xDC, 0x3E, 0x27, 0xE6, 0x19, 0x10, 0x7D, 0x27, 0x0E
.byte 0x88, 0xA3, 0xE4, 0x6E, 0x2A, 0x57, 0x28, 0x05, 0xE5, 0xD5, 0x15, 0x5E, 0x9F, 0x3A, 0xD4, 0x0D
.byte 0xF9, 0xAC, 0xE3, 0xF4, 0xFE, 0xB8, 0xD1, 0x3D, 0xE0, 0xB8, 0x57, 0xF1, 0x35, 0x7F, 0x00, 0xBD
.byte 0x22, 0xE5, 0x2C, 0x4D, 0x3C, 0x54, 0x52, 0x22, 0x2A, 0x68, 0x81, 0xC9, 0xA3, 0x55, 0xD7, 0x9C
.byte 0x02, 0xBA, 0x91, 0x00, 0x73, 0x62, 0x3E, 0x54, 0x1A, 0x96, 0x45, 0x4F, 0x15, 0x45, 0x0D, 0x38
.byte 0x2B, 0x3A, 0x85, 0x68, 0x8F, 0xD8, 0x8A, 0xB9, 0x40, 0x0C, 0x83, 0xE3, 0x61, 0x5B, 0x80, 0x63
.byte 0x15, 0x11, 0x64, 0x89, 0x73, 0xA3, 0xDD, 0x8E, 0x3A, 0x23, 0xDE, 0x4F, 0x69, 0xEC, 0x87, 0x94
.byte 0x27, 0x0D, 0xFC, 0xB7, 0xE6, 0x87, 0x71, 0x27, 0x93, 0xF4, 0x0B, 0xF5, 0x4F, 0x8C, 0x59, 0x65
.byte 0x9D, 0xBE, 0xEF, 0x11, 0x62, 0xCD, 0xA0, 0x9C, 0xF0, 0x7E, 0xEC, 0x59, 0x6B, 0x74, 0xEE, 0x92
.byte 0x81, 0xEB, 0x49, 0x68, 0x72, 0xBA, 0x90, 0x06, 0xAF, 0x9C, 0xFC, 0xFE, 0x28, 0x56, 0x64, 0xC5
.byte 0x14, 0x53, 0xD7, 0x76, 0x20, 0x77, 0x13, 0x11, 0xF5, 0xFF, 0x6B, 0x61, 0x73, 0x59, 0xF3, 0xF5
.byte 0x45, 0x3D, 0x5E, 0xB7, 0xF7, 0xEE, 0xBE, 0xA6, 0x8B, 0xBB, 0xA5, 0xB3, 0x11, 0x09, 0x79, 0x25
.byte 0x5D, 0x50, 0x9C, 0x7D, 0xC7, 0xAF, 0x8F, 0xBD, 0xAE, 0xFA, 0x1E, 0x22, 0x53, 0x12, 0x17, 0x98
.byte 0x4F, 0x75, 0x50, 0x46, 0x63, 0x0F, 0xED, 0xEE, 0xCA, 0x92, 0xA2, 0xDC, 0x9C, 0x1B, 0x01, 0xF9
.byte 0x6B, 0x9E, 0x77, 0x33, 0x4E, 0x06, 0xF1, 0xFC, 0x00, 0x0F, 0x1F, 0x54, 0x21, 0x36, 0xED, 0x70
.byte 0xAB, 0x3D, 0xB7, 0x0F, 0x4D, 0xA4, 0xFE, 0x18, 0x37, 0xA0, 0xF4, 0xD3, 0xBC, 0xF5, 0xCD, 0x28
.byte 0x94, 0x44, 0x5C, 0xE2, 0x4B, 0x4D, 0xDF, 0x4C, 0x5C, 0xFE, 0xA0, 0x7E, 0x34, 0x8D, 0xEE, 0xE0
.byte 0xCB, 0xA6, 0xF0, 0x18, 0x4A, 0xEE, 0x30, 0x81, 0x8F, 0x25, 0x55, 0x4C, 0x1B, 0x22, 0x74, 0xAF
.byte 0x67, 0xD0, 0x91, 0xB2, 0x1D, 0x71, 0xFE, 0x7A, 0x70, 0x9F, 0xF8, 0xA4, 0x2C, 0xE7, 0x85, 0xF8
.byte 0x8E, 0x75, 0x11, 0xD8, 0x64, 0x42, 0x5A, 0xF3, 0x67, 0xB0, 0x3F, 0x82, 0xD3, 0xB4, 0x31, 0x3A
.byte 0x85, 0xC3, 0xED, 0xA3, 0x35, 0xEC, 0x1D, 0xA5, 0x8B, 0x16, 0x4A, 0xB8, 0xFE, 0xCF, 0xB0, 0x8C
.byte 0x45, 0xC2, 0x65, 0xA9, 0x04, 0xC0, 0x9D, 0x6B, 0x71, 0xDD, 0xED, 0x44, 0x91, 0x1F, 0x7E, 0x16
.byte 0xE3, 0x6B, 0xB9, 0x18, 0x57, 0xD7, 0xBD, 0xE3, 0xEE, 0x07, 0x9B, 0xEC, 0xD7, 0x4C, 0x79, 0x1C
.byte 0x0F, 0xDF, 0xC5, 0x13, 0xA0, 0x63, 0x7F, 0x11, 0x40, 0x6D, 0x55, 0xD1, 0x8C, 0xD4, 0xE8, 0x6F
.byte 0x3F, 0xA2, 0x87, 0x97, 0x79, 0x44, 0x7B, 0x68, 0x4C, 0x17, 0x54, 0x23, 0x64, 0xCE, 0x3F, 0x73
.byte 0xAE, 0x05, 0x86, 0x4E, 0x68, 0x06, 0x60, 0xA8, 0x73, 0xB6, 0x7A, 0xFF, 0x8A, 0x62, 0x6F, 0xCA
.byte 0x04, 0xF6, 0x62, 0x7E, 0x3B, 0xDD, 0xE6, 0x87, 0xF4, 0x3B, 0xAB, 0x58, 0x0A, 0xEA, 0xCC, 0xB8
.byte 0xEF, 0x53, 0x07, 0x58, 0x59, 0x68, 0x00, 0xCC, 0x1E, 0x7A, 0xCC, 0xA8, 0xDD, 0x3B, 0x72, 0xE2
.byte 0x31, 0xD4, 0x60, 0x6D, 0xB2, 0x47, 0xF5, 0xA6, 0x83, 0xA0, 0xFF, 0x8D, 0x8B, 0xCC, 0x46, 0x7A
.byte 0x1F, 0x4E, 0xD3, 0x78, 0xB6, 0xD3, 0x45, 0xD5, 0x4E, 0x11, 0x7D, 0x2C, 0x4C, 0xF0, 0x0E, 0x7E
.byte 0xC4, 0x6F, 0xEC, 0x77, 0xB6, 0xE1, 0x1D, 0x39, 0x82, 0x1D, 0xC7, 0x0D, 0xE9, 0x0D, 0x88, 0x09
.byte 0x5C, 0x5B, 0x81, 0x12, 0x2F, 0xC7, 0xE7, 0x7D, 0xD8, 0x65, 0xA9, 0x25, 0x55, 0xB8, 0xA3, 0x1A
.byte 0x27, 0x90, 0x91, 0xDD, 0x71, 0xAF, 0x17, 0xF3, 0xCD, 0xDE, 0x00, 0xB6, 0xEC, 0x88, 0xBF, 0x48
.byte 0xE4, 0x41, 0x5B, 0x13, 0x09, 0x43, 0x90, 0xE1, 0xA8, 0x3A, 0x07, 0xFE, 0xF3, 0xAB, 0x18, 0x1A
.byte 0x3B, 0xAA, 0xF8, 0xAC, 0x59, 0x0F, 0xA0, 0x26, 0xEE, 0xA1, 0xDD, 0xDB, 0x2A, 0x9D, 0x23, 0x0E
.byte 0xDF, 0x7E, 0x21, 0xE8, 0xC2, 0xB2, 0xCA, 0x6A, 0xED, 0xD1, 0x68, 0xE0, 0x7C, 0x81, 0xFA, 0xB7
.byte 0x2B, 0xF3, 0x64, 0x85, 0x02, 0x04, 0xAB, 0xF1, 0xA6, 0x89, 0xCC, 0xD1, 0x26, 0xF0, 0xDF, 0x05
.byte 0x6F, 0x01, 0xEE, 0x31, 0xB4, 0xB8, 0x9B, 0xA1, 0x89, 0x04, 0x82, 0x05, 0x85, 0x7C, 0xBC, 0xB1
.byte 0x6F, 0x20, 0x36, 0x72, 0x25, 0xE1, 0x64, 0xCB, 0x6B, 0x30, 0x9C, 0x91, 0x20, 0x7C, 0x97, 0x90
.byte 0x7D, 0x85, 0xC1, 0x32, 0x3D, 0x5D, 0xD3, 0xC6, 0x61, 0x55, 0xCC, 0xE7, 0xD2, 0x88, 0x98, 0x42
.byte 0xA8, 0xCE, 0xB5, 0xCE, 0xB0, 0x19, 0x9A, 0x1B, 0x49, 0x37, 0xAD, 0x6A, 0xB3, 0x45, 0xFA, 0x31
.byte 0xCA, 0xBC, 0x63, 0x08, 0x19, 0x37, 0xCF, 0x7B, 0x8D, 0x9B, 0x62, 0x5F, 0x23, 0xFB, 0xA1, 0xCC
.byte 0xCA, 0x57, 0x9A, 0x7A, 0x70, 0x35, 0x96, 0xBA, 0x6C, 0x44, 0x24, 0x20, 0x89, 0x1F, 0x52, 0x53
.byte 0xDC, 0xB6, 0x5C, 0xF5, 0xEE, 0x2B, 0x71, 0x7B, 0xC6, 0xD3, 0xDA, 0xEA, 0xCF, 0x7C, 0xB6, 0x99
.byte 0xD3, 0x51, 0x14, 0x44, 0x86, 0xAA, 0xFE, 0xF3, 0xEF, 0x23, 0x14, 0x78, 0x43, 0x66, 0xCC, 0x1F
.byte 0x1D, 0x28, 0x15, 0x0B, 0x54, 0x86, 0x86, 0x1A, 0x5A, 0x61, 0x04, 0x29, 0xDE, 0xBB, 0xC3, 0xB2
.byte 0x0D, 0xD7, 0xF6, 0x94, 0x82, 0xF4, 0x87, 0x71, 0x17, 0x9C, 0xE9, 0x5A, 0x03, 0xB6, 0x7A, 0x20
.byte 0xDE, 0x8F, 0x2C, 0x33, 0x16, 0xB3, 0x4D, 0x70, 0x15, 0x52, 0x9A, 0xF3, 0x0E, 0x5D, 0xA6, 0x1B
.byte 0x35, 0x9C, 0xAF, 0xB7, 0x90, 0x37, 0x29, 0xA8, 0xD3, 0x12, 0x03, 0xD7, 0xC9, 0x7D, 0xF7, 0xA8
.byte 0x0D, 0x24, 0xDB, 0x23, 0xD7, 0x28, 0x94, 0xED, 0x7B, 0x2F, 0xE0, 0x89, 0x8D, 0x86, 0xA5, 0xC2
.byte 0x23, 0x54, 0x79, 0xB4, 0x8C, 0xA2, 0x5C, 0x60, 0xB5, 0x60, 0x37, 0x7F, 0xDE, 0x2F, 0x27, 0xEB
.byte 0x53, 0x02, 0x0F, 0x2B, 0x2B, 0xA4, 0x18, 0xA6, 0xD3, 0xF9, 0x30, 0x60, 0x7F, 0xD5, 0x22, 0xA3
.byte 0x2A, 0x9C, 0x57, 0xB7, 0x3F, 0xB4, 0x17, 0xF5, 0x14, 0x4E, 0x74, 0xF2, 0x7E, 0x9B, 0xDE, 0xD1
.byte 0x9E, 0xED, 0xFD, 0xC9, 0x91, 0x15, 0x70, 0x65, 0x0E, 0xA1, 0xC5, 0x8E, 0x77, 0xE8, 0x31, 0xA2
.byte 0x84, 0x89, 0x59, 0xC4, 0x3D, 0x71, 0xB9, 0x51, 0xC0, 0x2D, 0x44, 0x3E, 0xC9, 0x22, 0x10, 0x67
.byte 0x10, 0x0D, 0x31, 0xA2, 0x22, 0xA2, 0x07, 0x31, 0x43, 0xCC, 0xC0, 0xBB, 0xB5, 0xF2, 0x5D, 0x39
.byte 0x7B, 0xB6, 0xFD, 0xB8, 0x27, 0xB7, 0x0A, 0xE7, 0xE5, 0x4E, 0x26, 0xAE, 0x70, 0x36, 0x16, 0x81
.byte 0x43, 0x48, 0x23, 0x66, 0xEA, 0x2B, 0x98, 0x2E, 0xF8, 0x58, 0xE9, 0xAD, 0x4A, 0x46, 0xE6, 0xC6
.byte 0xFD, 0xE4, 0x7E, 0x25, 0x9B, 0x88, 0x0C, 0x80, 0xD6, 0x33, 0x2F, 0x47, 0x69, 0x45, 0xC9, 0xAC
.byte 0x8E, 0xEC, 0x13, 0x78, 0x17, 0xAB, 0xA6, 0x0F, 0x04, 0x8F, 0xBD, 0x4F, 0xD6, 0xA3, 0x15, 0xD3
.byte 0x88, 0x93, 0xF8, 0x24, 0x1C, 0x05, 0xA5, 0xF3, 0x38, 0xD4, 0x3B, 0xA1, 0x1A, 0x04, 0x4E, 0xA8
.byte 0xF0, 0x61, 0x21, 0x08, 0x0D, 0xC7, 0x18, 0x11, 0x57, 0xD5, 0x60, 0x2D, 0x79, 0x75, 0x01, 0x02
.byte 0x09, 0xF9, 0x26, 0x26, 0xFF, 0xCB, 0x19, 0x37, 0xA0, 0x54, 0xD8, 0xBA, 0x58, 0x27, 0x63, 0x49
.byte 0x89, 0x84, 0x52, 0x96, 0x4C, 0x6B, 0xA8, 0xA3, 0x40, 0x08, 0xD1, 0xBA, 0x7E, 0xD2, 0xBC, 0x88
.byte 0xCB, 0xE2, 0xAE, 0xCA, 0xAE, 0xC7, 0x02, 0x4E, 0x1C, 0xDB, 0x09, 0x74, 0x02, 0x6C, 0xBE, 0x8B
.byte 0xF1, 0x10, 0x22, 0x3D, 0x7B, 0xCA, 0xE1, 0xBC, 0xD3, 0xB2, 0x76, 0x52, 0x84, 0x33, 0xDA, 0x50
.byte 0x16, 0x89, 0x1B, 0xC4, 0x51, 0x1D, 0x13, 0x6D, 0xF8, 0x1C, 0xE2, 0xFB, 0x89, 0xA0, 0x87, 0x7B
.byte 0xB1, 0xA9, 0xB8, 0x2D, 0x74, 0x99, 0xE9, 0x47, 0x4C, 0x60, 0x99, 0xD0, 0x93, 0x74, 0x21, 0xA9
.byte 0xFD, 0x3C, 0x6E, 0x4E, 0x59, 0x81, 0xBC, 0x52, 0x9E, 0x9E, 0x4E, 0x27, 0x3F, 0xD5, 0xA2, 0xF1
.byte 0x7F, 0x5B, 0x1E, 0xF3, 0xF5, 0x08, 0x3B, 0x41, 0x68, 0xD4, 0x12, 0xFC, 0x49, 0x33, 0xA6, 0x46
.byte 0x70, 0x15, 0x95, 0xCA, 0x96, 0x51, 0x1C, 0x34, 0xF0, 0x6B, 0x5C, 0x30, 0x40, 0xFF, 0x21, 0xBF
.byte 0x5B, 0x40, 0xB2, 0x50, 0x48, 0xEE, 0x92, 0xB0, 0xC3, 0xA5, 0xAD, 0x0C, 0xD9, 0x54, 0x53, 0x49
.byte 0x69, 0xE8, 0x13, 0xFF, 0x3A, 0x30, 0x34, 0x2B, 0x9B, 0x91, 0x5B, 0xDC, 0x91, 0x7D, 0x9B, 0xEC
.byte 0xBD, 0x4E, 0x3C, 0x05, 0x3C, 0xCF, 0xB6, 0xFF, 0x74, 0x64, 0x0C, 0x4E, 0xB8, 0x5F, 0x97, 0x21
.byte 0x48, 0xAB, 0x21, 0x83, 0xDC, 0x56, 0xAE, 0x77, 0xE8, 0x0A, 0x53, 0x79, 0x88, 0xEF, 0x65, 0x46
.byte 0x3E, 0xA2, 0x4B, 0x7A, 0x72, 0x02, 0x7A, 0xE7, 0x66, 0x86, 0x35, 0x1F, 0xE6, 0xCC, 0x40, 0x2E
.byte 0x78, 0x62, 0xB2, 0x54, 0xB9, 0x61, 0xCC, 0xA1, 0x6B, 0x1F, 0x1A, 0xF4, 0x0F, 0x80, 0x3A, 0x4D
.byte 0x22, 0x86, 0xC8, 0x94, 0x88, 0x42, 0x7B, 0xEF, 0xC9, 0xB0, 0x0E, 0xAF, 0x7D, 0x4F, 0xDE, 0xF6
.byte 0xB2, 0x90, 0x4A, 0x6B, 0xF1, 0x16, 0x0C, 0x5D, 0x36, 0x27, 0x51, 0x45, 0xA7, 0x8C, 0x92, 0xCA
.byte 0x12, 0x5A, 0x5E, 0x9B, 0x9D, 0xDA, 0x8A, 0x67, 0x8B, 0x99, 0x16, 0x09, 0xE8, 0xF5, 0xFF, 0x9A
.byte 0x85, 0x49, 0x06, 0x77, 0x60, 0x13, 0xD4, 0x96, 0x3B, 0x26, 0xDB, 0xE2, 0xB2, 0x6E, 0xAD, 0xC5
.byte 0xC9, 0x0B, 0x60, 0x67, 0xE6, 0xEB, 0xCE, 0x71, 0x84, 0xE5, 0x7B, 0x6D, 0xDA, 0x7A, 0x08, 0x60
.byte 0xC4, 0x0E, 0xD7, 0x24, 0x22, 0xAB, 0xBA, 0x5D, 0xD2, 0x96, 0x3F, 0x85, 0x05, 0xEC, 0x4A, 0xCF
.byte 0xF8, 0xAB, 0x36, 0xDF, 0x96, 0x04, 0x51, 0x1B, 0xE9, 0xCC, 0x88, 0xC3, 0x46, 0x90, 0x23, 0x0A
.byte 0x9F, 0xFB, 0x2E, 0xC1, 0xA7, 0xE9, 0x1E, 0x79, 0x80, 0x5E, 0xFF, 0x85, 0x4B, 0x4A, 0x54, 0x44
.byte 0xF5, 0x8B, 0x23, 0x8C, 0x8F, 0x74, 0xA8, 0x79, 0x41, 0x30, 0x3D, 0x87, 0xC1, 0x61, 0x92, 0x61
.byte 0x5C, 0xC1, 0x22, 0x03, 0xAB, 0x41, 0x7D, 0x2B, 0xA0, 0x7C, 0xB1, 0xEB, 0xC6, 0x06, 0x2F, 0xBC
.byte 0x91, 0x53, 0x49, 0x21, 0xC8, 0xF1, 0x9A, 0x09, 0x22, 0xD7, 0x91, 0xE4, 0x38, 0x24, 0x45, 0x94
.byte 0xE5, 0x68, 0x98, 0x90, 0xAA, 0x15, 0xBB, 0x4A, 0x92, 0x6D, 0x35, 0x59, 0x73, 0x65, 0x16, 0x05
.byte 0xB9, 0x5F, 0x26, 0x81, 0x51, 0xC0, 0x8B, 0x73, 0x97, 0x1D, 0x57, 0xD0, 0x41, 0x9D, 0x64, 0x26
.byte 0x05, 0xFD, 0xB7, 0xB0, 0x12, 0x73, 0xFA, 0xA5, 0xE0, 0x2F, 0xFE, 0x54, 0x95, 0x14, 0x59, 0x4E
.byte 0x74, 0x7F, 0xD0, 0xC5, 0x40, 0x5C, 0x38, 0xD8, 0x79, 0x90, 0xA8, 0xBB, 0x2E, 0x0D, 0xE2, 0x34
.byte 0x0A, 0x99, 0xE4, 0x1D, 0x0C, 0xDE, 0xC2, 0xED, 0x0E, 0xC1, 0x41, 0xA3, 0xD6, 0x9A, 0xF2, 0x4A
.byte 0x1A, 0xC3, 0x0F, 0x5A, 0x20, 0x48, 0x33, 0x99, 0xD9, 0xDB, 0x55, 0x07, 0xE9, 0x37, 0x3B, 0xF4
.byte 0xD0, 0x20, 0x11, 0xDC, 0xFE, 0xD4, 0xC9, 0x0D, 0x96, 0x0B, 0xB0, 0x6C, 0xA5, 0xA3, 0xB7, 0xC0
.byte 0x67, 0xC7, 0x1B, 0x87, 0x0F, 0x4E, 0x21, 0xE9, 0x2A, 0x76, 0xF1, 0x13, 0xAD, 0x2D, 0x08, 0x7D
.byte 0x4D, 0x1A, 0x5A, 0x4B, 0xEE, 0x24, 0x58, 0x85, 0x2F, 0x09, 0xF2, 0xD5, 0xAD, 0xA9, 0x95, 0x14
.byte 0x70, 0xB1, 0x9C, 0x80, 0x00, 0xBD, 0x69, 0x2A, 0x33, 0x5B, 0x3E, 0xE0, 0x88, 0x46, 0x5E, 0xD5
.byte 0x60, 0xB9, 0x21, 0x4F, 0xDD, 0x7A, 0xD5, 0x0C, 0x84, 0xC7, 0xE2, 0x32, 0x70, 0x78, 0x47, 0xE0
.byte 0x29, 0xE3, 0x61, 0x29, 0xA0, 0xCB, 0x54, 0xD4, 0x26, 0x93, 0xB5, 0xAE, 0xDA, 0x13, 0x84, 0x3B
.byte 0xCC, 0xA6, 0x8B, 0xAA, 0x21, 0x60, 0xB6, 0xA5, 0x27, 0x99, 0xD8, 0x97, 0x11, 0x1F, 0x78, 0x3A
.byte 0x02, 0xDA, 0x64, 0xA3, 0xA5, 0xB9, 0x77, 0xCB, 0x4D, 0x2D, 0x7A, 0x27, 0x40, 0xFF, 0x63, 0x0D
.byte 0xA5, 0xEE, 0xB7, 0xC7, 0x4E, 0x6E, 0x6C, 0x76, 0x07, 0x45, 0x0E, 0x19, 0x64, 0x87, 0x54, 0x67
.byte 0x61, 0xB9, 0x0A, 0x06, 0x72, 0x82, 0xD2, 0xBF, 0xB0, 0x4D, 0xE7, 0xF0, 0x4D, 0x4A, 0xFE, 0xF3
.byte 0x39, 0xB6, 0xBA, 0x87, 0x25, 0x27, 0xFE, 0x2C, 0x6C, 0x0C, 0x46, 0xD0, 0x94, 0x9A, 0x38, 0xF5
.byte 0x53, 0x43, 0xFC, 0xC5, 0xC6, 0xCF, 0x85, 0x76, 0x1D, 0x6D, 0x67, 0x6A, 0xB7, 0x65, 0x5D, 0xF0
.byte 0x1C, 0x18, 0x78, 0x41, 0x3F, 0x77, 0x6E, 0xAB, 0x84, 0xB4, 0x7C, 0x18, 0x4E, 0xB4, 0x0E, 0xA1
.byte 0xF8, 0x0A, 0x67, 0xBE, 0xDA, 0xED, 0x34, 0xF7, 0x5A, 0x9B, 0x62, 0x12, 0x01, 0xC0, 0x03, 0x1D
.byte 0xD8, 0x7C, 0x5E, 0x18, 0xF3, 0xCD, 0xC4, 0x77, 0x81, 0x40, 0x8F, 0xD0, 0xF5, 0x9E, 0x72, 0xEE
.byte 0xA8, 0xDA, 0xAC, 0x83, 0xC7, 0xE0, 0x7A, 0x22, 0x7C, 0xDC, 0x35, 0x7D, 0x9D, 0x39, 0x9A, 0x75
.byte 0xB5, 0xF9, 0x8D, 0xA8, 0xC6, 0x52, 0x20, 0x48, 0x93, 0xB0, 0x18, 0x89, 0x4E, 0x8B, 0x77, 0xF7
.byte 0x65, 0x23, 0x7A, 0x2D, 0x03, 0xF5, 0x4F, 0x7F, 0xD2, 0x85, 0xFD, 0x6F, 0xBE, 0x97, 0xE4, 0x73
.byte 0x91, 0x72, 0x1C, 0x58, 0xC4, 0x3D, 0xA1, 0x58, 0xED, 0xBA, 0xE1, 0x3C, 0x45, 0x58, 0x33, 0xAA
.byte 0x7B, 0xAE, 0xD7, 0x7F, 0xA3, 0x27, 0xFF, 0x75, 0xAC, 0xFC, 0xE4, 0x6B, 0x94, 0xC9, 0xDE, 0x25
.byte 0x3C, 0xFB, 0x7E, 0x01, 0x38, 0x1F, 0x59, 0x26, 0xDA, 0x3A, 0x63, 0x1F, 0x92, 0x96, 0xC9, 0x0E
.byte 0x45, 0xA1, 0x8D, 0xE8, 0xC8, 0x8C, 0x5D, 0x75, 0x88, 0x42, 0xE0, 0x1C, 0x0B, 0xBF, 0x42, 0x48
.byte 0xBA, 0xC1, 0x49, 0xF3, 0xE1, 0xA2, 0x1A, 0xBB, 0xDD, 0x7D, 0xDA, 0x6F, 0x13, 0xA4, 0x7D, 0x58
.byte 0x45, 0x0B, 0x41, 0x0E, 0x97, 0x9F, 0x83, 0x20, 0xE1, 0x64, 0x3D, 0xED, 0x23, 0x7F, 0x35, 0xDE
.byte 0x40, 0x7E, 0xD1, 0x22, 0x21, 0xEB, 0xDD, 0xFE, 0x68, 0xB8, 0x6E, 0x7C, 0x5C, 0xEC, 0xD5, 0xA2
.byte 0xF7, 0x17, 0xB0, 0x8F, 0xB6, 0x34, 0xAF, 0x97, 0x98, 0xED, 0x85, 0xBC, 0x6C, 0xBA, 0x9A, 0xAD
.byte 0x39, 0x6C, 0xCF, 0x5A, 0x57, 0xAD, 0x59, 0xC0, 0x65, 0xC7, 0x3D, 0xC2, 0xB4, 0x13, 0x64, 0xAC
.byte 0x2A, 0x15, 0x3B, 0xE0, 0x4A, 0xEB, 0x78, 0xE3, 0xD8, 0xFD, 0x9F, 0x45, 0xB8, 0x39, 0xF3, 0xF1
.byte 0xA5, 0xC3, 0x4C, 0xFD, 0x70, 0xA5, 0xBE, 0xD6, 0x6D, 0xFC, 0x98, 0x22, 0x0F, 0xFD, 0xCE, 0x3A
.byte 0x13, 0x0A, 0x1A, 0x5D, 0xF5, 0x93, 0x40, 0xCE, 0x90, 0xDF, 0x14, 0x49, 0x19, 0x07, 0x3A, 0xBF
.byte 0xCA, 0x87, 0xBD, 0x3A, 0x2D, 0x7B, 0x11, 0x9A, 0x78, 0xA9, 0xBD, 0x87, 0xA7, 0x8B, 0xC1, 0xBA
.byte 0x95, 0xDC, 0x18, 0x8B, 0x6F, 0x58, 0x5A, 0x00, 0x38, 0x6E, 0x49, 0x52, 0x75, 0x84, 0x11, 0x40
.byte 0x0B, 0xCF, 0x7A, 0x38, 0x4B, 0x8C, 0xD3, 0xC3, 0x36, 0x90, 0x4B, 0xDD, 0x1C, 0x0D, 0x98, 0xB2
.byte 0xE9, 0xB0, 0x3E, 0x59, 0x09, 0x98, 0x5A, 0x42, 0x07, 0xA3, 0x94, 0x7D, 0x28, 0xA6, 0xBD, 0x33
.byte 0x76, 0x37, 0x6C, 0xC1, 0xC4, 0x40, 0x84, 0xFA, 0xD1, 0xD0, 0xD7, 0xED, 0xDD, 0x6F, 0xA0, 0xC6
.byte 0x20, 0xDE, 0x20, 0x2A, 0x77, 0x7A, 0x6C, 0x7F, 0x1E, 0x01, 0xFC, 0x46, 0xA8, 0xB9, 0x7A, 0x1E
.byte 0xF1, 0xE7, 0xE0, 0xB5, 0x27, 0x65, 0xAF, 0xF8, 0x35, 0x87, 0xE6, 0x12, 0xF7, 0x86, 0xD9, 0x17
.byte 0x65, 0xFA, 0x41, 0xDD, 0x74, 0xAE, 0x5C, 0x92, 0xB0, 0x59, 0xD9, 0x59, 0x12, 0x53, 0x78, 0x03
.byte 0x3A, 0x58, 0xB9, 0x62, 0xBD, 0x68, 0x5A, 0xF3, 0xF0, 0x41, 0x06, 0xE7, 0xC8, 0xE0, 0xFE, 0x2E
.byte 0xDA, 0x40, 0x0B, 0x4E, 0xEF, 0x68, 0xE1, 0x9F, 0xC1, 0xBA, 0xF8, 0xD4, 0x0E, 0x70, 0xD8, 0x49
.byte 0xC9, 0x91, 0xAB, 0x87, 0xFA, 0x06, 0x7A, 0xEA, 0x48, 0x81, 0xD1, 0x10, 0x61, 0xD0, 0x3E, 0x3B
.byte 0x11, 0x4A, 0x8A, 0x00, 0xB3, 0x6C, 0xA0, 0x75, 0x27, 0x99, 0x49, 0x36, 0x09, 0x21, 0x7F, 0xD3
.byte 0xB3, 0x2B, 0x5A, 0xAE, 0x32, 0xD5, 0x98, 0x7A, 0x56, 0x6A, 0x8B, 0xB7, 0x3B, 0xC9, 0xF3, 0x4C
.byte 0x14, 0x7E, 0x4D, 0xC7, 0xEB, 0xED, 0x3C, 0x12, 0x86, 0x86, 0x48, 0x90, 0xA7, 0xC8, 0x63, 0x5B
.byte 0xF4, 0xBE, 0x09, 0x26, 0x93, 0xA2, 0xA1, 0xEA, 0x0D, 0x2C, 0xA1, 0x48, 0xF6, 0x95, 0x94, 0x0B
.byte 0x14, 0xE1, 0xD2, 0xFF, 0xCF, 0x0F, 0x11, 0x55, 0x95, 0x5A, 0xE6, 0x3D, 0x23, 0x49, 0x98, 0x17
.byte 0x08, 0xA2, 0x3E, 0x9B, 0x45, 0xE0, 0x85, 0x52, 0x0D, 0x27, 0x9A, 0x03, 0xBD, 0x2F, 0x0E, 0xD1
.byte 0x11, 0xE1, 0xD0, 0xE0, 0xF0, 0xE2, 0x35, 0x86, 0x3C, 0x1B, 0xC3, 0x5F, 0x65, 0x5C, 0x77, 0x6E
.byte 0xFF, 0xB5, 0x09, 0x44, 0x96, 0x8F, 0x96, 0xA3, 0xB7, 0x31, 0xA7, 0x74, 0x60, 0xB6, 0x45, 0x71
.byte 0x97, 0x16, 0x51, 0x88, 0xF8, 0x87, 0x0E, 0x35, 0xA3, 0xD2, 0x95, 0x09, 0x2F, 0x0C, 0x77, 0x2E
.byte 0xC2, 0x81, 0x73, 0x59, 0x10, 0x09, 0xFC, 0xC7, 0x3A, 0xA3, 0x3C, 0x9B, 0x59, 0x82, 0x0C, 0xF1
.byte 0x98, 0x5D, 0x79, 0x91, 0xE5, 0x88, 0xC7, 0x88, 0x5B, 0x5C, 0x91, 0x8A, 0x69, 0x09, 0xB9, 0x2C
.byte 0x8A, 0x2C, 0x85, 0x9A, 0x35, 0x81, 0x62, 0x70, 0x25, 0x9F, 0x0B, 0x7F, 0x21, 0x18, 0x70, 0xBA
.byte 0x75, 0xEA, 0x4B, 0x5B, 0x72, 0x12, 0xE3, 0xCD, 0x6F, 0x75, 0x58, 0xD9, 0x7E, 0x11, 0x05, 0x09
.byte 0x3D, 0x8B, 0xA3, 0x73, 0x0D, 0x06, 0xE4, 0x32, 0xA5, 0xEF, 0xB1, 0xC7, 0x07, 0x21, 0x81, 0x7D
.byte 0x0B, 0xCD, 0xD9, 0x7E, 0xE0, 0xBC, 0x4C, 0x4F, 0x32, 0xA4, 0x28, 0xB1, 0xB5, 0x2E, 0xBA, 0xF3
.byte 0xB9, 0x5E, 0x66, 0xC6, 0x65, 0x4A, 0xF9, 0x0A, 0x3A, 0xAA, 0xD2, 0x42, 0xCC, 0x53, 0xC0, 0xD8
.byte 0x20, 0x99, 0x56, 0x00, 0x56, 0xA2, 0x50, 0x88, 0x47, 0x79, 0x3A, 0xFD, 0xA7, 0xF4, 0xF0, 0x61
.byte 0x52, 0x57, 0x28, 0xB7, 0xA1, 0x21, 0xC2, 0xDC, 0xCB, 0x94, 0x1F, 0x97, 0xE8, 0xE0, 0x70, 0x08
.byte 0x79, 0xC6, 0x09, 0xD0, 0x69, 0x59, 0x59, 0xB1, 0xD2, 0x93, 0xAE, 0x7A, 0x87, 0x9E, 0xDB, 0xDA
.byte 0xF5, 0x03, 0x92, 0x97, 0x24, 0x55, 0x74, 0xF0, 0xEA, 0x93, 0x88, 0xD2, 0x74, 0xF8, 0xDB, 0xED
.byte 0xBF, 0xE5, 0xBD, 0x28, 0x3F, 0x17, 0xD9, 0x12, 0xAA, 0x88, 0x8C, 0x32, 0x27, 0x68, 0x0D, 0x1C
.byte 0x6C, 0x9F, 0xB4, 0x91, 0xF5, 0x29, 0x81, 0xDF, 0xBD, 0x0A, 0xB2, 0x31, 0x02, 0x8E, 0x1F, 0xC1
.byte 0x73, 0xDC, 0xEA, 0xB3, 0xF4, 0xC4, 0xC5, 0x9E, 0x4C, 0x51, 0xD0, 0x73, 0xBA, 0xDE, 0x90, 0x26
.byte 0x7E, 0x45, 0xB7, 0x73, 0x6E, 0x38, 0x53, 0x2C, 0x42, 0x06, 0x5D, 0x45, 0x94, 0x7C, 0x07, 0x08
.byte 0x59, 0xF1, 0xBB, 0x4D, 0xB6, 0x80, 0xEC, 0x03, 0xD2, 0xBD, 0x77, 0x8C, 0x9B, 0x08, 0xB2, 0x19
.byte 0x4D, 0x6A, 0x8D, 0xBC, 0xA2, 0xE0, 0xE8, 0xE5, 0xE6, 0x46, 0x2B, 0x7B, 0xC2, 0x32, 0x84, 0x1C
.byte 0x24, 0x3F, 0x6A, 0xDB, 0xC0, 0x56, 0xDE, 0x93, 0x13, 0x56, 0x20, 0xAE, 0x5E, 0xD3, 0xC8, 0xAB
.byte 0x3D, 0x55, 0x68, 0xE0, 0x35, 0x51, 0xC6, 0x1C, 0x97, 0xF1, 0x98, 0x5A, 0x24, 0x1C, 0x76, 0x49
.byte 0x5C, 0xE0, 0x24, 0x1D, 0x37, 0x03, 0xB0, 0x4A, 0x59, 0xD1, 0xF9, 0xB7, 0xA4, 0xC1, 0x63, 0xE1
.byte 0x17, 0xCB, 0xC1, 0x4D, 0x1D, 0x87, 0x69, 0xB4, 0x79, 0x02, 0x0E, 0x9D, 0x1E, 0x85, 0xE6, 0x7A
.byte 0x66, 0x0A, 0x98, 0x9E, 0x0E, 0x49, 0xE8, 0x67, 0x1A, 0xE2, 0x1F, 0xBE, 0xA3, 0x82, 0x9F, 0xBB
.byte 0x4E, 0x60, 0x08, 0x6B, 0xE8, 0x72, 0x20, 0x61, 0x74, 0x2F, 0xFE, 0x92, 0xB5, 0xE5, 0x0D, 0x1B
.byte 0xF0, 0xA6, 0xB9, 0xFE, 0xEF, 0xA2, 0x66, 0x09, 0x84, 0x85, 0xC7, 0x28, 0x08, 0x67, 0xE3, 0x57
.byte 0xC8, 0xEC, 0xC2, 0xB0, 0x5E, 0xE3, 0x12, 0xD2, 0x12, 0x11, 0x65, 0xC7, 0xF6, 0x73, 0xE3, 0xE6
.byte 0x19, 0x9D, 0xE5, 0x08, 0x40, 0x4B, 0x12, 0xC5, 0xD1, 0xDA, 0xED, 0xD9, 0x41, 0xD1, 0x30, 0x09
.byte 0xBD, 0xF3, 0xBA, 0x1C, 0xD7, 0xCD, 0xEE, 0xE9, 0xDE, 0x54, 0xB1, 0xD4, 0xC7, 0x95, 0xBB, 0xE1
.byte 0x33, 0xA1, 0xEA, 0x73, 0xED, 0xFC, 0x39, 0xBE, 0xD6, 0x26, 0x98, 0x18, 0xF8, 0xC9, 0x21, 0xB6
.byte 0xBD, 0xDC, 0xD2, 0x94, 0xA9, 0xC1, 0x7E, 0x87, 0x16, 0x2F, 0x5C, 0xDD, 0xC5, 0x18, 0xBF, 0xF8
.byte 0xBA, 0xA9, 0x6C, 0xA7, 0xA5, 0xA5, 0x66, 0x7C, 0xCC, 0xFE, 0x94, 0xC5, 0xC8, 0xB6, 0x7B, 0x85
.byte 0x92, 0x4E, 0x19, 0x3C, 0x10, 0x97, 0xC4, 0x26, 0xC7, 0x21, 0x04, 0x8C, 0x39, 0xC3, 0x85, 0xF4
.byte 0x6C, 0xF2, 0x9C, 0x12, 0x97, 0x02, 0x8E, 0x64, 0x01, 0x23, 0x29, 0xC9, 0xD9, 0xA5, 0x4E, 0x6C
.byte 0xF4, 0x68, 0xA8, 0x04, 0xFF, 0x6C, 0x2B, 0xC7, 0x8D, 0x2F, 0x54, 0xC7, 0xF2, 0xD9, 0xBB, 0x5F
.byte 0xCB, 0x57, 0x71, 0x63, 0x5A, 0x00, 0xC8, 0x5B, 0x24, 0xF2, 0x25, 0xFD, 0x97, 0x73, 0x69, 0x8C
.byte 0xDC, 0x11, 0x91, 0xDB, 0x7E, 0xBC, 0xA3, 0x0C, 0xEB, 0xF7, 0xD3, 0xDE, 0xD0, 0x8F, 0x3D, 0x9C
.byte 0xE7, 0xAF, 0x00, 0x41, 0xB0, 0xC8, 0x9C, 0xD4, 0xBA, 0xC1, 0xD1, 0x52, 0x35, 0x3B, 0xDE, 0x11
.byte 0x4D, 0x6F, 0xED, 0xCB, 0x2C, 0x90, 0xD7, 0x17, 0x87, 0xAB, 0xF5, 0x58, 0x3A, 0x33, 0xF4, 0x21
.byte 0xE2, 0xF4, 0x62, 0x92, 0xBD, 0xFF, 0x67, 0x77, 0xC1, 0x38, 0xC9, 0xF7, 0x74, 0xA8, 0x09, 0xC1
.byte 0x18, 0xF7, 0x8D, 0x44, 0x87, 0x64, 0x5B, 0x0F, 0x10, 0x51, 0x67, 0x4A, 0x84, 0x5C, 0x6C, 0x67
.byte 0x51, 0xCF, 0xFA, 0x0E, 0xCF, 0x61, 0x86, 0x91, 0x9A, 0x4F, 0x88, 0x0E, 0xF8, 0x92, 0xCF, 0x10
.byte 0x89, 0x5D, 0x54, 0x10, 0xC1, 0xB0, 0x20, 0xD2, 0x02, 0x87, 0x1D, 0x86, 0xE3, 0x89, 0xEE, 0x35
.byte 0x59, 0xE8, 0x43, 0x28, 0x49, 0xC9, 0xB9, 0xE4, 0x19, 0x42, 0xF2, 0x12, 0xD5, 0xC2, 0x22, 0x5E
.byte 0x1F, 0x77, 0x6F, 0xE1, 0x28, 0x8F, 0xB3, 0x2A, 0x16, 0xD1, 0xB0, 0xFA, 0x5A, 0x9E, 0x2F, 0xB4
.byte 0x87, 0x73, 0xDD, 0xD1, 0x3D, 0x97, 0xB5, 0x56, 0xD9, 0xA8, 0x69, 0xAE, 0x6B, 0x8B, 0x0D, 0x8A
.byte 0x03, 0x7C, 0x6C, 0x2B, 0x0B, 0x20, 0x55, 0x22, 0xF1, 0x06, 0x1D, 0x4C, 0xA5, 0x4D, 0x00, 0x2C
.byte 0xC0, 0xDD, 0xFD, 0xFE, 0x74, 0xB3, 0x55, 0x4E, 0x5C, 0xBE, 0xFD, 0xC7, 0x49, 0x0A, 0x52, 0x4C
.byte 0x87, 0xBE, 0x78, 0x92, 0xDF, 0xCD, 0xB5, 0xD0, 0xD4, 0xD2, 0x1D, 0x79, 0x1F, 0x1E, 0xA5, 0xE0
.byte 0xFB, 0xA3, 0xDE, 0x70, 0x57, 0x33, 0xBF, 0xB3, 0xF1, 0xBD, 0x7A, 0x3B, 0xC8, 0xCC, 0x88, 0x4F
.byte 0x8B, 0x00, 0xE2, 0x6A, 0xCE, 0x97, 0x3B, 0xA2, 0x69, 0x58, 0x1B, 0x89, 0x76, 0xC1, 0x69, 0x72
.byte 0x65, 0x47, 0xE3, 0xBD, 0x7B, 0xA3, 0x70, 0x6C, 0x60, 0xEB, 0xA7, 0x28, 0xB8, 0x2F, 0x78, 0x44
.byte 0x30, 0x5A, 0xAE, 0xFE, 0xF2, 0xEA, 0xA0, 0x5B, 0x43, 0xBC, 0xE5, 0xBA, 0x7D, 0x4E, 0x2D, 0xE3
.byte 0x96, 0x10, 0xA0, 0x11, 0xB4, 0x10, 0x7E, 0x14, 0xFC, 0x26, 0x3D, 0xB4, 0x55, 0xB5, 0xF9, 0x86
.byte 0x10, 0xA8, 0x84, 0x02, 0x92, 0x25, 0x5E, 0xD6, 0xE1, 0x43, 0x90, 0x5F, 0x92, 0xBD, 0x42, 0x28
.byte 0xCE, 0xE2, 0x3A, 0x82, 0xF3, 0xB9, 0x97, 0xF0, 0xDF, 0xD4, 0xA5, 0x35, 0x8A, 0x9E, 0xBB, 0x9A
.byte 0x46, 0x3F, 0x9D, 0xD8, 0x64, 0xFB, 0xAE, 0x46, 0x3E, 0x3F, 0xA5, 0xD0, 0xFC, 0xE7, 0xF9, 0xCB
.byte 0xCA, 0x34, 0x4D, 0xBD, 0xED, 0xE4, 0xAE, 0xCC, 0xB9, 0x53, 0x02, 0x43, 0xF1, 0xBD, 0xDE, 0x37
.byte 0xFD, 0x7B, 0x10, 0x62, 0x76, 0xBE, 0xA8, 0xB4, 0xFE, 0x4E, 0x85, 0xFA, 0x35, 0x7F, 0xC5, 0x00
.byte 0xB3, 0x13, 0xBE, 0xA1, 0xF7, 0x6C, 0x6D, 0xB1, 0xBF, 0x70, 0xF4, 0xB0, 0x2D, 0xD2, 0xE7, 0x2B
.byte 0x4E, 0xF7, 0x8D, 0xC4, 0xB6, 0x36, 0x79, 0xB4, 0x84, 0xFF, 0xAF, 0xBA, 0x7E, 0x75, 0xBB, 0x31
.byte 0x89, 0x79, 0xD2, 0x81, 0xE5, 0x40, 0x32, 0xA5, 0xB1, 0x26, 0x55, 0xDE, 0xF9, 0x3D, 0x0A, 0x47
.byte 0x35, 0x98, 0x0C, 0xEC, 0xCE, 0x85, 0xA1, 0x53, 0x85, 0x51, 0x0E, 0x03, 0xC6, 0xC9, 0x35, 0x50
.byte 0x43, 0x08, 0xD1, 0x29, 0x49, 0x03, 0xCE, 0xFA, 0x2A, 0x24, 0xD9, 0x24, 0x61, 0xE3, 0x6C, 0x97
.byte 0x7B, 0x78, 0x83, 0x4A, 0xFE, 0x24, 0x9E, 0x83, 0x75, 0xAD, 0x86, 0x3C, 0x77, 0xBC, 0x8C, 0xBA
.byte 0xC4, 0x5D, 0xE4, 0x0D, 0x61, 0xB2, 0x07, 0x8B, 0xD6, 0xE0, 0xB0, 0x38, 0xC4, 0x1C, 0xCF, 0x40
.byte 0x94, 0x52, 0x8B, 0x93, 0x76, 0x29, 0x17, 0xEC, 0xD7, 0x9E, 0x29, 0x4E, 0x5A, 0xB5, 0x09, 0x1E
.byte 0x13, 0xED, 0x2C, 0x74, 0x9F, 0x33, 0x00, 0x76, 0x14, 0xB1, 0xAE, 0xD9, 0xCD, 0x7D, 0x19, 0x62
.byte 0xD0, 0xA4, 0xF5, 0x47, 0xCE, 0x0C, 0x33, 0xA5, 0xAA, 0x5C, 0xF3, 0x05, 0x12, 0xFD, 0x23, 0x25
.byte 0xEA, 0x50, 0x9A, 0x8A, 0x84, 0x9B, 0x01, 0x98, 0x4C, 0xAF, 0x72, 0x1A, 0x2D, 0x8B, 0x7C, 0xFD
.byte 0x30, 0x72, 0x44, 0xFE, 0x7F, 0x78, 0xA3, 0x2A, 0xD4, 0x97, 0x2F, 0xE7, 0x94, 0x53, 0x0D, 0x7F
.byte 0xA4, 0xA8, 0x09, 0x28, 0x43, 0x0A, 0xC1, 0x90, 0xBA, 0x33, 0xAB, 0xE7, 0xBE, 0x28, 0xE5, 0xEE
.byte 0x9A, 0x29, 0xEC, 0x1A, 0xA1, 0x90, 0x45, 0x76, 0x27, 0x75, 0x5E, 0xBC, 0xC8, 0x6B, 0x3B, 0x6D
.byte 0x13, 0x45, 0x95, 0x57, 0x50, 0x56, 0xE8, 0x0A, 0x89, 0x93, 0xF2, 0x48, 0xBB, 0xD7, 0x37, 0x56
.byte 0x01, 0x24, 0x70, 0xA3, 0xB4, 0xB5, 0x19, 0xDC, 0x2B, 0x78, 0x98, 0xF3, 0xE3, 0xD4, 0x60, 0xF6
.byte 0x19, 0xF6, 0x4E, 0x69, 0x4C, 0x36, 0x74, 0xD6, 0xC9, 0x66, 0x1E, 0x85, 0x3E, 0x56, 0xDB, 0x3F
.byte 0x7A, 0x4B, 0xE2, 0x2F, 0x01, 0xFC, 0x0B, 0x2C, 0x74, 0xA4, 0x20, 0x58, 0x78, 0x81, 0x4E, 0x92
.byte 0x78, 0x9D, 0xFC, 0xC4, 0xD3, 0x70, 0x9A, 0x9D, 0xD7, 0xB9, 0x22, 0x16, 0x0F, 0xFD, 0x55, 0x89
.byte 0x49, 0x38, 0xB8, 0x4B, 0x35, 0xC4, 0x78, 0xA9, 0x69, 0x99, 0x01, 0xE1, 0x1A, 0x50, 0x74, 0x92
.byte 0xED, 0x70, 0x57, 0xC1, 0xE1, 0xF2, 0x5E, 0xB9, 0xAB, 0x80, 0xCF, 0xBB, 0x7D, 0x25, 0x44, 0xC7
.byte 0x5D, 0xFD, 0x12, 0x92, 0xC2, 0x8A, 0x3C, 0x2B, 0x23, 0x3E, 0x0D, 0x3E, 0x8F, 0x81, 0xD1, 0x7D
.byte 0xF2, 0x29, 0x3E, 0xD4, 0x1B, 0x9C, 0x8D, 0xC7, 0x1C, 0x5D, 0x82, 0x9A, 0x82, 0xC7, 0x61, 0xE0
.byte 0xC5, 0x73, 0x73, 0x87, 0xFE, 0xAF, 0xB2, 0x22, 0xEE, 0xC0, 0x60, 0x7D, 0x41, 0x32, 0xFA, 0x34
.byte 0x5B, 0x39, 0x08, 0x76, 0xD5, 0x95, 0x3E, 0xF2, 0xF2, 0xC0, 0x8C, 0x74, 0x87, 0xEE, 0x55, 0x4C
.byte 0x62, 0xC8, 0xD4, 0x60, 0x77, 0x87, 0x82, 0x66, 0x47, 0xE3, 0xE4, 0x89, 0x15, 0xDF, 0xBD, 0x71
.byte 0x18, 0xC5, 0xE8, 0xED, 0x5A, 0x26, 0xE0, 0x4D, 0xE6, 0x6D, 0xC2, 0x6E, 0x5B, 0x17, 0xBB, 0xBD
.byte 0xDF, 0x8F, 0x1E, 0x57, 0x16, 0xA1, 0xBE, 0x5D, 0x84, 0xA2, 0xE7, 0x9A, 0x81, 0xA4, 0x0B, 0x99
.byte 0x69, 0xF4, 0x87, 0xC4, 0x1A, 0x68, 0x11, 0x01, 0xD5, 0xD4, 0x6F, 0x30, 0xEC, 0x2B, 0xEE, 0xCB
.byte 0xBA, 0x0C, 0x23, 0xD1, 0xAD, 0xE1, 0x2F, 0x32, 0x84, 0x16, 0xCC, 0x05, 0xBA, 0xD8, 0x9F, 0x24
.byte 0xCC, 0x27, 0xE8, 0xE7, 0x8F, 0xFA, 0xE8, 0x65, 0xCE, 0x58, 0x95, 0xBA, 0x83, 0x84, 0x86, 0x3E
.byte 0x90, 0xAA, 0x0F, 0x3E, 0x8C, 0x3F, 0x70, 0x10, 0x55, 0x3C, 0x16, 0x10, 0x15, 0xB6, 0x34, 0xE1
.byte 0xDE, 0x1C, 0xC8, 0x6D, 0x16, 0xB1, 0xD3, 0xE5, 0x09, 0x68, 0xA0, 0x8D, 0xEC, 0x26, 0xCB, 0x7D
.byte 0xD1, 0xDB, 0xBB, 0x5D, 0x1A, 0x2C, 0x6E, 0x70, 0x69, 0x84, 0x80, 0x7E, 0x3B, 0xB4, 0x60, 0x19
.byte 0xD1, 0x28, 0x87, 0xE8, 0xDA, 0x5A, 0xCD, 0xE3, 0xC3, 0x6E, 0x71, 0xB0, 0x94, 0x3C, 0x2E, 0x66
.byte 0x18, 0xE9, 0xC3, 0x33, 0x16, 0x31, 0xA3, 0x7F, 0xB6, 0x24, 0xFE, 0xF2, 0xD9, 0x5E, 0x0B, 0xAA
.byte 0x87, 0x93, 0x92, 0x61, 0xED, 0x60, 0x45, 0xB1, 0xCE, 0xB6, 0x61, 0x63, 0xF3, 0x8F, 0xC9, 0x0B
.byte 0x79, 0x8D, 0x3E, 0x8F, 0xBE, 0xE2, 0x0F, 0x75, 0x07, 0x0D, 0x67, 0xE0, 0x6B, 0x73, 0x8A, 0xF2
.byte 0x06, 0x1D, 0x54, 0xF4, 0x7D, 0x99, 0xA5, 0x4C, 0x4F, 0x07, 0xAF, 0x42, 0x96, 0x79, 0x4E, 0x10
.byte 0x06, 0x8D, 0xA0, 0xC5, 0x6F, 0xAF, 0x3B, 0x77, 0xBD, 0xA2, 0x57, 0x29, 0x15, 0xE1, 0x1B, 0x1C
.byte 0xFF, 0x70, 0x10, 0x7D, 0x09, 0xB5, 0xC9, 0x58, 0xBC, 0x79, 0x9B, 0x53, 0xF3, 0xE9, 0x63, 0xF9
.byte 0x76, 0x04, 0xBF, 0xE6, 0xB4, 0xFA, 0x5D, 0x71, 0x9D, 0xB4, 0x9A, 0xB3, 0x96, 0xB6, 0xCF, 0x96
.byte 0x26, 0xDF, 0x13, 0x30, 0x94, 0xDD, 0x88, 0x51, 0x56, 0x24, 0xA4, 0x4A, 0x0D, 0x08, 0x44, 0x84
.byte 0x0D, 0x03, 0x6B, 0xC1, 0xFE, 0xC8, 0x32, 0x9B, 0x7D, 0xCD, 0x4E, 0x14, 0x84, 0x1D, 0xAA, 0xAB
.byte 0xFD, 0xBE, 0xDB, 0x92, 0x9B, 0x64, 0xE3, 0xF2, 0x88, 0x88, 0x3C, 0x96, 0x91, 0x80, 0x1A, 0x9E
.byte 0x84, 0x86, 0x5F, 0x82, 0x4F, 0x92, 0x1E, 0xCC, 0x5F, 0x6D, 0xE1, 0xE4, 0x8B, 0x8C, 0x8F, 0x88
.byte 0x4A, 0x6B, 0x1A, 0xE5, 0xCF, 0xFD, 0xD7, 0x58, 0x86, 0x14, 0xEE, 0x17, 0x94, 0x09, 0xB5, 0x19
.byte 0x8F, 0x14, 0x9C, 0xDE, 0xA6, 0xBA, 0xAB, 0x06, 0x28, 0x8D, 0xEB, 0xB3, 0x19, 0x7A, 0x3B, 0x63
.byte 0xE6, 0x56, 0x49, 0xB5, 0x54, 0x20, 0x0E, 0xDA, 0x34, 0xFC, 0xF1, 0xC9, 0x06, 0xA7, 0xE2, 0x96
.byte 0xBB, 0x7E, 0x74, 0x62, 0x39, 0x20, 0x69, 0x61, 0xAD, 0x54, 0x14, 0xC6, 0xCF, 0x50, 0x2A, 0xB5
.byte 0xA6, 0x73, 0x6B, 0xFA, 0x93, 0x79, 0xD5, 0xC8, 0x76, 0xC6, 0x92, 0x7C, 0x6D, 0x74, 0x12, 0x29
.byte 0xF3, 0x87, 0x8C, 0x2D, 0xA7, 0xF5, 0x8E, 0x55, 0x49, 0xA3, 0x1B, 0x18, 0xF3, 0x45, 0xCD, 0x9A
.byte 0xB8, 0x38, 0x95, 0x4C, 0xB1, 0x6A, 0x15, 0x28, 0x31, 0xA7, 0xA5, 0x9F, 0x1C, 0xB7, 0xC9, 0x0F
.byte 0x3F, 0x55, 0x3C, 0xE7, 0x4A, 0xCB, 0x3C, 0x93, 0x6E, 0x57, 0xAC, 0x62, 0x9D, 0x7A, 0xFC, 0x56
.byte 0xB2, 0x91, 0xA2, 0x64, 0xFC, 0xB7, 0x8C, 0x2D, 0x5F, 0x32, 0xCC, 0x7B, 0xE9, 0x95, 0x8B, 0x29
.byte 0xEB, 0xC8, 0x10, 0x35, 0x93, 0x4D, 0xC9, 0x01, 0xA5, 0x75, 0x63, 0x42, 0xEF, 0x60, 0x99, 0xA2
.byte 0xF1, 0x3C, 0x07, 0xED, 0xF4, 0x94, 0x1B, 0x53, 0xC6, 0xE8, 0xCE, 0xB0, 0x7E, 0x5A, 0xD9, 0x69
.byte 0x22, 0xEA, 0x9E, 0xB5, 0x38, 0x68, 0xB6, 0xDD, 0xDE, 0x1A, 0x20, 0xCE, 0x7A, 0xB9, 0x70, 0x6C
.byte 0xF5, 0x78, 0x5A, 0xE9, 0x0C, 0x75, 0x3D, 0xD2, 0x5D, 0x0C, 0x83, 0xDC, 0x66, 0x5D, 0x45, 0x88
.byte 0x47, 0xE4, 0x3D, 0x80, 0x4C, 0xF4, 0x5D, 0x2A, 0x0E, 0x7E, 0xF8, 0x89, 0x38, 0x69, 0xF6, 0x2E
.byte 0xE1, 0x50, 0x18, 0xED, 0xC6, 0x55, 0xC0, 0x24, 0x61, 0x43, 0x00, 0xC7, 0xA0, 0x45, 0x50, 0xE8
.byte 0x2A, 0x8D, 0x69, 0x76, 0x81, 0xC7, 0xA1, 0x90, 0x45, 0x9A, 0x1A, 0x7E, 0x04, 0x10, 0xAC, 0xE5
.byte 0x61, 0xC5, 0xD3, 0x27, 0x1B, 0x94, 0x4C, 0x7C, 0xD8, 0x4C, 0x44, 0x79, 0x92, 0x94, 0x61, 0xBC
.byte 0x22, 0xCA, 0x33, 0xA3, 0x92, 0xD5, 0x34, 0xD7, 0x6F, 0x4F, 0x55, 0x73, 0x5F, 0x02, 0x59, 0xC1
.byte 0xC7, 0x2D, 0xE9, 0xE2, 0xC1, 0x35, 0x5F, 0x99, 0x82, 0xA4, 0x12, 0x14, 0x39, 0x74, 0xD1, 0x5B
.byte 0x3F, 0x05, 0xFF, 0xD1, 0xDA, 0x33, 0xA9, 0x4A, 0x82, 0xFF, 0xBE, 0xE2, 0x02, 0x18, 0xA4, 0xCA
.byte 0x45, 0x8D, 0xAD, 0x07, 0xC2, 0x0C, 0xA0, 0x45, 0xB1, 0xB3, 0x59, 0xEA, 0x28, 0x2B, 0x45, 0x67
.byte 0x31, 0x44, 0x39, 0x0C, 0x78, 0xE3, 0x57, 0xFB, 0xE2, 0x15, 0xDE, 0xE4, 0x2E, 0x82, 0xAE, 0x74
.byte 0x0F, 0x5B, 0x7B, 0xD2, 0x68, 0x1C, 0x17, 0x19, 0xCF, 0x71, 0x04, 0xF8, 0x9D, 0x49, 0x60, 0xCE
.byte 0x8E, 0x99, 0xDA, 0x07, 0x7C, 0x31, 0x02, 0x5F, 0x47, 0xE1, 0x43, 0x75, 0x63, 0xF2, 0xE9, 0x72
.byte 0x4D, 0x65, 0x44, 0xB6, 0x81, 0x5C, 0xCF, 0x51, 0xCD, 0xD3, 0x49, 0x6A, 0x1D, 0xA9, 0x39, 0xAC
.byte 0x43, 0x13, 0xB3, 0xC0, 0x45, 0xB6, 0x1F, 0x8D, 0x97, 0x63, 0x03, 0xFB, 0x55, 0xED, 0x6D, 0xA3
.byte 0x52, 0xB2, 0x59, 0xD3, 0x0F, 0x29, 0x24, 0xDC, 0xFD, 0x6E, 0x47, 0x1B, 0x18, 0x80, 0xC7, 0x5B
.byte 0x94, 0x7B, 0x1C, 0xDA, 0x32, 0x3C, 0x67, 0xCA, 0x9F, 0x6A, 0xC5, 0xF5, 0x58, 0x33, 0x99, 0xAA
.byte 0xE6, 0xF3, 0x7E, 0xF5, 0x1C, 0xA3, 0xD2, 0x1A, 0x11, 0x1A, 0x35, 0x29, 0x9B, 0xFD, 0x85, 0x30
.byte 0x78, 0xA2, 0x0A, 0xAB, 0xDE, 0x72, 0x76, 0x7E, 0xDD, 0x3B, 0x74, 0x35, 0x6F, 0x0D, 0xDF, 0x55
.byte 0x00, 0x5D, 0x4B, 0x1D, 0x00, 0x1E, 0x37, 0x12, 0x38, 0x6D, 0x3C, 0xD3, 0x6A, 0xC2, 0x03, 0xE3
.byte 0x64, 0x0E, 0x8E, 0x43, 0x80, 0x05, 0xC1, 0x5D, 0x40, 0x36, 0x93, 0xB0, 0x43, 0x73, 0x06, 0x44
.byte 0xD1, 0x52, 0x61, 0xD2, 0x70, 0x99, 0xE4, 0xA8, 0x06, 0x21, 0x7C, 0x71, 0xE3, 0x80, 0x54, 0x48
.byte 0x8E, 0xE3, 0x8B, 0x0F, 0xE8, 0x4D, 0x6D, 0x29, 0x83, 0x00, 0xD9, 0xC6, 0x73, 0xE0, 0x0B, 0x45
.byte 0x32, 0x6D, 0x17, 0xA2, 0x06, 0xFB, 0x4B, 0x0D, 0x1D, 0xC7, 0x7E, 0x00, 0x48, 0xD2, 0x48, 0xD6
.byte 0xB6, 0xD3, 0xE5, 0x9E, 0x21, 0x52, 0xC7, 0xA4, 0x52, 0xA1, 0x6B, 0xC6, 0x81, 0x76, 0x0B, 0xB3
.byte 0xE3, 0x22, 0x56, 0xEA, 0x1E, 0xA1, 0xF8, 0x3B, 0x69, 0x76, 0x3C, 0xB1, 0x49, 0x84, 0x87, 0xFF
.byte 0x58, 0x6D, 0x9E, 0x79, 0xBF, 0x65, 0x1E, 0x12, 0x07, 0x89, 0xD9, 0x88, 0xFF, 0xE4, 0x3C, 0xE3
.byte 0x07, 0x92, 0xCD, 0x26, 0x33, 0xC5, 0x62, 0x9D, 0x3C, 0x9E, 0x4E, 0x86, 0x23, 0xD6, 0x86, 0x7C
.byte 0x43, 0x24, 0xF6, 0x02, 0x8A, 0x15, 0x15, 0x91, 0x9E, 0xEE, 0x19, 0x9E, 0xD3, 0x56, 0x81, 0xDB
.byte 0xE8, 0x4F, 0x01, 0x1C, 0x14, 0x64, 0xB9, 0x51, 0x03, 0x07, 0xD7, 0x27, 0xDD, 0x5D, 0xA4, 0x21
.byte 0x82, 0x9A, 0x24, 0x0C, 0xAF, 0x39, 0x9D, 0x4E, 0x28, 0xB7, 0xEC, 0xFB, 0x0D, 0x6D, 0xD6, 0xF6
.byte 0xBC, 0xD8, 0x12, 0xD1, 0x3C, 0xCB, 0x23, 0x40, 0xD3, 0xFB, 0x67, 0xB1, 0x58, 0x0B, 0xD2, 0xDA
.byte 0xA6, 0xF6, 0xE7, 0x56, 0x30, 0x85, 0xA4, 0x58, 0x3C, 0x90, 0x54, 0x4A, 0xFE, 0x2A, 0x41, 0xBA
.byte 0x03, 0x53, 0x8C, 0x3F, 0x1F, 0xAF, 0x7F, 0xF2, 0xAA, 0xE7, 0xA3, 0x03, 0xF2, 0x76, 0xDE, 0x98
.byte 0x6C, 0xC6, 0xEE, 0x9D, 0x4B, 0x93, 0xF5, 0x88, 0x23, 0x49, 0xD2, 0x22, 0x74, 0x14, 0xDD, 0x77
.byte 0x67, 0x69, 0xB7, 0x86, 0x19, 0x37, 0x78, 0xC4, 0x1E, 0x1C, 0xC8, 0x11, 0x92, 0xA7, 0xAA, 0xFF
.byte 0x6D, 0x99, 0x9D, 0xB8, 0x2C, 0x93, 0x40, 0x50, 0xDC, 0x13, 0x72, 0x51, 0x27, 0x4F, 0xC8, 0x8F
.byte 0xB8, 0x80, 0x15, 0xD2, 0xB7, 0x8E, 0x97, 0xD6, 0xAB, 0x5F, 0xE7, 0x3E, 0x06, 0x91, 0x3E, 0x74
.byte 0x2A, 0xDB, 0x2D, 0x57, 0x6E, 0x6D, 0xA7, 0x4B, 0x81, 0x19, 0x9C, 0xA9, 0x68, 0x65, 0x38, 0x21
.byte 0xE6, 0x4E, 0xF4, 0x9D, 0xDD, 0x8B, 0x74, 0x89, 0xEB, 0x5C, 0xC7, 0xF2, 0xED, 0x05, 0x66, 0x18
.byte 0xE1, 0x93, 0x6F, 0x4F, 0x01, 0x17, 0x9A, 0x83, 0x30, 0x37, 0x2D, 0x99, 0x9C, 0x66, 0xBB, 0x83
.byte 0xB4, 0xAF, 0x21, 0x92, 0x3B, 0x95, 0x1B, 0x26, 0xF1, 0xE3, 0x19, 0xDF, 0xE8, 0x7F, 0xF8, 0xC9
.byte 0x13, 0x68, 0x19, 0x15, 0x7F, 0xB3, 0x98, 0xB0, 0xEB, 0xC6, 0x49, 0x88, 0x2C, 0x05, 0x0B, 0xE1
.byte 0xB4, 0x2C, 0x73, 0xF0, 0xC1, 0x8F, 0x17, 0xB3, 0x72, 0x30, 0x93, 0x5B, 0xAF, 0x8B, 0x25, 0xC3
.byte 0xF3, 0x3E, 0xD8, 0x73, 0xF2, 0x71, 0x23, 0xDD, 0x37, 0x6C, 0x65, 0x64, 0x72, 0x70, 0x45, 0x26
.byte 0x9C, 0xB9, 0x17, 0x5E, 0x48, 0x2E, 0x12, 0xBB, 0x5E, 0xA5, 0x17, 0x0E, 0x30, 0x3C, 0xD1, 0x24
.byte 0x7B, 0xAA, 0x97, 0x6D, 0x1B, 0xBA, 0x4A, 0x53, 0x27, 0xB0, 0xB7, 0x99, 0x21, 0xFD, 0xC0, 0xBE
.byte 0xB6, 0xD8, 0x1C, 0xFF, 0x06, 0x2E, 0xBB, 0x64, 0xD3, 0xD2, 0x72, 0x04, 0x0F, 0x44, 0x28, 0x8A
.byte 0xEE, 0xC0, 0xF7, 0x0A, 0x7B, 0x42, 0x5E, 0xA3, 0xF3, 0x16, 0x3D, 0x14, 0x13, 0xFD, 0xD2, 0xC9
.byte 0xD6, 0xEF, 0xC9, 0xDC, 0x1E, 0x84, 0x40, 0xF2, 0x57, 0xB3, 0xF6, 0x66, 0xF7, 0x1F, 0xF0, 0xE6
.byte 0xE0, 0xE8, 0xF1, 0x5B, 0x2B, 0x4F, 0xFE, 0x1E, 0x65, 0x3B, 0x33, 0x78, 0x39, 0x06, 0x42, 0x0F
.byte 0xF6, 0x0B, 0xEC, 0x14, 0x90, 0x2C, 0x07, 0xE7, 0xE0, 0xFE, 0x4D, 0xD8, 0x1D, 0x3E, 0xBE, 0xFE
.byte 0x27, 0xB0, 0x59, 0x52, 0xFF, 0x58, 0x71, 0x65, 0x94, 0xA5, 0xDD, 0xCD, 0xAC, 0x20, 0xDD, 0xA2
.byte 0x2C, 0xC9, 0xB7, 0xBC, 0xF6, 0xBE, 0xA4, 0xD7, 0xBC, 0xF1, 0xAF, 0xDA, 0x30, 0x6E, 0xD8, 0x57
.byte 0x1E, 0x32, 0xAA, 0x1E, 0x8A, 0x1B, 0x83, 0x1E, 0xC1, 0x61, 0xEC, 0x6D, 0x81, 0xCA, 0x0F, 0xAD
.byte 0x94, 0xC6, 0x6A, 0x8B, 0x85, 0x0E, 0x62, 0x42, 0x00, 0x12, 0x1C, 0x30, 0x80, 0xF5, 0x88, 0x9F
.byte 0x27, 0x32, 0xBD, 0xB1, 0x4E, 0x40, 0xD0, 0x0F, 0xA1, 0xBC, 0x7C, 0x23, 0x87, 0x8C, 0xD1, 0x1B
.byte 0x53, 0x3B, 0xA6, 0xD8, 0x4A, 0x09, 0x1A, 0x4A, 0x1B, 0x37, 0x7B, 0x9B, 0x2C, 0x03, 0x3A, 0x53
.byte 0x36, 0xF7, 0x05, 0x84, 0x38, 0xD5, 0x94, 0xD9, 0x92, 0x11, 0xFD, 0x19, 0x9D, 0xCE, 0x35, 0xF1
.byte 0x0A, 0xDC, 0xCA, 0x54, 0xE5, 0xE5, 0x9F, 0x01, 0x1C, 0x1B, 0x9C, 0x49, 0x1E, 0xD7, 0x9D, 0x55
.byte 0xCF, 0xA2, 0xD9, 0x07, 0x78, 0x6E, 0xE1, 0x0B, 0x7F, 0xDF, 0x25, 0x1C, 0xAD, 0x5A, 0x0E, 0xB7
.byte 0x37, 0xD8, 0x0C, 0x1C, 0xBD, 0xAB, 0x1E, 0xDA, 0xC6, 0xBA, 0x23, 0xE5, 0x92, 0xC0, 0x3A, 0x61
.byte 0x63, 0x14, 0x69, 0xDB, 0x82, 0x4B, 0xE6, 0x02, 0x2A, 0x0B, 0x1F, 0xD8, 0x66, 0x2D, 0x90, 0x9D
.byte 0x05, 0x9C, 0xBA, 0xC3, 0x48, 0xD8, 0x9D, 0x0E, 0x93, 0xC1, 0xF4, 0x25, 0x81, 0x2F, 0x87, 0xE5
.byte 0x44, 0xF1, 0xC0, 0xC7, 0x3D, 0xA7, 0xC9, 0x68, 0xB3, 0xE8, 0x40, 0x19, 0x15, 0xD0, 0xB7, 0x1B
.byte 0x6C, 0x71, 0xDE, 0xB4, 0x4A, 0x7C, 0xC3, 0xDD, 0x3D, 0xB8, 0x03, 0xBF, 0xE8, 0x8A, 0xA4, 0x2C
.byte 0x7C, 0x64, 0xF3, 0xB9, 0x0C, 0xBD, 0x21, 0xBF, 0xA5, 0x62, 0xD8, 0xBB, 0x32, 0x8F, 0xD6, 0x9F
.byte 0x01, 0xB5, 0x54, 0x4B, 0x31, 0x18, 0x29, 0x6E, 0xD1, 0x2C, 0x2D, 0xB9, 0xB7, 0xD1, 0xE6, 0x34
.byte 0x36, 0xDA, 0xED, 0x43, 0x97, 0x0F, 0x02, 0x3D, 0x72, 0xDB, 0xF8, 0xA5, 0x6B, 0xCF, 0x45, 0x6C
.byte 0x84, 0x99, 0xB8, 0xB5, 0xB2, 0xE2, 0x23, 0x84, 0x0E, 0x51, 0x3D, 0xC6, 0x23, 0x24, 0xFA, 0x5A
.byte 0xFE, 0xE8, 0x9D, 0x96, 0xF8, 0x9F, 0xD3, 0x6A, 0x7B, 0xCC, 0x0F, 0xE6, 0x9B, 0x54, 0x53, 0x1F
.byte 0xEE, 0x0C, 0xD5, 0xA1, 0xEE, 0xF9, 0x25, 0xFC, 0x4A, 0x63, 0xC3, 0x6E, 0x87, 0xBD, 0xC8, 0x86
.byte 0xA6, 0x65, 0x1C, 0x9E, 0x05, 0xF0, 0x08, 0x81, 0xBC, 0x18, 0x67, 0x58, 0x6D, 0xBB, 0x77, 0x5B
.byte 0xC7, 0x4D, 0xFD, 0xB6, 0x46, 0x22, 0xB2, 0x91, 0x85, 0x76, 0x00, 0x0D, 0x34, 0xC8, 0x93, 0xDA
.byte 0x2E, 0xAF, 0x78, 0x34, 0x9F, 0x81, 0xB5, 0x5C, 0x9A, 0x1D, 0xB4, 0x07, 0xD9, 0x2C, 0x63, 0xA0
.byte 0x79, 0x61, 0x56, 0xC0, 0x83, 0x09, 0x51, 0x09, 0x80, 0x52, 0x17, 0xB4, 0x1A, 0xAA, 0x8E, 0x49
.byte 0x5A, 0x07, 0x7D, 0xFA, 0x89, 0x33, 0x56, 0x24, 0x50, 0x0A, 0x2C, 0x29, 0x36, 0x90, 0xCA, 0xB0
.byte 0xF1, 0x21, 0x70, 0x74, 0x2B, 0xC2, 0x7E, 0xAB, 0x14, 0x95, 0x60, 0x2F, 0x40, 0xEF, 0x78, 0x9A
.byte 0xF7, 0xF6, 0x95, 0x81, 0x29, 0xEB, 0xA5, 0x79, 0xF6, 0xD1, 0xA3, 0x2D, 0x61, 0x6E, 0xDD, 0x52
.byte 0x90, 0x4E, 0xC7, 0xBB, 0x11, 0x46, 0x67, 0x25, 0xDC, 0xC8, 0x55, 0x1C, 0xB7, 0xCD, 0xB7, 0xAE
.byte 0xC4, 0x4C, 0x2F, 0xED, 0x38, 0xD5, 0x67, 0x2E, 0xA6, 0x0A, 0x5B, 0x08, 0x79, 0x38, 0x5B, 0x09
.byte 0x87, 0x23, 0xC4, 0x98, 0x69, 0x2C, 0xBE, 0x46, 0xF4, 0x13, 0x63, 0xAC, 0xE1, 0x1A, 0x5B, 0xA5
.byte 0x67, 0x8A, 0x93, 0x9F, 0x60, 0xFA, 0xCD, 0x07, 0x04, 0x29, 0x0F, 0x7D, 0x62, 0x6B, 0x87, 0xE9
.byte 0x8E, 0x4C, 0x82, 0xF8, 0x78, 0x40, 0x3F, 0x6D, 0x54, 0xA2, 0x19, 0x36, 0xBC, 0x74, 0xDC, 0x24
.byte 0xFF, 0x6F, 0xC3, 0x5F, 0x69, 0x91, 0x66, 0x6E, 0xBB, 0x76, 0xEC, 0x1D, 0xE1, 0x73, 0x07, 0x70
.byte 0xBF, 0x89, 0x69, 0x38, 0xCA, 0xA8, 0xA5, 0x1E, 0x4A, 0xBF, 0x55, 0x07, 0x34, 0x31, 0x2B, 0x34
.byte 0xA0, 0xEF, 0x93, 0x0A, 0x81, 0xFA, 0x79, 0x3C, 0x71, 0x65, 0x5A, 0x52, 0xD9, 0x61, 0xC3, 0x99
.byte 0xEB, 0x2C, 0xD1, 0xB5, 0xD5, 0x77, 0xD4, 0x20, 0x37, 0x29, 0x27, 0x6B, 0x5A, 0x53, 0x9F, 0xFB
.byte 0x43, 0x33, 0x06, 0xC4, 0x2D, 0x7F, 0x01, 0x9F, 0xE4, 0x5C, 0xF1, 0xBE, 0xBD, 0xB5, 0x57, 0xA9
.byte 0xE2, 0x29, 0x5E, 0xB7, 0xA1, 0x32, 0xD7, 0xD8, 0x5C, 0xFF, 0x43, 0xB6, 0x53, 0xE3, 0xB2, 0x96
/verify/lxp32/src/firmware/test019.asm
0,0 → 1,35
/*
* This test verifies non-returnable interrupt handling
* Note: "iret" is never called here
*/
 
lc r100, 0x10000000 // test result output pointer
lcs r101, halt
lc r102, failure
lc r103, 0x20000000 // timer: number of pulses (0xFFFFFFFF - infinite)
lc r104, 0x20000004 // timer: delay between pulses (in cycles)
lcs r105, success
lcs r32, 0 // counter
lcs iv0, test_loop@1 // set IRF to mark the interrupt as non-returnable
mov cr, 1 // enable timer interrupt
sw r104, 100 // delay between interrupts
sw r103, 100 // generate 100 interrupts
hlt // wait for a non-returnable interrupt
test_loop:
add r32, r32, 1
cjmpuge r105, r32, 100 // success
hlt // wait for a non-returnable interrupt
failure:
sw r100, 2 // should never reach here
jmp r101 // halt
success:
sw r100, 1 // success
halt:
hlt
jmp r101 // halt
/verify/lxp32/src/firmware/test020.asm
0,0 → 1,39
/*
* Check that there are no pipeline hazards
*/
 
lc r100, 0x10000000 // test result output pointer
lcs r101, halt
lcs r102, failure
lcs r103, success
add r0, 100, 50 // r0:=150
add r1, r0, 3 // r1:=153, potential RAW hazard
mul r2, r1, 109 // r2:=16677, potential RAW hazard
mul r3, r2, r0 // r3:=2501550, potential RAW hazard
sub r4, r3, 15 // r4:=2501535, potential RAW hazard
mul r5, 50, 117 // r2:=5850
sub r5, 100, 9 // r2:=91, overwrites previous result, potential WAW hazard
lc r6, 1800
mul r7, r6, 49 // r7:=88200, potential RAW hazard
mov r6, 1 // r6:=1, potential WAR hazard
lc r0, 2501535
cjmpne r102, r4, r0 // failure
cjmpne r102, r5, 91 // failure
lcs r0, 88200
cjmpne r102, r7, r0 // failure
jmp r103 // success
failure:
sw r100, 2
jmp r101 // halt
success:
sw r100, 1 // success
halt:
hlt
jmp r101 // halt
/verify/lxp32/src/make/sources.make
22,6 → 22,11
$(LXP32_DIR)/lxp32_icache.vhd\
$(LXP32_DIR)/lxp32c_top.vhd
 
# Common package
 
COMMON_PKG_DIR=../../../common_pkg
COMMON_SRC=$(COMMON_PKG_DIR)/common_pkg.vhd $(COMMON_PKG_DIR)/common_pkg_body.vhd
 
# Platform RTL
 
PLATFORM_DIR=../../src/platform
39,9 → 44,7
 
COMMON_PKG_DIR=../../../common_pkg
TB_DIR=../../src/tb
TB_SRC=$(COMMON_PKG_DIR)/common_pkg.vhd\
$(COMMON_PKG_DIR)/common_pkg_body.vhd\
$(TB_DIR)/tb_pkg.vhd\
TB_SRC=$(TB_DIR)/tb_pkg.vhd\
$(TB_DIR)/tb_pkg_body.vhd\
$(TB_DIR)/monitor.vhd\
$(TB_DIR)/tb.vhd
66,7 → 69,11
test013.ram\
test014.ram\
test015.ram\
test016.ram
test016.ram\
test017.ram\
test018.ram\
test019.ram\
test020.ram
 
# LXP32 assembler executable
 
/verify/lxp32/src/platform/dbus_monitor.vhd
47,6 → 47,9
signal prbs: std_logic;
signal cycle: std_logic:='0';
 
signal cyc_ff: std_logic:='0';
signal ack_ff: std_logic:='0';
 
begin
 
-- Manage throttling
88,8 → 91,27
wbm_adr_o<=wbs_adr_i;
wbm_dat_o<=wbs_dat_i;
 
assert not rising_edge(clk_i) or wbm_ack_i='0' or (wbs_cyc_i and (not prbs or cycle))='1'
report "DBUS error: ACK asserted without CYC"
severity failure;
-- Check handshake correctness
 
process (clk_i) is
begin
if rising_edge(clk_i) then
if rst_i='1' then
cyc_ff<='0';
ack_ff<='0';
else
cyc_ff<=wbs_cyc_i;
ack_ff<=wbm_ack_i;
assert wbm_ack_i='0' or (wbs_cyc_i and (not prbs or cycle))='1'
report "DBUS error: ACK asserted without CYC"
severity failure;
assert not (wbs_cyc_i='0' and cyc_ff='1' and ack_ff/='1')
report "DBUS error: cycle terminated prematurely"
severity failure;
end if;
end if;
end process;
 
end architecture;
/verify/lxp32/src/platform/generic_dpram.vhd
49,7 → 49,7
signal ram: ram_type;
 
attribute syn_ramstyle: string;
attribute syn_ramstyle of ram: signal is "block_ram,no_rw_check";
attribute syn_ramstyle of ram: signal is "no_rw_check";
attribute ram_style: string; -- for Xilinx
attribute ram_style of ram: signal is "block";
 
76,7 → 76,11
ram(to_integer(unsigned(addra_i)))<=da_i;
da_o<=(others=>'-');
else
da_o<=ram(to_integer(to_01(unsigned(addra_i))));
if is_x(addra_i) then
da_o<=(others=>'X');
else
da_o<=ram(to_integer(unsigned(addra_i)));
end if;
end if;
end if;
end if;
92,7 → 96,11
ram(to_integer(unsigned(addra_i)))<=da_i;
da_o<=da_i;
else
da_o<=ram(to_integer(to_01(unsigned(addra_i))));
if is_x(addra_i) then
da_o<=(others=>'X');
else
da_o<=ram(to_integer(unsigned(addra_i)));
end if;
end if;
end if;
end if;
107,7 → 115,11
if wea_i='1' then
ram(to_integer(unsigned(addra_i)))<=da_i;
end if;
da_o<=ram(to_integer(to_01(unsigned(addra_i))));
if is_x(addra_i) then
da_o<=(others=>'X');
else
da_o<=ram(to_integer(unsigned(addra_i)));
end if;
end if;
end if;
end process;
121,7 → 133,11
if wea_i='1' then
ram(to_integer(unsigned(addra_i)))<=da_i;
else
da_o<=ram(to_integer(to_01(unsigned(addra_i))));
if is_x(addra_i) then
da_o<=(others=>'X');
else
da_o<=ram(to_integer(unsigned(addra_i)));
end if;
end if;
end if;
end if;
134,7 → 150,11
begin
if rising_edge(clkb_i) then
if ceb_i='1' then
db_o<=ram(to_integer(to_01(unsigned(addrb_i))));
if is_x(addrb_i) then
db_o<=(others=>'X');
else
db_o<=ram(to_integer(unsigned(addrb_i)));
end if;
end if;
end if;
end process;
/verify/lxp32/src/platform/platform.vhd
17,6 → 17,8
 
entity platform is
generic(
CPU_DBUS_RMW: boolean;
CPU_MUL_ARCH: string;
MODEL_LXP32C: boolean;
THROTTLE_DBUS: boolean;
THROTTLE_IBUS: boolean
178,9 → 180,9
gen_lxp32u: if not MODEL_LXP32C generate
lxp32u_top_inst: entity work.lxp32u_top(rtl)
generic map(
DBUS_RMW=>false,
DBUS_RMW=>CPU_DBUS_RMW,
DIVIDER_EN=>true,
MUL_ARCH=>"dsp",
MUL_ARCH=>CPU_MUL_ARCH,
START_ADDR=>(others=>'0')
)
port map(
208,11 → 210,11
gen_lxp32c: if MODEL_LXP32C generate
lxp32c_top_inst: entity work.lxp32c_top(rtl)
generic map(
DBUS_RMW=>false,
DBUS_RMW=>CPU_DBUS_RMW,
DIVIDER_EN=>true,
IBUS_BURST_SIZE=>16,
IBUS_PREFETCH_SIZE=>32,
MUL_ARCH=>"dsp",
MUL_ARCH=>CPU_MUL_ARCH,
START_ADDR=>(others=>'0')
)
port map(
/verify/lxp32/src/platform/program_ram.vhd
16,6 → 16,8
library ieee;
use ieee.std_logic_1164.all;
 
use work.common_pkg.all;
 
entity program_ram is
generic(
THROTTLE: boolean
91,7 → 93,7
process (clk_i) is
begin
if rising_edge(clk_i) then
ack_read<=wbs_cyc_i and wbs_stb_i and not wbs_we_i;
ack_read<=wbs_cyc_i and wbs_stb_i and not wbs_we_i and not ack_read;
end if;
end process;
 
102,6 → 104,16
 
-- Low Latency Interface (with optional pseudo-random throttling)
 
process (clk_i) is
begin
if rising_edge(clk_i) then
assert lli_re_i='0' or lli_adr_i(lli_adr_i'high downto 14)=X"0000"
report "Attempted to fetch instruction from a non-existent address 0x"&
hex_string(lli_adr_i&"00")
severity failure;
end if;
end process;
 
gen_throttling: if THROTTLE generate
throttle_inst: entity work.scrambler(rtl)
generic map(TAP1=>9,TAP2=>11)
/verify/lxp32/src/tb/tb.vhd
8,6 → 8,8
-- Simulates LXP32 test platform, verifies results.
--
-- Parameters:
-- CPU_DBUS_RMW: DBUS_RMW CPU generic
-- CPU_MUL_ARCH: MUL_ARCH CPU generic
-- MODEL_LXP32C: when true, simulates LXP32C variant (with
-- instruction cache), otherwise LXP32U
-- TEST_CASE: If non-empty, selects a test case to run.
29,6 → 31,8
 
entity tb is
generic(
CPU_DBUS_RMW: boolean:=false;
CPU_MUL_ARCH: string:="dsp";
MODEL_LXP32C: boolean:=true;
TEST_CASE: string:="";
THROTTLE_DBUS: boolean:=true;
55,6 → 59,8
 
dut: entity work.platform(rtl)
generic map(
CPU_DBUS_RMW=>CPU_DBUS_RMW,
CPU_MUL_ARCH=>CPU_MUL_ARCH,
MODEL_LXP32C=>MODEL_LXP32C,
THROTTLE_DBUS=>THROTTLE_DBUS,
THROTTLE_IBUS=>THROTTLE_IBUS
125,6 → 131,10
run_test("test014.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out);
run_test("test015.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out);
run_test("test016.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out);
run_test("test017.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out);
run_test("test018.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out);
run_test("test019.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out);
run_test("test020.ram",clk,globals,soc_wbs_in,soc_wbs_out,monitor_out);
else
run_test(TEST_CASE,clk,globals,soc_wbs_in,soc_wbs_out,monitor_out);
end if;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.