Commit 31f7081f authored by Carlos Gil Soriano's avatar Carlos Gil Soriano

Updated documentation for m25p32 core.

parent 7cc28d23
%%This is a very basic article template.
%%There is just one section and two subsections.
\documentclass[a4paper,11pt]{article}
\usepackage[pdfborder= 0 0 0 1]{hyperref}
\usepackage{graphicx}
%%\usepackage{draftwatermark}
%%\SetWatermarkLightness{0.9}
%%\SetWatermarkScale{5}
\begin{document}
\title{m25p32 manager HDL core}
\author{Carlos Gil Soriano\\BE-CO-HT\\
\href{mailto:carlos.gil.soriano@cern.ch}{
\textbf{\textit{carlos.gil.soriano@cern.ch}}}}
\date{June 10, 2012}
\hypersetup{
colorlinks = true,
urlcolor = blue
pdftitle = {SPI multifield HDL core},
pdfauthor = {Carlos Gil Soriano},
pdfsubject = {Reference guide for SPI multifield HDL core},
pdfkeywords = {SPI, VHDL, core, register, mapping}
}
\maketitle
\thispagestyle{empty}
\begin{figure}[htb]
\begin{center}
\includegraphics[scale=0.5,
keepaspectratio]{../../../doc/OHWR/Pictures/Figures/OHRlogo.png}
\includegraphics[scale=0.25,
keepaspectratio]{../../../doc/OHWR/Pictures/Figures/CERN-Logo.png}
\end{center}
\end{figure}
\begin{abstract}
A module for accessing m25p32 EEPROM memory. It is able to perform writes and
reads thanks to \textit{SPI multifields HDL core}.
The present documentation address the following subjects:
\begin{itemize}
\item The registers to control the module.
\item Step-by-step instructions for proper use.
access.
\end{itemize}
\end{abstract}
\vspace{2cm}
\begin{center}
\begin{tabular}{|p{2.5cm}|p{4cm}|p{2.5cm}|}
\hline
\multicolumn{3}{|c|}{\textbf{Revision history}}\\
\hline
\hline
\textbf{HDL version} & \textbf{Module} & \textbf{Date}\\
\hline
0.1 & m25p32 manager core & July 25, 2012\\
& (Preliminary) &\\
\hline
0.9 & m25p32 manager core & Oct. 25, 2012\\
\hline
\end{tabular}
\end{center}
\pagebreak
\tableofcontents
\pagebreak
\section{Structure}
The m25p32 manager module contains several blocks related the following way:\\
-- m25p32\_pkg.vhd
-- m25p32\_top.vhd
----- m25p32\_master\_regs.vhd
----- m25p32\_core.vhd
--------- spi\_master\_core.vhd
\subsection{Dependencies}
m25p32 core depends on \textit{spi\_master\_core.vhd}, thus, all the
dependencies of \textit{spi\_master\_core.vhd} must be met. The corresponding
files from \textit{ctdah\_lib} must be added to the project.
\section{Registers}
\subsection{FMI}
The FMI, \textit{Flash Memory Instruction Register} is a write-read register.
It can be write-read in all the bit fields but OPA and OPF, which are
read-only. When performing a write into the \textit{FMI} register, bits OPA
and OPF will not be written on.\\
\begin{tabular}{| l | c | c | c |}
\hline
\textbf{Bits} & \textbf{Field} & \textbf{Meaning} & \textbf{Default}\\
\hline
\hline
0 & OPR & OPeration Requested & \textbf{'0'} \\
\hline
1 & OPA & OPeration Attended & \textbf{'0'} \\
\hline
2 & OPF & OPeration Finished & \textbf{'0'} \\
\hline
5-3 & OP & OPeration to perform & \textbf{x} \\
\hline
13-6 & PG & PaGe number & \textbf{0} \\
\hline
19-14 & SCT & SeCTor number & \textbf{0} \\
\hline
23-20 & y & Reserved & \textbf{x0} \\
\hline
\end{tabular}
\subsubsection{Available FMI SPI Operations}
The table below shows the available operations that can be commanded
through field \textit{OP} in \textit{FMI} register.\\
\begin{tabular}{| l | c | c | c |}
\hline
\textbf{Operation} & \textbf{Meaning} & \textbf{OP code}\\
\hline
\hline
x & Reserved & \textbf{"000"}\\
\hline
ERS & ERase sector. Sets everything to FF & \textbf{"001"}\\
\hline
RDP & ReaD Page. Not implemented by now & \textbf{"010"}\\
\hline
WRP & WRite Page & \textbf{"011"}\\
\hline
RDSR & ReaD Status Register & \textbf{"100"}\\
\hline
WRSR & WRite Status Register & \textbf{"101"}\\
\hline
\end{tabular}
\subsubsection{SPI Instructions implemented}
The following SPI instructions have been implemented:\\
\begin{tabular}{| c | c | c | c | c |}
\hline
\textbf{Instruction} & \textbf{Description} & \textbf{Address} & \textbf{Data} & \textbf{SPI}\\
& & \textbf{Bytes} & \textbf{Bytes} & \textbf{Code} \\
\hline
\hline
WREN & WRite ENable & 0 & 0 & 0x06 \\
\hline
WRDI & WRite DIsable & 0 & 0 & 0x04 \\
\hline
RDSR & ReaD Status Register & 0 & 1 & 0x05 \\
\hline
WRSR & WRite Status Register & 0 & 1 & 0x01 \\
\hline
READ & READ data bytes & 3 & 4 & 0x03 \\
\hline
PP & Page Program & 3 & 256 & 0x02 \\
\hline
SE & Sector Erase & 3 & 0 & 0xD8 \\
\hline
BE & Bulk Erase & 0 & 0 & 0xC7 \\
\hline
\end{tabular} \\
It should be noted that the bytes read back from a READ instruction have
been bounded to four consecutives bytes. This helps to reduce the
complexity of the design and easily let the data to be read from the
wishbone interface.
\section{Internal memory mapping}
The internal registers map is as follow:\\
\begin{tabular}{| c | c | c | c | c |}
\hline
\textbf{Address} & \textbf{Padding} & \textbf{Address} & \textbf{Register} & \textbf{Access} \\
\textbf{prefix} & & \textbf{suffix} & & \\
\hline
\textbf{'0'} & \textbf{0's} & \textbf{"00"} & \textit{FMI register} & Write-read \\
\hline
\textbf{'0'} & \textbf{0's} & \textbf{"01"} & \textit{m25p32 SR} & Write-only \\
\hline
\textbf{'0'} & \textbf{0's} & \textbf{"10"} & \textit{MISO bytes read} & Read-only \\
\hline
\textbf{'1'} & \textbf{0's} & \textbf{"00"} & \textit{Least significant word} & Write-read \\
& & & \textit{to be written into MOSI}& \\
\hline
\textbf{'1'} & \textbf{...} & \textbf{"..."} & \textit{Word 'n' to be} & Write-read \\
& & & \textit{written into MOSI} & \\
\hline
\textbf{'1'} & \textbf{1's} & \textbf{"11"} & \textit{Most significant word} & Write-read \\
& & & \textit{to be written into MOSI}& \\
\hline
\end{tabular}
\section{How to use it}
\begin{description}
\item [ADDITIONAL] In the case that data will be outputted in the MOSI pin, write all the
internal memory area allocated for MOSI writes. In the case of a WRSR
instruction this will take wishbone transaction. For PP instructions, it will
take the number of words that can fit in one page.
\item [1.-] Write the operation to be performed to the flash memory via the SPI command in
\textbf{FMI register}.
\end{description}
\end{document}
----------------------------------------------------------------------------------
--
-- Copyright CERN 2011.
--
-- This documentation describes Open Hardware and is licensed under the
-- CERN OHL v. 1.1.
--
-- You may redistribute and modify this documentation under the terms of the CERN
-- OHL v.1.1. (http://ohwr.org/cernohl).
--
-- This documentation is distributed WITHOUT
-- ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING OF MERCHANTABILITY, SATISFACTORY
-- QUALITY AND FITNESS FOR A PARTICULAR PURPOSE. Please see the CERN OHL v.1.1 for
-- applicable conditions.
--
---------------------------------------------------------------------------------
--
-- Company: CERN, BE-CO-HT
-- Engineer: Carlos Gil Soriano
--
-- Create Date: 08:26:02 06/18/2012
-- Design Name: m25p32 wishbone access
-- Module Name: m25p32_buff - Behavioral
-- Project Name: Level Conversion Circuits
-- Target Devices: Spartan 6
-- Tool versions:
-- Description: Page buffers for storing temporal pages before/after
-- accessing the m25p32
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
library work;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.m25p32_pkg.ALL;
use work.ctdah_pkg.ALL;
use work.spi_master_pkg.ALL;
entity m25p32_buff is
generic(
g_BUFFER_SIZE : NATURAL := c_NUMBER_OF_BUFFERS;
g_inst_width : NATURAL := c_INST_LENGTH;
g_addr_width : NATURAL := c_ADDR_LENGTH;
g_data_width : NATURAL := c_PAGE_SIZE
); port(
rst_i : in STD_LOGIC;
clk : in STD_LOGIC;
inst_i : in STD_LOGIC_VECTOR (8*g_inst_width - 1 downto 0);
addr_i : in STD_LOGIC_VECTOR (8*g_addr_width - 1 downto 0);
data_i : in STD_LOGIC_VECTOR (31 downto 0);
inst_db_o : out STD_LOGIC_VECTOR (g_BUFFER_SIZE*8*g_inst_width - 1 downto 0);
addr_db_o : out STD_LOGIC_VECTOR (g_BUFFER_SIZE*8*g_addr_width - 1 downto 0);
data_db_o : out STD_LOGIC_VECTOR (g_BUFFER_SIZE*8*g_data_width - 1 downto 0);
CTR1_i : in STD_LOGIC_VECTOR (r_CTR1'a_length - 1 downto 0);
DBUF_o : out STD_LOGIC_VECTOR (r_DBUF'a_length - 1 downto 0)
);
end m25p32_buff;
architecture Behavioral of m25p32_buff is
type data_db is array (0 to c_NUMBER_OF_BUFFERS - 1) of
STD_LOGIC_VECTOR(8*c_DATA_LENGTH - 1 downto 0);
signal s_data_db : data_db;
signal s_CTR1 : r_CTR1;
signal s_DBUF : r_DBUF;
signal s_push_inst : STD_LOGIC_VECTOR (c_NUMBER_OF_BUFFERS - 1 downto 0);
signal s_push_addr : STD_LOGIC_VECTOR (c_NUMBER_OF_BUFFERS - 1 downto 0);
signal s_push_data : STD_LOGIC_VECTOR (c_NUMBER_OF_BUFFERS - 1 downto 0);
signal s_pull : STD_LOGIC_VECTOR (c_NUMBER_OF_BUFFERS - 1 downto 0);
signal s_active_buffer : STD_LOGIC_VECTOR(1 downto 0);
begin
s_CTR1 <= f_CTR1(CTR1_i);
DBUF_o(23 downto 0) <= f_STD_LOGIC_VECTOR(s_DBUF(0));
DBUF_o(47 downto 24) <= f_STD_LOGIC_VECTOR(s_DBUF(1));
data_db_assign: for I in 0 to (c_NUMBER_OF_BUFFERS - 1) generate
data_db_o( (I+1)*8*g_data_width - 1 downto I*8*g_data_width)
<= s_data_db(I);
end generate data_db_assign;
inst_push: for I in 0 to (c_NUMBER_OF_BUFFERS - 1) generate
s_push_inst(I) <= s_CTR1.ARBF(I + s_CTR1.ARBF'low) and s_CTR1.PUSH_I;
end generate inst_push;
addr_push: for I in 0 to (c_NUMBER_OF_BUFFERS - 1) generate
s_push_addr(I) <= s_CTR1.ARBF(I + s_CTR1.ARBF'low) and s_CTR1.PUSH_A;
end generate addr_push;
data_push: for I in 0 to (c_NUMBER_OF_BUFFERS - 1) generate
s_push_data(I) <= s_CTR1.ARBF(I + s_CTR1.ARBF'low) and s_CTR1.PUSH_D;
end generate data_push;
INST_BUFF: for I in 0 to (c_NUMBER_OF_BUFFERS - 1) generate
inst_fifo: FIFO_simple
generic map(
g_data_width => 8)
port map(
reg_i => inst_i,
clk => clk,
push => s_push_inst(I),
flush => rst_i,
reg_o => inst_db_o(8*g_inst_width*(I+1) - 1 downto
8*g_inst_width*I)
);
end generate INST_BUFF;
INST_ADDR: for I in 0 to c_NUMBER_OF_BUFFERS - 1 generate
addr_fifo: FIFO_simple
generic map(
g_data_width => 24)
port map(
reg_i => addr_i,
clk => clk,
push => s_push_addr(I),
flush => rst_i,
reg_o => addr_db_o(8*g_addr_width*(I+1) - 1 downto
8*g_addr_width*I)
);
end generate INST_ADDR;
INST_DATA: for I in 0 to c_NUMBER_OF_BUFFERS - 1 generate
data_fifo_i2c: FIFO_stack
generic map(
g_data_width => 32, g_stack_depth => c_PAGE_SIZE*8/32)
port map(
reg_i => data_i,
clk => clk,
push => s_push_data(I),
flush => rst_i,
reg_o => s_data_db(I)
-- reg_o => data_db_o(8*g_data_width*(I+1) - 1 downto
-- 8*g_data_width*I)
);
end generate INST_DATA;
--! @brief Process to keep track of the page and sector of each double
--! buffer
p_write_buffer: process(clk)
begin
if rising_edge (clk) then
if rst_i = '1' then
s_DBUF(0) <= c_BUF_default;
s_DBUF(1) <= c_BUF_default;
-- s_push <= (others => '0');
-- s_pull <= (others => '0');
-- elsif s_CTR1.WRA = '1' then
-- s_push <= (others => '0');
-- case s_CTR1.ABF is
-- when "01" =>
-- s_push(0) <= '1';
-- s_DBUF(0).PAGE <= unsigned(addr_i(15 downto 8));
-- s_DBUF(0).SECT <= unsigned(addr_i(23 downto 16));
-- when "10" =>
-- s_push(1) <= '1';
-- s_DBUF(1).PAGE <= unsigned(addr_i(15 downto 8));
-- s_DBUF(1).SECT <= unsigned(addr_i(23 downto 16));
-- when others =>
-- end case;
else
end if;
end if;
end process;
end Behavioral;
......@@ -103,7 +103,7 @@ package m25p32_pkg is
-- 0[WBits-2]10 READ_DATA
-- 1[WBits-2]00 WR_DATA
-- ... ...
-- 1[WBits-2]00 WR_DATA
-- 1[WBits-2]11 WR_DATA
----------------------------------------
constant c_FMI_addr :STD_LOGIC_VECTOR (c_WORDS_PER_PAGE_BITS
downto 0) :=
......@@ -143,8 +143,9 @@ package m25p32_pkg is
-- 16 bits
-- Wishbone access: Write-read
----------------------------------------
-- BIT NAME DESCRIPTION
-- 2-0 x Reserved (from drives vp will be appended here OP)
-- BIT NAME DESCRIPTION
-- 0 OPR OPeration Requested
-- 2-1 x Reserved (It will be appended here OP)
-- 5-3 OP OPeration
-- 13-6 PG PaGe number
-- 19-14 SCT SeCTor number
......
......@@ -37,16 +37,16 @@ entity m25p32_top_tb is
architecture Behavioral of m25p32_top_tb is
file s_file_handler : TEXT;
constant c_log_path : STRING := "../test/log/m25p32_top_tb.log";
constant sep : CHARACTER := ht;
file s_file_handler : TEXT;
constant c_log_path : STRING := "../test/log/m25p32_top_tb.log";
constant sep : CHARACTER := ht;
constant c_MANUFACTURER_ID : STD_LOGIC_VECTOR(7 downto 0) := X"20";
constant c_MEMORY_TYPE : STD_LOGIC_VECTOR(7 downto 0) := X"20";
constant c_MEMORY_CAPACITY : STD_LOGIC_VECTOR(7 downto 0) := X"16";
constant c_RDID : STD_LOGIC_VECTOR(23 downto 0) := c_MANUFACTURER_ID
& c_MEMORY_TYPE
& c_MEMORY_CAPACITY;
constant c_READ_value : STD_LOGIC_VECTOR(c_READ_LENGTH*8 - 1 downto 0)
constant c_READ_value : STD_LOGIC_VECTOR(c_READ_LENGTH*8 - 1 downto 0)
:= X"A0B9C8D7";
signal wb_rst_i : STD_LOGIC;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment