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

Subversion Repositories ion

[/] [ion/] [trunk/] [doc/] [src/] [tex/] [usage.tex] - Diff between revs 210 and 221

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 210 Rev 221
Line 7... Line 7...
The core is split in three main modules:
The core is split in three main modules:
 
 
\begin{enumerate}
\begin{enumerate}
    \item The CPU (mips\_cpu.vhdl).
    \item The CPU (mips\_cpu.vhdl).
    \item The cache+memory controller (mips\_cache.vhdl).
    \item The cache+memory controller (mips\_cache.vhdl).
    \item An 'MCU' entity which combines CPU+Cache (mips\_mpu.vhdl).
    \item A 'SoC' entity which combines CPU+Cache (mips\_soc.vhdl).
\end{enumerate}
\end{enumerate}
 
 
The entity you should use in your projects is the MCU module. The project
The entity you should use in your projects is the SoC module. The project
includes a 'hardware demo' built around this module (see section
includes a 'hardware demo' built around this module (see section
~\ref{pregenerated_demo}) which can be used as an usage example.\\
~\ref{pregenerated_demo}) which is meant as an usage example.\\
 
 
The main modules are briefly described in the following subsections.
 
 
 
 
\section{Bootstrap Code}
 
\label{bootstrap_code}
 
 
\section{MCU Module}
Though the core is meant to run mostly from off-chip memory, the current version
\label{mcu_module}
of the SoC module includes a small ROM implemented as FPGA BRAM and called
 
'bootstrap BRAM'. In the current version of the core, this BRAM can be loaded
 
with arbitrary code and its size can be configured by using generics, but it
 
can't be removed from the SoC. Even though the memory map can be modified to
 
boot from external FLASH and not use a BRAM at all, a BRAM will still be
 
inferred within the SoC -- subsequent versions will fix this.
 
 
 
As can be seen in table~\ref{tab_soc_memory_map}, the internal BRAM is mirrored
 
all over a wide area starting at \texttt{0xb8000000}. In practice, this means
 
the BRAM will be mapped at the CPU reset address (\texttt{0xbfc00000}) and thus
 
the bootstrap code should be placed there.
 
Unless the bootstrap BRAM is very small, it will span over the interrupt vector
 
address too (\texttt{0xbfc00180}).
 
 
 
For example, the 'Adventure' demo included with the project uses bootstrap
 
code included in file \texttt{/src/common/bootstrap.s}. This bootstrap code
 
is fairly incomplete (interrupt response code is mostly a stub) yet it's enough
 
to boot most applications.
 
Note that the C startup code, which deals with things like initializing the
 
static variables on the data segment, etc. is not part of this bootstrap code.
 
It can be found in file \texttt{/src/common/c\_startup.s}
 
 
 
So, in short, the code loaded onto the startup BRAM should include the most
 
basic system initialization (cache initialization at least) and the entry point
 
for the interrupt response code; plus a jump to the main program entry address.
 
 
 
Anyone trying to build some application on this core is advised to use the code
 
samples as starting points, specially the makefiles.
 
 
 
 
 
\subsection{Loading Bootstrap Code on the SoC Module}
 
\label{loading_bootstrap_code}
 
 
 
Once the code that is to be loaded on the bootstrap BRAM has been built, you
 
need to load it onto the bootstrap BRAM within the FPGA.
 
 
 
As you probably already know, there are several possible ways to deal with this
 
and most of them involve using \emph{'Memory Initialization Files'} of
 
some sort. This project is different.
 
 
 
So far, this project does not include any support for using IMF
 
files of any kind. Instead, the bootstrap BRAM is inferred and initialized
 
using regular VHDL constructs and a constant passed to the SoC module as a
 
generic.
 
 
 
This scheme has a big drawback: every time the object code within the FPGA
 
changes, the whole synthesis needs to be re-run. This drawback is manageable
 
as long as the core is not used in any big project or if the bootstrap code
 
does not change often.
 
 
The MCU module main purpose is to encapsulate the somewhat complex
On the other hand, I see some big advantages in using regular BRAM inference in
interconnection between the CPU and the Cache module.
this stage of the project:
 
 
If some project demands that some piece of hardware be directly connected to the
 
CPU, bypassing the cache, this is where it should be -- an MMU comes to mind.
 
 
 
Any peripherals deemed common enough that they will be present in all projects
 
might be placed in the MCU module too -- after all, the MCU name has been chosen
 
to imply that 'bundling together' of a CPU and a bunch of peripherals.
 
 
 
In the current version of the MCU module, there is only a peripheral included in
 
it -- a hardwired UART module. There is no penalty for placing peripherals
 
ouside the MCU module, so there is no incentive to place them inside, thus
 
making the interface more complex. This is an implementation option of yours.\\
 
 
 
\subsection{MCU Ports}
 
\label{mcu_ports}
 
 
 
\begin{figure}[h]
 
\makebox[\textwidth]{\framebox[9cm]{\rule{0pt}{9cm}
 
\includegraphics[width=8cm]{img/mpu_symbol.png}}}
 
\caption{MPU module interface\label{mpu_symbol}}
 
\end{figure}
 
 
 
\begin{table}[h]
 
\caption{MCU module interface ports}
 
\begin{tabularx}{\textwidth}{ lll|X }
 
\toprule
 
Name & Type & Width & Description \\
 
\midrule
 
clk                 & in    & 1  & Clock input, active rising edge. \\
 
reset               & in    & 1  & Synchronous global reset. \\
 
\midrule
 
sram\_address       & out   & 16 & Memory word address (bit 0 absent). \\
 
sram\_data\_wr      & out   & 16 & Memory write data. Only valid when one of the \\
 
                    &       &    & memory byte write enable outputs is active.\\
 
sram\_data\_rd      & in    & 16 & Memory read data. Latched when xxx. \\
 
sram\_byte\_we\_n   & out   & 2  & Memory byte write enable, active low.  \\
 
                    &       &    & (0) enables the low byte (7 downto 0) \\
 
                    &       &    & (1) enables the high byte (15 downto 8). \\
 
\midrule
 
io\_rd\_addr        & out   & 30 & I/O port read address (bits 1..0 absent). \\
 
                    &       &    & Only valid when io\_rd\_vma is high. \\
 
io\_wr\_addr        & out   & 30 & I/O port write address (bits 1..0 absent). \\
 
io\_wr\_data        & out   & 32 & I/O write data.  Only valid when one of the \\
 
                    &       &    & i/o byte write enable outputs is active.\\
 
io\_rd\_data        & in    & 32 & I/O read data. Latched when xxx. \\
 
io\_byte\_we        & out   & 4  & I/O byte write enable, active high. \\
 
                    &       &    & (0) enables the low byte (7 downto 0) \\
 
                    &       &    & (3) enables the high byte (31 downto 24). \\
 
io\_rd\_vma         & out   & 1  & Active high on i/o read cycles. \\
 
\midrule
 
uart\_rxd           & in    & 1  & RxD input to internal UART. \\
 
uart\_txd           & out   & 1  & TxD output from internal UART. \\
 
\midrule
 
interrupt           & in    & 8  & Interrupt request inputs, active high. \\
 
\bottomrule
 
\end{tabularx}
 
\end{table}
 
 
 
As you can see in figure~\ref{mpu_symbol} (symbol generated by Xilinx ISE),
 
the MCU has the following interfaces:
 
 
 
\begin{enumerate}
\begin{enumerate}
    \item Interface to external static asynchronous memory (SRAM, FLASH...).
\item The whole scheme is totally vendor agnostic.
    \item Interface to on-chip peripherals.
\item Object code embedded on VHDL constants can very easily be used in both simulation and synthesis.
    \item Interrupt inputs.
 
\end{enumerate}
\end{enumerate}
 
 
These interfaces will be explained in the following subsections. The top module
So, whatever object code is to be used to initialize the SoC bootstrap BRAM has
for the demo supplied with the project (c2sb\_demo.vhdl) will be used for
to be passed to the SoC module instance as a generic constant (see section
illustration.
~\ref{soc_generics}). The constant must be of type \texttt{t\_obj\_code}, which
 
is defined in package \emph{mips\_pkg}.
\emph{NOTE}: This section needs a lot of elaboration -- ideally this should be
 
equivalent to
 
a datasheet in thoroughness and detail. This work, like many other parts of this
\subsection{Building the Bootstrap Initialization Constant}
project, will have to wait.
\label{boot_code_conversion}
 
 
\subsection{MCU interface to static memory}
    The project includes a python script (\texttt{/tools/build\_pkg/build\_pkg.py})
\label{mcu_if_sram}
    whose purpose is to build an VHDL \texttt{t\_obj\_code} constant out of a
 
    \emph{binary} object code file.
The interface to external memory in the MCU module is essentially that of the
 
internal cache/memory controller. Its timing is described in section
    This script will read one or more big-endian, binary object files and will
~\ref{cache_state_machine}.\\
    produce a  VHDL package file that will contain initialization constants for
 
    the bootstrap BRAM and for some other memories that are only used in the
The MCU inputs are meant to be connected straight to the FPGA i/o pins. The only
    simulation test bench.
trick is the bidirectional memory data bus: as you can see, the MCU data buses
    The package can optionally include too some simulation and synthesis
are unidirectional and thus you will need to provide an interconnection
    configuration constants -- such as the size of the bootstrap BRAM.
external to this module. This interconnection shall include the requisite
 
3-state buffers:
    The makefiles included in the code samples invoke this script twice: once
 
    to generate a package called \emph{sim\_params\_pkg} and used in the
\begin{verbatim}
    simulation test bench; and once to build a package called
sram_databus <= sram_data_wr when sram_byte_we_n/="11" else (others => 'Z');
    \emph{bootstrap\_code\_pkg} used for synthesis.
\end{verbatim}
 
 
 
The top level module can be used as a fully tested example of how to use this
 
interface to connect to a common SRAM chip (ISSI IS61LV25616).
 
 
 
In reviewing the top module source, note that I had to adapt the dual
 
byte-write-enable outputs to the SRAM
 
configuration of a single write-enable plus dual byte-enable inputs.
 
 
 
Note too that the static memory bus is used to access both the 16-bit wide SRAM
 
and an 8-bit wide FLASH. These chips are connected to separate buses on the
 
target board, so the top module needs to conflate both buses before connecting
 
them to the MPU. This is why a multiplexor is used in the mpu\_sram\_data\_rd
 
bus. A real-world board would probably have the SRAM and the FLASH connected
 
to the same bus, simplifying the interface logic.
 
 
 
 
 
\subsection{MCU interface to peripherals}
 
\label{mcu_if_io}
 
 
 
    TODO Documentation to be done
 
 
 
\subsection{MCU interrupt inputs}
    Please refer to the makefiles for usage examples, and read the script source
\label{mcu_irqs}
    for more detailed usage instructions.
 
 
    TODO Documentation to be done
 
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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