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

Subversion Repositories spi_slave

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 1 to Rev 2
    Reverse comparison

Rev 1 → Rev 2

/trunk/doc/src/Grafik/block_diagramm.eps Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
trunk/doc/src/Grafik/block_diagramm.eps Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: trunk/doc/src/Grafik/block_diagramm.odg =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: trunk/doc/src/Grafik/block_diagramm.odg =================================================================== --- trunk/doc/src/Grafik/block_diagramm.odg (nonexistent) +++ trunk/doc/src/Grafik/block_diagramm.odg (revision 2)
trunk/doc/src/Grafik/block_diagramm.odg Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: trunk/doc/src/Grafik/block_diagramm.pdf =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: trunk/doc/src/Grafik/block_diagramm.pdf =================================================================== --- trunk/doc/src/Grafik/block_diagramm.pdf (nonexistent) +++ trunk/doc/src/Grafik/block_diagramm.pdf (revision 2)
trunk/doc/src/Grafik/block_diagramm.pdf Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: trunk/doc/src/opb_spi_slave.tex =================================================================== --- trunk/doc/src/opb_spi_slave.tex (nonexistent) +++ trunk/doc/src/opb_spi_slave.tex (revision 2) @@ -0,0 +1,46 @@ +\documentclass[11pt, a4paper, german, oneside]{scrbook} +\textheight240mm +\usepackage{hyperref} +\usepackage[latin1]{inputenc} +\usepackage{graphicx} +\usepackage{colortbl} +\usepackage{tabularx} +\usepackage{longtable} +\definecolor{yellow1}{rgb}{0.98, 1.0, 0.6} +\pagestyle{plain} +\pagenumbering{arabic} +\usepackage{verbatim} + +\title{Specification OPB-SPI Slave} +\author{Daniel Koethe} +\date{\today} + + +\begin{document} + \maketitle +\tableofcontents + +\input{content/spec} + + +% Anhang (Bibliographie darf im deutschen nicht in den Anhang!) +\bibliography{bib/BibtexDatabase} +\bibliographystyle{plain} +\clearpage +\listoffigures +\listoftables + + + + + + + +% Anhang +\appendix +\input{content/Z-Anhang} + + +%% Dokument ENDE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\end{document} + Index: trunk/doc/src/content/Titel.tex =================================================================== --- trunk/doc/src/content/Titel.tex (nonexistent) +++ trunk/doc/src/content/Titel.tex (revision 2) @@ -0,0 +1,13 @@ +\begin{titlepage} + \mbox{}\vspace{5\baselineskip}\\ + \sffamily\huge + \centering + specification OPB-SPI-Slave + \vspace{2\baselineskip}\\ + \rmfamily\Large + Daniel Koethe + \vspace{1\baselineskip}\\ + \today +\end{titlepage} + + Index: trunk/doc/src/content/Z-Anhang.tex =================================================================== --- trunk/doc/src/content/Z-Anhang.tex (nonexistent) +++ trunk/doc/src/content/Z-Anhang.tex (revision 2) @@ -0,0 +1,3 @@ +% \input{content/Z-Anhang-01-Herleitungen} + +\chapter*{} Index: trunk/doc/src/content/spec.tex =================================================================== --- trunk/doc/src/content/spec.tex (nonexistent) +++ trunk/doc/src/content/spec.tex (revision 2) @@ -0,0 +1,410 @@ +\chapter{Introduction} +This document describe a SPI Slave core designed for the Xilinx EDK. \cite{bib_xilinx_edk} + +\section{Features} +\begin{itemize} +\item OPB-Clock and SPI-Clock are complete independent +\item SPI can run faster than OPB if guaranteed that no TX-FIFO Underrunn or RX-FIFO Overrunn occure. +\item variable transfer length 2..32 +\end{itemize} + + + + +\section{Limitations} +\begin{itemize} +\item designed only for Xilinx Spartan-3/Virtex-4 at the moment +\item only Slave Operation +\end{itemize} + +\chapter{Core configuration} +\begin{table} [h] + \centering + \begin{tabular} {|l|l|c|c|} \hline + Description & Parameter Name & Allowable Values & Default Value \\ \hline + \multicolumn{4} {|c|} {System Parameter} \\ \hline + Base address for OPB SPI& C\_BASEADDR & 0x00 & 0x00000000 \\ \hline + High address for OPB SPI& C\_HIGHADDR & BASEADDR+0x3F & BASEADDR+0x3f \\ \hline + OPB address bus width & C\_OPB\_AWIDTH & 32 & 32 \\ \hline + OPB data bus width & C\_OPB\_DWIDTH & 32 & 32 \\ \hline + Target FPGA Family & C\_FAMILY & spartan3,virtex4 & virtex4 \\ \hline + \multicolumn{4} {|c|} {User Parameter} \\ \hline + Shift register width & C\_SR\_WIDTH & 8-32 & 8 \\ \hline + Shift MSB First & C\_MSB\_FIRST & true, false & true \\ \hline + SPI Clock Polarity & C\_CPOL & 0,1 & 0 \\ \hline + SPI Clock Phase & C\_CPHA & 0,1 & 0 \\ \hline + FIFO Size Width(TX/RX)\footnotemark[1] & C\_FIFO\_DEPTH & 4-7 & 4 \\ \hline + DMA\_EN & C\_DMA\_EN & true, false & false \\ \hline + \end{tabular} + \caption{Generics} + \label{tab:Generics} +\end{table} + +\footnotetext[1]{FIFO depth is $2^{Value}$ =(16,32,64,128)} + + + +\chapter{IO-Ports} +\begin{table} [h] + \centering + \begin{tabular}{|l|l|l|l|} \hline + \textbf{Port} & \textbf{width} & \textbf{direction} & \textbf{Description} \\ \hline + SPI\_SCLK & 1 & input & Serial clock input \\ + SPI\_MOSI & 1 & input & Master Out Slave in \\ + SPI\_MISO & 1 & output & Master in Slave out \\ + SPI\_SS & 1 & input & Slave select \\ \hline + opb\_irq & 1 & output & IRQ Output \\ \hline + \end{tabular} + \caption{external ports} + \label{tab:externalPorts} +\end{table} + +\chapter{Registers} +\section{Adressmap} +\begin{table} [!h] + \centering + \begin{tabular}{|l|c|c|l|} \hline + \textbf{Name} & \textbf{Adress} & \textbf{Acess} & \textbf{Description} \\ \hline + SPI\_CR & 0x00 & R/W & SPI Control Register \\ \hline + SPI\_SR & 0x04 & R/W & SPI Status Register \\ \hline + SPI\_TD & 0x08 & W & SPI Transmit Data Register \\ \hline + SPI\_RD & 0x0C & R & SPI Receive Data Register \\ \hline + TX\_THRESH & 0x10 & R/W & TX-Threshold Prog Full/Emty \\ \hline + RX\_THRESH & 0x14 & R/W & RX-Threshold Prog Full/Emty \\ \hline + TX\_DMA\_CTL & 0x18 & R/W & TX DMA Control \\ \hline + TX\_DMA\_ADDR & 0x1C & R/W & TX DMA Base Adress Offset \\ \hline + TX\_DMA\_NUM & 0x20 & R/W & TX DMA Number of Transfers \\ \hline + RX\_DMA\_CTL & 0x24 & R/W & RX DMA Control \\ \hline + RX\_DMA\_ADDR & 0x28 & R/W & RX DMA Base Adress Offset \\ \hline + RX\_DMA\_NUM & 0x2C & R/W & RX DMA Number of Transfers \\ \hline + + DGIE & 0x40 & R/W & Device global IRQ Enable Register \\ \hline + IPISR & 0x44 & R/W & IRQ Status Register \\ \hline + IPIER & 0x48 & R/W & IRQ Enable Register \\ \hline + \end{tabular} + \caption{Address-Map} + \label{tab:registers} +\end{table} + +\section{SPI\_CR} +\begin{table} [!h] + \centering + \begin{tabular} {|l|c|c|c|l|} \hline + \textbf{Bit} & \textbf{Name} & \textbf{Acess} & \textbf{Reset Value} & \textbf{Description} \\ \hline + 31 & DGE & R/W & 0 & Device Global Enable \\ + & & & & 0: Disable \\ + & & & & 1: Enable \\ \hline + 30 & TX\_EN & R/W & 0 & Transmit Enable \\ + & & & & 0: Disable \\ + & & & & 1: Enable \\ \hline + 29 & RX\_EN & R/W & 0 & Receive Enable \\ + & & & & 0: Disable \\ + & & & & 1: Enable \\ \hline + 29 & RESET & R/W & 0 & Reset Device(self cleared) \\ + & & & & 0: Normal Operation \\ + & & & & 1: Reset SPI-Core(SR/FIFO) \\ \hline 29..0 & \multicolumn{4} {c|} {reserved} \\ \hline \end{tabular} + \caption{SPI\_CR Register} + \label{tab:SPI_CR} +\end{table} + + +\section{SPI\_SR} +\begin{table} [!h] + \centering + \begin{tabular} {|l|l|c|c|l|} \hline + \textbf{Bit} & \textbf{Name} & \textbf{Acess} & \textbf{Reset Value} & \textbf{Description} \\ \hline + 31 & TX Prog Full & R & 0 & Prog Full Flag \\ + & & & & 1: FIFO Prog Full \\ \hline + 30 & TX Full & R & 0 & Full Flag \\ + & & & & 1: FIFO Full \\ \hline + 29 & TX Overflow & R & 0 & Overflow Flag \\ + & & & & 1: FIFO Overflow \\ + & & & & (Cleared only at Reset) \\ \hline + 28 & TX Prog Empty & R & 0 & Prog Empty Flag \\ + & & & & 1: FIFO Prog Empty \\ \hline + 27 & TX Empty & R & 0 & Full Flag \\ + & & & & 1: FIFO Empty \\ \hline + 26 & TX Underflow & R & 0 & Underflow Flag \\ + & & & & 1: FIFO Underflow \\ + & & & & (Cleared only at Reset) \\ \hline + 25 & RX Prog Full & R & 0 & Prog Full Flag \\ + & & & & 1: FIFO Prog Full \\ \hline + 24 & RX Full & R & 0 & Full Flag \\ + & & & & 1: FIFO Full \\ \hline + 23 & RX Overflow & R & 0 & Overflow Flag \\ + & & & & 1: FIFO Overflow \\ + & & & & (Cleared only at Reset) \\ \hline + 22 & RX Prog Empty & R & 0 & Prog Empty Flag \\ + & & & & 1: FIFO Prog Empty \\ \hline + 21 & RX Empty & R & 0 & Full Flag \\ + & & & & 1: FIFO Empty \\ \hline + 20 & RX Underflow & R & 0 & Underflow Flag \\ + & & & & 1: FIFO Underflow \\ + & & & & (Cleared only at Reset) \\ \hline + 19 & Chip Select & R & 0 & Chip Select Flag \\ + & & & & 0: CS\_N Low \\ + & & & & 1: CS\_N High \\ \hline + 18 & TX DMA Done & R & 0 & Transmit DMA done \\ + & & & & 0: TX DMA in progress \\ + & & & & 1: TX DMA all Transfers done\\ \hline 17 & RX DMA Done & R & 0 & Receive DMA done \\ + & & & & 0: RX DMA in progress \\ + & & & & 1: RX DMA all Transfers done\\ \hline + 16..0 & \multicolumn{4} {c|} {reserved} \\ \hline \end{tabular} + \caption{SPI\_SR Register} + \label{tab:SPI_SR} +\end{table} + +\newpage +\section{TX\_THRESH} +\begin{table}[!h] + \centering + \begin{tabular} {|l|l|c|c|l|} \hline + \textbf{Bit} & \textbf{Name} & \textbf{Acess} & \textbf{Reset} & \textbf{Description} \\ + & & & \textbf{Value} & \\ \hline + 31..16 & TX\_THRESH\_PROG\_FULL & R/W & 0 & Transmit Prog Full Threshold\\ + & & & & [1..$2^{C\_FIFO\_DEPTH}-2$] \\ \hline + 15..0 & TX\_THRESH\_PROG\_EMPTY & R/W & 0 & Transmit Prog Empty Threshold\\ + & & & & [1..$2^{C\_FIFO\_DEPTH}-2$] \\ \hline + \end{tabular} + \caption{TX\_THRESH Register} + \label{tab:TX_THRESH} +\end{table} + + +\section{RX\_THRESH} +\begin{table}[!h] + \centering + \begin{tabular} {|l|l|c|c|l|} \hline + \textbf{Bit} & \textbf{Name} & \textbf{Acess} & \textbf{Reset} & \textbf{Description} \\ + & & & \textbf{Value} & \\ \hline + 31..16 & RX\_THRESH\_PROG\_FULL & R/W & 0 & Receive Prog Full Threshold \\ + & & & & [1..$2^{C\_FIFO\_DEPTH}-2$] \\ \hline + 15..0 & RX\_THRESH\_PROG\_EMPTY & R/W & 0 & Receive Prog Empty Threshold\\ + & & & & [1..$2^{C\_FIFO\_DEPTH}-2$] \\ \hline \end{tabular} + \caption{RX\_THRESH Register} + \label{tab:RX_THRESH} +\end{table} + + +\section{DGIE} +\begin{table} [!h] + \centering + \begin{tabular} {|l|c|c|c|l|} \hline + \textbf{Bit} & \textbf{Name} & \textbf{Acess} & \textbf{Reset Value} & \textbf{Description} \\ \hline + 31 & DGIE & R/W & 0 & Global IRQ Ebable \\ + & & & & 0: Disable \\ + & & & & 1: Enable \\ \hline + 29..0 & \multicolumn{4} {c|} {reserved} \\ \hline \end{tabular} + \caption{DGIE Register} + \label{tab:dgie} +\end{table} + +\newpage +\section{IPISR} +\begin{table} [!h] + \centering + \begin{tabular} {|l|l|c|c|l|} \hline + \textbf{Bit} & \textbf{Name} & \textbf{Acess} & \textbf{Reset Value} & \textbf{Description} \\ \hline + 31 & TX\_Prog\_Empty & R/ToW\footnotemark[1] & 0 & IRQ Prog Empty Flag \\ \hline + 29 & TX\_Empty & R/ToW & 0 & IRQ Full Flag \\ \hline + 28 & RX\_Prog\_Full& R/ToW & 0 & IRQ Prog Full Flag \\ \hline + 27 & RX\_Full & R/ToW & 0 & IRQ Full Flag \\ \hline + 26 & SS\_FALL & R/ToW & 0 & IRQ SS FALL Flag \\ \hline + 25 & SS\_RISE & R/ToW & 0 & IRQ SS RISE Flag \\ \hline + 24..0 & \multicolumn{4} {c|} {reserved} \\ \hline \end{tabular} + \caption{IPISR Register} + \label{tab:IPISR} +\end{table} + +\footnotetext[1]{Read and ToggleOnWrite (writing 1 clears the bit)} + +\section{IPISE} +\begin{table} [!h] + \centering + \begin{tabular} {|l|l|c|c|l|} \hline + \textbf{Bit} & \textbf{Name} & \textbf{Acess} & \textbf{Reset Value} & \textbf{Description} \\ \hline + 31 & TX\_Prog\_Empty & R/W & 0 & IRQ Prog Empty Enable \\ \hline + 29 & TX\_Empty & R/W & 0 & IRQ Full Enable \\ \hline + 28 & RX\_Prog\_Full & R/W & 0 & IRQ Prog Full Enable \\ \hline + 27 & RX\_Full & R/W & 0 & IRQ Full Enable \\ \hline + 26 & SS\_FALL & R/W & 0 & IRQ SS FALL Enable \\ \hline + 25 & SS\_RISE & R/W & 0 & IRQ SS RISE Enable \\ \hline + 24 & TX\_DMA\_DONE & R/W & 0 & IRQ TX Transfer done Enable\\ \hline + 23 & TX\_DMA\_DONE & R/W & 0 & IRQ RX Transfer done Enable\\ \hline 22..0 & \multicolumn{4} {c|} {reserved} \\ \hline \end{tabular} + \caption{IPISE Register} + \label{tab:IPISE} +\end{table} + +1: IRQ enabled + +\chapter{System Integration} +To integrate this IP-Core in your System, unzip the opb\_spi\_slave.zip to your project-directory. Then Rescan the user repository with \textit{Project $\rightarrow$ Rescan User Repositories}. This will take some seconds. After this you find the core in the \textit{IP Catalog $\rightarrow$ Project Repository}. + +\section{MPD-File} +\begin{verbatim} +BEGIN opb_spi_slave + PARAMETER INSTANCE = opb_spi_slave_0 + PARAMETER HW_VER = 1.00.a + PARAMETER C_BASEADDR = 0x7d600000 + PARAMETER C_HIGHADDR = 0x7d60ffff + BUS_INTERFACE MSOPB = mb_opb + PORT sclk = opb_spi_slave_0_sclk + PORT ss_n = opb_spi_slave_0_ss_n + PORT mosi = opb_spi_slave_0_mosi + PORT miso = opb_spi_slave_0_miso + PORT opb_irq = opb_spi_slave_0_opb_irq +END +\end{verbatim} + +\section{UCF-File} +\begin{verbatim} +# assign I/O Pins +NET opb_spi_slave_0_sclk_pin LOC= AA24; # must CC capable IO in virtex-4 +NET opb_spi_slave_0_ss_n_pin LOC= V20; +NET opb_spi_slave_0_mosi_pin LOC= AC25; +NET opb_spi_slave_0_miso_pin LOC= AC24; +NET opb_spi_slave_0_miso_pin SLEW = FAST; + +#### Module OPB_SPI_Slave constraints +Net opb_spi_slave_0_sclk_pin TNM_NET = spi_clk; +TIMESPEC TS_spi_clk = PERIOD spi_clk 40 ns; + +NET "opb_spi_slave_0_mosi_pin" TNM = "spi_in"; +#NET "opb_spi_slave_0_cs_n_pin" TNM = "spi_in"; +TIMEGRP "spi_in" OFFSET = IN 5 ns VALID 10 ns BEFORE "opb_spi_slave_0_sclk_pin" HIGH ; + +NET "opb_spi_slave_0_miso_pin" TNM = "spi_out"; +TIMEGRP "spi_out" OFFSET = OUT 14 ns AFTER "opb_spi_slave_0_sclk_pin" LOW ; +\end{verbatim} + +\section{Register Header} + +\verbatiminput{opb_spi_slave.h} + + +\chapter{Operations} + +\chapter{Architecture} + +\begin{figure}[h] + \centering + \includegraphics[width=1.00\textwidth]{Grafik/block_diagramm} + \caption{Blockdiagramm} + \label{fig:blockdiagramm} +\end{figure} + +\section{Serial Shift Register} +\begin{table}[!h] + \centering + \begin{tabular} {|l|c|l|} \hline \rowcolor{yellow1} + \textbf{Signal} & \textbf{Direction}& \textbf{Description} \\ \hline + \multicolumn{3} {c|} {Generics} \\ \hline + C\_SR\_WIDTH & - & Shift register width \\ \hline + C\_MSB\_FIRST & - & Transfer MSB First \\ \hline + \multicolumn{3} {c|} {Global} \\ \hline + rst & input & Async-Reset \\ \hline + \multicolumn{3} {c|} {External Interface} \\ \hline + sclk & input & Serial clock input \\ \hline + cs\_n & input & Chip Select \\ \hline + mosi & input & Master Out Slave in \\ \hline + miso\_o & output & Master in Slave out \\ \hline + miso\_i & input & not used \\ \hline + miso\_t & output & MISO Tristate \\ \hline + \multicolumn{3} {c|} {TX-FIFO (1)} \\ \hline + sr\_tx\_clk & output & FIFO-TX CLK \\ \hline + sr\_tx\_en & output & FIFO-TX enable \\ \hline + sr\_tx\_data[C\_SR\_WIDTH:0] & input & FIFO-TX Data \\ \hline + \multicolumn{3} {c|} {RX-FIFO (3)} \\ \hline + sr\_rx\_clk & output & FIFO-RX CLK \\ \hline + sr\_rx\_en & output & FIFO-RX enable \\ \hline + sr\_rx\_data[C\_SR\_WIDTH:0] & output & FIFO-RX Data \\ \hline + \end{tabular} + \caption{Serial-Register} + \label{tab:SerialRegister} +\end{table} +\clearpage + +\section{FIFO} +\begin{table}[!h] + \centering + \begin{tabular} {|l|c|l|} \hline \rowcolor{yellow1} + \textbf{Signal} & \textbf{Direction}& \textbf{Description} \\ \hline + \multicolumn{3} { c|} {Generics} \\ \hline + C\_FIFO\_WIDTH & - & Shift register width \\ \hline + C\_FIFO\_SIZE & - & FIFO Size Width \\ \hline + C\_SYNC\_TO & - & FIFO Sync Flags to Clock \\ \hline + \multicolumn{3} { c|} {Global} \\ \hline + rst & input & Async-Reset \\ \hline + \multicolumn{3} { c|} {Write-Port (2,3)} \\ \hline + wr\_clk & input & FIFO Write CLK \\ \hline + wr\_en & input & FIFO Write enable \\ \hline + din[C\_FIFO\_WIDTH:0] & input & FIFO Write data \\ \hline + \multicolumn{3} { c|} {READ-Port (1,4)} \\ \hline + rd\_clk & input & FIFO Read CLK \\ \hline + rd\_en & input & FIFO Read enable \\ \hline + dout[C\_FIFO\_WIDTH:0] & output & FIFO Read data \\ \hline + \multicolumn{3} { c|} {Flags (4)} \\ \hline + empty & output & FIFO Emtpy \\ \hline + full & output & FIFO Full \\ \hline + overflow & output & FIFO Overflow \\ \hline + underflow & output & FIFO Underflow \\ \hline + prog\_full\_thresh[C\_FIFO\_WIDTH:0] & output & FIFO Programmable Full Threshold \\ \hline + prog\_empty\_thresh[C\_FIFO\_WIDTH:0] & output & FIFO Programmable Empty Threshold\\ \hline + prog\_full & output & FIFO Programmable Full \\ \hline + prog\_empty & output & FIFO Programmable Empty \\ \hline + \end{tabular} + \caption{TX-FIFO} + \label{tab:tx-fifo} +\end{table} + +\newpage +\section{OPB\_IF} +\begin{table}[!h] + \centering + \begin{tabular} {|l|c|l|} \hline \rowcolor{yellow1} + \textbf{Signal} & \textbf{Direction}& \textbf{Description} \\ \hline + \multicolumn{3} { c|} {Generics} \\ \hline + C\_BASEADDR & - & Base address for OPB SPI \\ \hline + C\_HIGHADDR & - & High address for OPB SPI \\ \hline + C\_OPB\_AWIDTH & - & OPB address bus width \\ \hline + C\_OPB\_DWIDTH & - & OPB data bus width \\ \hline + C\_FAMILY & - & Target FPGA Family \\ \hline + C\_SR\_WIDTH & - & Shift register width \\ \hline + C\_FIFO\_WIDTH & - & Shift register width \\ \hline + C\_FIFO\_SIZE & - & FIFO Size Width \\ \hline + C\_NUM\_FLG & - & Number of FIFO Status flags \\ \hline + C\_NUM\_INT & - & Number of IRQ Sources \\ \hline + \multicolumn{3} { c|} {OPB-Bus} \\ \hline + OPB\_rst & input & Async-Reset \\ \hline + OPB\_ABus[C\_OPB\_AWIDTH-1:0] & input & Adress-Bus \\ \hline + OPB\_BE[C\_OPB\_DWIDTH/8-1:0] & input & Bytes Enables \\ \hline + OPB\_Clk & input & Clock \\ \hline + OPB\_DBus[C\_OPB\_DWIDTH-1:0] & input & Data-Bus to slave \\ \hline + OPB\_RNW & input & Read/Write \\ \hline + OPB\_Rst & input & Reset \\ \hline + OPB\_select & input & Select \\ \hline + OPB\_seqAddr & input & Sequential Adress Enable \\ \hline + Sln\_DBus & output & Data-Bus to Master \\ \hline + Sln\_errAck & output & Error Acknowledge \\ \hline + Sln\_retry & output & Retry \\ \hline + Sln\_toutSup & output & Timeout Suppression \\ \hline + Sln\_xferAck & output & transfer Acknowledge \\ \hline + \multicolumn{3} { c|} {FIFO-PORT (2)} \\ \hline + opb\_tx\_en & output & FIFO-TX Write Enable \\ \hline + opb\_tx\_data[C\_SR\_WIDTH:0] & output & FIFO-TX Write Data \\ \hline + tx\_thresh[(2*C\_FIFO\_SIZE)-1:0] & output & FIFO-TX Prog Thresholds \\ \hline + \multicolumn{3} { c|} {FIFO-PORT (4)} \\ \hline + opb\_rx\_en & output & FIFO-RX Read Enable \\ \hline + opb\_rx\_data[C\_SR\_WIDTH:0] & input & FIFO-RX Read Data \\ \hline + rx\_thresh[(2*C\_FIFO\_SIZE)-1:0] & output & FIFO-RX Prog Thresholds \\ \hline + \multicolumn{3} { c|} {FIFO-Flags(2,4)} \\ \hline + opb\_fifo\_flg[C\_NUM\_FLG-1:0] & input & FIFO Flags \\ \hline + \multicolumn{3} { c|} {IRQ-Signals} \\ \hline + opb\_dgie & output & Device Global IRQ Enable \\ \hline + opb\_ier(C\_NUM\_INT-1:0) & output & IRQ Enable Register \\ \hline + opb\_isr(C\_NUM\_INT-1:0) & input & IRQ Status Register \\ \hline + opb\_isr\_clr(C\_NUM\_INT-1:0) & output & Clear IRQ Flags \\ \hline + \end{tabular} + \caption{OPB\_IF} + \label{tab:opb_if} +\end{table} Index: trunk/doc/src/opb_spi_slave.tcp =================================================================== --- trunk/doc/src/opb_spi_slave.tcp (nonexistent) +++ trunk/doc/src/opb_spi_slave.tcp (revision 2) @@ -0,0 +1,12 @@ +[FormatInfo] +Type=TeXnicCenterProjectInformation +Version=4 + +[ProjectInfo] +MainFile=opb_spi_slave.tex +UseBibTeX=0 +UseMakeIndex=0 +ActiveProfile=LaTeX => PDF +ProjectLanguage=de +ProjectDialect=DE + Index: trunk/doc/opb_spi_slave.pdf =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: trunk/doc/opb_spi_slave.pdf =================================================================== --- trunk/doc/opb_spi_slave.pdf (nonexistent) +++ trunk/doc/opb_spi_slave.pdf (revision 2)
trunk/doc/opb_spi_slave.pdf Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property Index: trunk/pcore/opb_spi_slave_v1_00_a/hdl/vhdl/ram.vhd =================================================================== --- trunk/pcore/opb_spi_slave_v1_00_a/hdl/vhdl/ram.vhd (nonexistent) +++ trunk/pcore/opb_spi_slave_v1_00_a/hdl/vhdl/ram.vhd (revision 2) @@ -0,0 +1,46 @@ +------------------------------------------------------------------------------- +--* +--* @short RAM Sync-Write, Async Read +--* +--* @generic C_FIFO_WIDTH RAM-With (1..xx) +--* @generic C_FIFO_SIZE_WIDTH RAM Size = 2**C_FIFO_SIZE_WIDTH +--* +--* @author: Daniel Köthe +--* @version: 1.0 +--* @date: 2007-11-11 +--/ +------------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; + +entity ram is + generic ( + C_FIFO_WIDTH : integer := 8; + C_FIFO_SIZE_WIDTH : integer := 4); + + port (clk : in std_logic; + we : in std_logic; + a : in std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); + dpra : in std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); + di : in std_logic_vector(C_FIFO_WIDTH-1 downto 0); + dpo : out std_logic_vector(C_FIFO_WIDTH-1 downto 0)); +end ram; + +architecture behavior of ram is + type ram_type is array (2**C_FIFO_SIZE_WIDTH-1 downto 0) of std_logic_vector (C_FIFO_WIDTH-1 downto 0); + signal RAM : ram_type; +begin + + process (clk) + begin + if (clk'event and clk = '1') then + if (we = '1') then + RAM(conv_integer(a)) <= di; + end if; + end if; + end process; + + dpo <= RAM(conv_integer(dpra)); + +end behavior; Index: trunk/pcore/opb_spi_slave_v1_00_a/hdl/vhdl/gray_adder.vhd =================================================================== --- trunk/pcore/opb_spi_slave_v1_00_a/hdl/vhdl/gray_adder.vhd (nonexistent) +++ trunk/pcore/opb_spi_slave_v1_00_a/hdl/vhdl/gray_adder.vhd (revision 2) @@ -0,0 +1,68 @@ +------------------------------------------------------------------------------- +--* +--* @short gray Adder +--* +--* @generic width with of adder vector +--* +--* @author: Daniel Köthe +--* @version: 1.0 +--* @date: 2007-11-11 +--/ +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; +use ieee.std_logic_arith.all; + +entity gray_adder is + generic ( + width : integer := 4); + port ( + in_gray : in std_logic_vector(width-1 downto 0); + out_gray : out std_logic_vector(width-1 downto 0)); +end gray_adder; + +architecture behavior of gray_adder is + --* convert gray to bin + component gray2bin + generic ( + width : integer); + port ( + in_gray : in std_logic_vector(width-1 downto 0); + out_bin : out std_logic_vector(width-1 downto 0)); + end component; + --* convert bin to gray + component bin2gray + generic ( + width : integer); + port ( + in_bin : in std_logic_vector(width-1 downto 0); + out_gray : out std_logic_vector(width-1 downto 0)); + end component; + + signal out_bin : std_logic_vector(width-1 downto 0); + signal bin_add : std_logic_vector(width-1 downto 0); + +begin -- behavior + --* convert input gray signal to binary + gray2bin_1 : gray2bin + generic map ( + width => width) + port map ( + in_gray => in_gray, + out_bin => out_bin); + + --* add one to signal + bin_add <= out_bin + 1; + --* convert signal back to gray + bin2gray_1 : bin2gray + generic map ( + width => width) + port map ( + in_bin => bin_add, + out_gray => out_gray); + + + +end behavior; Index: trunk/pcore/opb_spi_slave_v1_00_a/hdl/vhdl/shift_register.vhd =================================================================== --- trunk/pcore/opb_spi_slave_v1_00_a/hdl/vhdl/shift_register.vhd (nonexistent) +++ trunk/pcore/opb_spi_slave_v1_00_a/hdl/vhdl/shift_register.vhd (revision 2) @@ -0,0 +1,190 @@ +------------------------------------------------------------------------------- +--* +--* @short Shift-Register +--* +--* Control Register Description: +--* @li Bit0: DGE : Global Device Enable +--* @li Bit1: TX_EN: Transmit enable +--* @li Bit2: RX_EN: Receive enable +--* +--* Generics described in top entity. +--* @port opb_ctl_reg Control Register +--* +--* @see opb_spi_slave +--* @author: Daniel Köthe +--* @version: 1.1 +--* @date: 2007-11-11 +--/ +-- Version 1.0 Initial Release +-- Version 1.1 rx_cnt/tx_cnt only increment if < C_SR_WIDTH +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use IEEE.STD_LOGIC_ARITH.all; + +library work; +use work.opb_spi_slave_pack.all; + +entity shift_register is + + generic ( + C_SR_WIDTH : integer := 8; + C_MSB_FIRST : boolean := true; + C_CPOL : integer range 0 to 1 := 0; + C_PHA : integer range 0 to 1 := 0); + + port ( + rst : in std_logic; + -- control register + opb_ctl_reg : in std_logic_vector(C_OPB_CTL_REG_WIDTH-1 downto 0); + -- external + sclk : in std_logic; + ss_n : in std_logic; + mosi : in std_logic; + miso_o : out std_logic; + miso_i : in std_logic; + miso_t : out std_logic; + -- transmit fifo + sr_tx_clk : out std_logic; + sr_tx_en : out std_logic; + sr_tx_data : in std_logic_vector(C_SR_WIDTH-1 downto 0); + -- receive fifo + sr_rx_clk : out std_logic; + sr_rx_en : out std_logic; + sr_rx_data : out std_logic_vector(C_SR_WIDTH-1 downto 0)); +end shift_register; + + +architecture behavior of shift_register is + --* Global + signal sclk_int : std_logic; + signal sclk_int_inv : std_logic; + signal rx_cnt : integer range 0 to 31 := 0; + + -- RX + signal rx_sr_reg : std_logic_vector(C_SR_WIDTH-2 downto 0); + signal sr_rx_en_int : std_logic; + signal sr_rx_data_int : std_logic_vector(C_SR_WIDTH-1 downto 0); + + -- tx + signal miso_int : std_logic; + signal tx_cnt : integer range 0 to 31 := 0; + signal sr_tx_en_int : std_logic; + signal sr_tx_data_int : std_logic_vector(C_SR_WIDTH-1 downto 0); + + +begin -- behavior + + miso_t <= ss_n; -- tristate + + + sclk_int <= sclk when (C_PHA = 0 and C_CPOL = 0) else + sclk when (C_PHA = 1 and C_CPOL = 1) else + not sclk; + + + sr_rx_en <= transport sr_rx_en_int after 1 ns; + sr_tx_en <= transport sr_tx_en_int after 1 ns; + + --* reorder received bits if not "MSB_First" + reorder_rx_bits : process(sr_rx_data_int) + begin + for i in 0 to C_SR_WIDTH-1 loop + if C_MSB_FIRST then + sr_rx_data(i) <= transport sr_rx_data_int(i) after 1 ns; + else + sr_rx_data(C_SR_WIDTH-1-i) <= transport sr_rx_data_int(i)after 1 ns; + end if; + end loop; -- i + end process reorder_rx_bits; + + --* reorder transmit bits if not "MSB_First" + reorder_tx_bits : process(sr_tx_data) + begin + for i in 0 to C_SR_WIDTH-1 loop + if C_MSB_FIRST then + sr_tx_data_int(i) <= sr_tx_data(i); + else + sr_tx_data_int(C_SR_WIDTH-1-i) <= sr_tx_data(i); + end if; + end loop; -- i + end process reorder_tx_bits; + + + ----------------------------------------------------------------------------- + + sr_rx_clk <= sclk_int; + + sr_rx_data_int <= rx_sr_reg & mosi; + + --* RX-Shift-Register + rx_shift_proc : process(rst, opb_ctl_reg, sclk_int) + begin + if (rst = '1' or opb_ctl_reg(C_OPB_CTL_REG_DGE) = '0' or opb_ctl_reg(C_OPB_CTL_REG_RX_EN) = '0') then + rx_cnt <= 0; + sr_rx_en_int <= '0'; + rx_sr_reg <= (others => '0'); + + elsif rising_edge(sclk_int) then + if (ss_n = '0') then + rx_sr_reg <= rx_sr_reg(C_SR_WIDTH-3 downto 0) & mosi; + if (rx_cnt = C_SR_WIDTH-2) then + rx_cnt <= rx_cnt +1; + sr_rx_en_int <= '1'; + elsif (rx_cnt = C_SR_WIDTH-1) then + rx_cnt <= 0; + sr_rx_en_int <= '0'; + else + rx_cnt <= rx_cnt +1; + end if; + else + -- ss_n high + -- assert framing error if cnt != 0? + sr_rx_en_int <= '0'; + rx_cnt <= 0; + end if; + end if; + end process rx_shift_proc; + +------------------------------------------------------------------------------- + -- TX Shift Register + sr_tx_clk <= sclk_int_inv; + sclk_int_inv <= not sclk_int; + + miso_o <= sr_tx_data_int(C_SR_WIDTH-1) when (tx_cnt = 0) else + miso_int; + + + --* TX Shift-Register + tx_shift_proc : process(rst, opb_ctl_reg, sclk_int_inv) + begin + if (rst = '1' or opb_ctl_reg(C_OPB_CTL_REG_DGE) = '0' or opb_ctl_reg(C_OPB_CTL_REG_TX_EN) = '0') then + tx_cnt <= 0; + sr_tx_en_int <= '0'; + miso_int <= '0'; + elsif rising_edge(sclk_int_inv) then + if (ss_n = '0') then + if (tx_cnt /= C_SR_WIDTH-1) then + miso_int <= sr_tx_data_int(C_SR_WIDTH-1-(tx_cnt+1)); + end if; + if (tx_cnt = C_SR_WIDTH-2) then + sr_tx_en_int <= '1'; + tx_cnt <= tx_cnt +1; + elsif (tx_cnt = C_SR_WIDTH-1) then + tx_cnt <= 0; + sr_tx_en_int <= '0'; + else + tx_cnt <= tx_cnt +1; + end if; + else + -- ss_n high + -- assert framing error if cnt != 0? + sr_tx_en_int <= '0'; + tx_cnt <= 0; + end if; + end if; + end process tx_shift_proc; +------------------------------------------------------------------------------- + + end behavior; Index: trunk/pcore/opb_spi_slave_v1_00_a/hdl/vhdl/fifo.vhd =================================================================== --- trunk/pcore/opb_spi_slave_v1_00_a/hdl/vhdl/fifo.vhd (nonexistent) +++ trunk/pcore/opb_spi_slave_v1_00_a/hdl/vhdl/fifo.vhd (revision 2) @@ -0,0 +1,262 @@ +------------------------------------------------------------------------------- +--* +--* @short Configurable FIFO +--* +--* @generic C_FIFO_WIDTH RAM-With (1..xx) +--* @generic C_FIFO_SIZE_WIDTH RAM Size = 2**C_FIFO_SIZE_WIDTH +--* @generic C_SYNC_TO Sync FIFO Flags to read or write clock +--* +--* @author: Daniel Köthe +--* @version: 1.0 +--* @date: 2007-11-11 +--/ +------------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; +use ieee.std_logic_arith.all; + + +entity fifo is + generic ( + C_FIFO_WIDTH : integer := 8; + C_FIFO_SIZE_WIDTH : integer := 4; + C_SYNC_TO : string := "RD"); + port ( + rst : in std_logic; + -- write port + wr_clk : in std_logic; + wr_en : in std_logic; + din : in std_logic_vector(C_FIFO_WIDTH-1 downto 0); + -- read port + rd_clk : in std_logic; + rd_en : in std_logic; + dout : out std_logic_vector(C_FIFO_WIDTH-1 downto 0); + -- flags + empty : out std_logic; + full : out std_logic; + overflow : out std_logic; + underflow : out std_logic; + prog_empty_thresh : in std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); + prog_full_thresh : in std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); + prog_empty : out std_logic; + prog_full : out std_logic); + +end fifo; + +architecture behavior of fifo is + --* ram with sync write and async read + component ram + generic ( + C_FIFO_WIDTH : integer := 8; + C_FIFO_SIZE_WIDTH : integer := 4); + port ( + clk : in std_logic; + we : in std_logic; + a : in std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); + dpra : in std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); + di : in std_logic_vector(C_FIFO_WIDTH-1 downto 0); + dpo : out std_logic_vector(C_FIFO_WIDTH-1 downto 0)); + end component; + + --* component generates fifo flag + component fifo_prog_flags + generic ( + C_FIFO_SIZE_WIDTH : integer; + C_SYNC_TO : string); + port ( + rst : in std_logic; + clk : in std_logic; + cnt_grey : in std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); + cnt : in std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); + prog_full_thresh : in std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); + prog_empty_thresh : in std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); + prog_empty : out std_logic; + prog_full : out std_logic); + end component; + + --* logic coded gray counter + component gray_adder + generic ( + width : integer); + port ( + in_gray : in std_logic_vector(width-1 downto 0); + out_gray : out std_logic_vector(width-1 downto 0)); + end component; + + signal wr_cnt_gray_add_one : std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); + signal wr_cnt_next_grey_add_one : std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); + signal rd_cnt_grey_add_one : std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); + + attribute fsm_extract : string; + -- wr_clock domain + -- main wr grey code counter + signal wr_cnt_grey : std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); + attribute fsm_extract of wr_cnt_grey : signal is "no"; + + -- main grey code counter for full + signal wr_cnt_next_grey : std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); + attribute fsm_extract of wr_cnt_next_grey : signal is "no"; + + -- rd_clk domain + -- main rd grey code counter + signal rd_cnt_grey : std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); + attribute fsm_extract of rd_cnt_grey : signal is "no"; + + -- binary counter for prog full/empty + signal rd_cnt : std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); + signal wr_cnt : std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); + + signal empty_int : std_logic; + signal full_int : std_logic; + +begin -- behavior + + empty <= empty_int; + full <= full_int; + +--* write counter generation + fifo_write_proc: process(rst, wr_clk) + begin + if (rst = '1') then + wr_cnt_grey <= (others => '0'); + wr_cnt <= (others => '0'); + wr_cnt_next_grey(C_FIFO_SIZE_WIDTH-1 downto 1) <= (others => '0'); + wr_cnt_next_grey(0) <= '1'; + elsif rising_edge(wr_clk) then + if (wr_en = '1') then + wr_cnt <= wr_cnt+1; + + -- wr_cnt_grey <= add_grey_rom(conv_integer(wr_cnt_grey)); + wr_cnt_grey <= wr_cnt_gray_add_one; + + -- wr_cnt_next_grey <= add_grey_rom(conv_integer(wr_cnt_next_grey)); + wr_cnt_next_grey <= wr_cnt_next_grey_add_one; + + end if; + end if; + end process fifo_write_proc; + + --* add one to wr_cnt_gray + gray_adder_1 : gray_adder + generic map ( + width => C_FIFO_SIZE_WIDTH) + port map ( + in_gray => wr_cnt_grey, + out_gray => wr_cnt_gray_add_one); + + --* add one to wr_cnt_next_grey + gray_adder_2 : gray_adder + generic map ( + width => C_FIFO_SIZE_WIDTH) + port map ( + in_gray => wr_cnt_next_grey, + out_gray => wr_cnt_next_grey_add_one); + + +--* read counter generation + fifo_read_proc: process(rst, rd_clk) + begin + if (rst = '1') then + rd_cnt_grey <= (others => '0'); + rd_cnt <= (others => '0'); + elsif rising_edge(rd_clk) then + -- rd grey code counter + if (rd_en = '1') then + -- rd_cnt_grey <= add_grey_rom(conv_integer(rd_cnt_grey)); + rd_cnt_grey <= rd_cnt_grey_add_one; + rd_cnt <= rd_cnt+1; + end if; + end if; + end process fifo_read_proc; + + --* add one to rd_cnt_grey + gray_adder_3 : gray_adder + generic map ( + width => C_FIFO_SIZE_WIDTH) + port map ( + in_gray => rd_cnt_grey, + out_gray => rd_cnt_grey_add_one); + + + --* FIFO Memory + ram_1 : ram + generic map ( + C_FIFO_WIDTH => C_FIFO_WIDTH, + C_FIFO_SIZE_WIDTH => C_FIFO_SIZE_WIDTH) + port map ( + clk => wr_clk, + we => wr_en, + a => wr_cnt_grey, + di => din, + dpra => rd_cnt_grey, + dpo => dout); + + + --* generate overflow + gen_of_proc: process(rst, wr_clk) + begin + if (rst = '1') then + overflow <= '0'; + elsif rising_edge(wr_clk) then + if (full_int = '1' and wr_en = '1') then + overflow <= '1'; + end if; + end if; + end process gen_of_proc; + + --* generate underflow + gen_uf_proc: process(rst, rd_clk) + begin + if (rst = '1') then + underflow <= '0'; + elsif rising_edge(rd_clk) then + if (empty_int = '1' and rd_en = '1') then + underflow <= '1'; + end if; + end if; + end process gen_uf_proc; + + -- generate empty + empty_int <= '1' when (wr_cnt_grey = rd_cnt_grey) else + '0'; + + -- generate full + full_int <= '1' when (wr_cnt_next_grey = rd_cnt_grey) else + '0'; + + --* select clock side for flags + u1 : if (C_SYNC_TO = "WR") generate + --* sync flags to write clock + fifo_prog_flags_1 : fifo_prog_flags + generic map ( + C_FIFO_SIZE_WIDTH => C_FIFO_SIZE_WIDTH, + C_SYNC_TO => C_SYNC_TO) + port map ( + rst => rst, + clk => wr_clk, + cnt_grey => rd_cnt_grey, + cnt => wr_cnt, + prog_full_thresh => prog_full_thresh, + prog_empty_thresh => prog_empty_thresh, + prog_empty => prog_empty, + prog_full => prog_full); + end generate u1; + + u2 : if (C_SYNC_TO = "RD") generate + --* sync flags to read clock + fifo_prog_flags_1 : fifo_prog_flags + generic map ( + C_FIFO_SIZE_WIDTH => C_FIFO_SIZE_WIDTH, + C_SYNC_TO => C_SYNC_TO) + port map ( + rst => rst, + clk => rd_clk, + cnt_grey => wr_cnt_grey, + cnt => rd_cnt, + prog_full_thresh => prog_full_thresh, + prog_empty_thresh => prog_empty_thresh, + prog_empty => prog_empty, + prog_full => prog_full); + end generate u2; +end behavior; Index: trunk/pcore/opb_spi_slave_v1_00_a/hdl/vhdl/opb_spi_slave_pack.vhd =================================================================== --- trunk/pcore/opb_spi_slave_v1_00_a/hdl/vhdl/opb_spi_slave_pack.vhd (nonexistent) +++ trunk/pcore/opb_spi_slave_v1_00_a/hdl/vhdl/opb_spi_slave_pack.vhd (revision 2) @@ -0,0 +1,67 @@ +library ieee; +use ieee.std_logic_1164.all; +use IEEE.STD_LOGIC_ARITH.all; +use IEEE.STD_LOGIC_UNSIGNED.all; +use IEEE.numeric_std.all; -- conv_integer() + +package opb_spi_slave_pack is + + constant C_ADR_CTL : std_logic_vector(7 downto 2) := conv_std_logic_vector(16#0#, 6); + constant C_ADR_STATUS : std_logic_vector(7 downto 2) := conv_std_logic_vector(16#1#, 6); + constant C_ADR_TX_DATA : std_logic_vector(7 downto 2) := conv_std_logic_vector(16#2#, 6); + constant C_ADR_RX_DATA : std_logic_vector(7 downto 2) := conv_std_logic_vector(16#3#, 6); + constant C_ADR_TX_THRESH : std_logic_vector(7 downto 2) := conv_std_logic_vector(16#4#, 6); + constant C_ADR_RX_THRESH : std_logic_vector(7 downto 2) := conv_std_logic_vector(16#5#, 6); + constant C_ADR_TX_DMA_CTL : std_logic_vector(7 downto 2) := conv_std_logic_vector(16#6#, 6); + constant C_ADR_TX_DMA_ADDR : std_logic_vector(7 downto 2) := conv_std_logic_vector(16#7#, 6); + constant C_ADR_TX_DMA_NUM : std_logic_vector(7 downto 2) := conv_std_logic_vector(16#8#, 6); + constant C_ADR_RX_DMA_CTL : std_logic_vector(7 downto 2) := conv_std_logic_vector(16#9#, 6); + constant C_ADR_RX_DMA_ADDR : std_logic_vector(7 downto 2) := conv_std_logic_vector(16#A#, 6); + constant C_ADR_RX_DMA_NUM : std_logic_vector(7 downto 2) := conv_std_logic_vector(16#B#, 6); + +-- XIIF_V123B compatible + constant C_ADR_DGIE : std_logic_vector(7 downto 2) := conv_std_logic_vector(16#10#, 6); + constant C_ADR_ISR : std_logic_vector(7 downto 2) := conv_std_logic_vector(16#11#, 6); + constant C_ADR_IER : std_logic_vector(7 downto 2) := conv_std_logic_vector(16#12#, 6); + + constant C_NUM_FLG : integer := 15; + constant C_NUM_INT : integer := 10; + + +-- CTL_Register + -- width + constant C_OPB_CTL_REG_WIDTH : integer := 4; + -- bits + constant C_OPB_CTL_REG_DGE : integer := 0; + constant C_OPB_CTL_REG_TX_EN : integer := 1; + constant C_OPB_CTL_REG_RX_EN : integer := 2; + constant C_OPB_CTL_REG_RST : integer := 3; + + + -- Status Register + constant SPI_SR_Bit_TX_Prog_Full : integer := 0; + constant SPI_SR_Bit_TX_Full : integer := 1; + constant SPI_SR_Bit_TX_Overflow : integer := 2; + constant SPI_SR_Bit_TX_Prog_empty : integer := 3; + constant SPI_SR_Bit_TX_Empty : integer := 4; + constant SPI_SR_Bit_TX_Underflow : integer := 5; + + constant SPI_SR_Bit_RX_Prog_Full : integer := 6; + constant SPI_SR_Bit_RX_Full : integer := 7; + constant SPI_SR_Bit_RX_Overflow : integer := 8; + constant SPI_SR_Bit_RX_Prog_empty : integer := 9; + constant SPI_SR_Bit_RX_Empty : integer := 10; + constant SPI_SR_Bit_RX_Underflow : integer := 11; + + constant SPI_SR_Bit_SS_n : integer := 12; + + -- Interrupt Status Register + constant SPI_ISR_Bit_TX_Prog_Empty : integer := 0; + constant SPI_ISR_Bit_TX_Empty : integer := 1; + constant SPI_ISR_Bit_TX_Underflow : integer := 2; + constant SPI_ISR_Bit_RX_Prog_Full : integer := 3; + constant SPI_ISR_Bit_RX_Full : integer := 4; + constant SPI_ISR_Bit_RX_Overflow : integer := 5; + constant SPI_ISR_Bit_SS_Fall : integer := 6; + constant SPI_ISR_Bit_SS_Rise : integer := 7; +end opb_spi_slave_pack; Index: trunk/pcore/opb_spi_slave_v1_00_a/hdl/vhdl/opb_spi_slave.vhd =================================================================== --- trunk/pcore/opb_spi_slave_v1_00_a/hdl/vhdl/opb_spi_slave.vhd (nonexistent) +++ trunk/pcore/opb_spi_slave_v1_00_a/hdl/vhdl/opb_spi_slave.vhd (revision 2) @@ -0,0 +1,562 @@ +------------------------------------------------------------------------------- +--* +--* @short Top entity of the project opi_spi_slave +--* +--* @generic C_FAMILY virtex-4 and generic supported +--* @author: Daniel Köthe +--* @version: 1.0 +--* @date: 2007-11-11 +--/ +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use IEEE.STD_LOGIC_UNSIGNED.all; + + +library UNISIM; +use UNISIM.vcomponents.all; + +library work; +use work.opb_spi_slave_pack.all; + + +entity opb_spi_slave is + + generic ( + C_BASEADDR : std_logic_vector(0 to 31) := X"00000000"; + C_HIGHADDR : std_logic_vector(0 to 31) := X"FFFFFFFF"; + C_USER_ID_CODE : integer := 0; + C_OPB_AWIDTH : integer := 32; + C_OPB_DWIDTH : integer := 32; + + C_FAMILY : string := "virtex4"; + -- user ports + C_SR_WIDTH : integer := 8; + C_MSB_FIRST : boolean := true; + C_CPOL : integer range 0 to 1 := 0; + C_PHA : integer range 0 to 1 := 0; + C_FIFO_SIZE_WIDTH : integer range 4 to 7 := 5; -- depth 32 + C_DMA_EN : boolean := false); + + port ( + -- OPB signals (Slave Side) + OPB_ABus : in std_logic_vector(0 to C_OPB_AWIDTH-1); + OPB_BE : in std_logic_vector(0 to C_OPB_DWIDTH/8-1); + OPB_Clk : in std_logic; + OPB_DBus : in std_logic_vector(0 to C_OPB_DWIDTH-1); + OPB_RNW : in std_logic; + OPB_Rst : in std_logic; + OPB_select : in std_logic; + OPB_seqAddr : in std_logic; + Sln_DBus : out std_logic_vector(0 to C_OPB_DWIDTH-1); + Sln_errAck : out std_logic; + Sln_retry : out std_logic; + Sln_toutSup : out std_logic; + Sln_xferAck : out std_logic; + + -- OPB signals (Master Side) + -- Arbitration + M_request : out std_logic; + MOPB_MGrant : in std_logic; + M_busLock : out std_logic; + -- + M_ABus : out std_logic_vector(0 to C_OPB_AWIDTH-1); + M_BE : out std_logic_vector(0 to C_OPB_DWIDTH/8-1); + M_DBus : out std_logic_vector(0 to C_OPB_DWIDTH-1); + M_RNW : out std_logic; + M_select : out std_logic; + M_seqAddr : out std_logic; + MOPB_errAck : in std_logic; + MOPB_retry : in std_logic; + MOPB_timeout : in std_logic; + MOPB_xferAck : in std_logic; + -- spi ports + sclk : in std_logic; + ss_n : in std_logic; + mosi : in std_logic; + miso_o : out std_logic; + miso_i : in std_logic; + miso_t : out std_logic; + -- irq output + opb_irq : out std_logic); + +end opb_spi_slave; + +architecture behavior of opb_spi_slave is + + component opb_if + generic ( + C_BASEADDR : std_logic_vector(0 to 31); + C_HIGHADDR : std_logic_vector(0 to 31); + C_USER_ID_CODE : integer; + C_OPB_AWIDTH : integer; + C_OPB_DWIDTH : integer; + C_FAMILY : string; + C_SR_WIDTH : integer; + C_FIFO_SIZE_WIDTH : integer; + C_DMA_EN : boolean); + port ( + OPB_ABus : in std_logic_vector(0 to C_OPB_AWIDTH-1); + OPB_BE : in std_logic_vector(0 to C_OPB_DWIDTH/8-1); + OPB_Clk : in std_logic; + OPB_DBus : in std_logic_vector(0 to C_OPB_DWIDTH-1); + OPB_RNW : in std_logic; + OPB_Rst : in std_logic; + OPB_select : in std_logic; + OPB_seqAddr : in std_logic; + Sln_DBus : out std_logic_vector(0 to C_OPB_DWIDTH-1); + Sln_errAck : out std_logic; + Sln_retry : out std_logic; + Sln_toutSup : out std_logic; + Sln_xferAck : out std_logic; + opb_s_tx_en : out std_logic; + opb_s_tx_data : out std_logic_vector(C_SR_WIDTH-1 downto 0); + opb_s_rx_en : out std_logic; + opb_s_rx_data : in std_logic_vector(C_SR_WIDTH-1 downto 0); + opb_ctl_reg : out std_logic_vector(C_OPB_CTL_REG_WIDTH-1 downto 0); + tx_thresh : out std_logic_vector((2*C_FIFO_SIZE_WIDTH)-1 downto 0); + rx_thresh : out std_logic_vector((2*C_FIFO_SIZE_WIDTH)-1 downto 0); + opb_fifo_flg : in std_logic_vector(C_NUM_FLG-1 downto 0); + opb_dgie : out std_logic; + opb_ier : out std_logic_vector(C_NUM_INT-1 downto 0); + opb_isr : in std_logic_vector(C_NUM_INT-1 downto 0); + opb_isr_clr : out std_logic_vector(C_NUM_INT-1 downto 0); + opb_tx_dma_addr : out std_logic_vector(C_OPB_DWIDTH-1 downto 0); + opb_tx_dma_ctl : out std_logic_vector(0 downto 0); + opb_tx_dma_num : out std_logic_vector(15 downto 0); + opb_rx_dma_addr : out std_logic_vector(C_OPB_DWIDTH-1 downto 0); + opb_rx_dma_ctl : out std_logic_vector(0 downto 0); + opb_rx_dma_num : out std_logic_vector(15 downto 0)); + end component; + + + component opb_m_if + generic ( + C_BASEADDR : std_logic_vector(0 to 31); + C_HIGHADDR : std_logic_vector(0 to 31); + C_USER_ID_CODE : integer; + C_OPB_AWIDTH : integer; + C_OPB_DWIDTH : integer; + C_FAMILY : string; + C_SR_WIDTH : integer; + C_MSB_FIRST : boolean; + C_CPOL : integer range 0 to 1; + C_PHA : integer range 0 to 1; + C_FIFO_SIZE_WIDTH : integer range 4 to 7); + port ( + OPB_Clk : in std_logic; + OPB_Rst : in std_logic; + OPB_DBus : in std_logic_vector(0 to C_OPB_DWIDTH-1); + M_request : out std_logic; + MOPB_MGrant : in std_logic; + M_busLock : out std_logic; + M_ABus : out std_logic_vector(0 to C_OPB_AWIDTH-1); + M_BE : out std_logic_vector(0 to C_OPB_DWIDTH/8-1); + M_DBus : out std_logic_vector(0 to C_OPB_DWIDTH-1); + M_RNW : out std_logic; + M_select : out std_logic; + M_seqAddr : out std_logic; + MOPB_errAck : in std_logic; + MOPB_retry : in std_logic; + MOPB_timeout : in std_logic; + MOPB_xferAck : in std_logic; + opb_m_tx_req : in std_logic; + opb_m_tx_en : out std_logic; + opb_m_tx_data : out std_logic_vector(C_SR_WIDTH-1 downto 0); + opb_tx_dma_ctl : in std_logic_vector(0 downto 0); + opb_tx_dma_addr : in std_logic_vector(C_OPB_DWIDTH-1 downto 0); + opb_tx_dma_num : in std_logic_vector(15 downto 0); + opb_tx_dma_done : out std_logic; + opb_m_rx_req : in std_logic; + opb_m_rx_en : out std_logic; + opb_m_rx_data : in std_logic_vector(C_SR_WIDTH-1 downto 0); + opb_rx_dma_ctl : in std_logic_vector(0 downto 0); + opb_rx_dma_addr : in std_logic_vector(C_OPB_DWIDTH-1 downto 0); + opb_rx_dma_num : in std_logic_vector(15 downto 0); + opb_rx_dma_done : out std_logic); + end component; + + component shift_register + generic ( + C_SR_WIDTH : integer; + C_MSB_FIRST : boolean; + C_CPOL : integer range 0 to 1; + C_PHA : integer range 0 to 1); + port ( + rst : in std_logic; + opb_ctl_reg : in std_logic_vector(C_OPB_CTL_REG_WIDTH-1 downto 0); + sclk : in std_logic; + ss_n : in std_logic; + mosi : in std_logic; + miso_o : out std_logic; + miso_i : in std_logic; + miso_t : out std_logic; + sr_tx_clk : out std_logic; + sr_tx_en : out std_logic; + sr_tx_data : in std_logic_vector(C_SR_WIDTH-1 downto 0); + sr_rx_clk : out std_logic; + sr_rx_en : out std_logic; + sr_rx_data : out std_logic_vector(C_SR_WIDTH-1 downto 0)); + end component; + + component fifo + generic ( + C_FIFO_WIDTH : integer; + C_FIFO_SIZE_WIDTH : integer; + C_SYNC_TO : string); + port ( + rst : in std_logic; + wr_clk : in std_logic; + wr_en : in std_logic; + din : in std_logic_vector(C_SR_WIDTH-1 downto 0); + rd_clk : in std_logic; + rd_en : in std_logic; + dout : out std_logic_vector(C_SR_WIDTH-1 downto 0); + empty : out std_logic; + full : out std_logic; + overflow : out std_logic; + underflow : out std_logic; + prog_empty_thresh : in std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); + prog_full_thresh : in std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); + prog_empty : out std_logic; + prog_full : out std_logic); + end component; + + component irq_ctl + generic ( + C_ACTIVE_EDGE : std_logic); + port ( + rst : in std_logic; + clk : in std_logic; + opb_fifo_flg : in std_logic; + opb_ier : in std_logic; + opb_isr : out std_logic; + opb_isr_clr : in std_logic); + end component; + +-- opb_if + signal opb_ctl_reg : std_logic_vector(C_OPB_CTL_REG_WIDTH-1 downto 0); + + signal opb_s_tx_en : std_logic; + signal opb_s_tx_data : std_logic_vector(C_SR_WIDTH-1 downto 0); + signal opb_s_rx_en : std_logic; + signal opb_s_rx_data : std_logic_vector(C_SR_WIDTH-1 downto 0); + + signal tx_thresh : std_logic_vector((2*C_FIFO_SIZE_WIDTH)-1 downto 0); + signal rx_thresh : std_logic_vector((2*C_FIFO_SIZE_WIDTH)-1 downto 0); + + signal opb_tx_dma_addr : std_logic_vector(C_OPB_DWIDTH-1 downto 0); + signal opb_tx_dma_ctl : std_logic_vector(0 downto 0); + signal opb_tx_dma_num : std_logic_vector(15 downto 0); + signal opb_rx_dma_addr : std_logic_vector(C_OPB_DWIDTH-1 downto 0); + signal opb_rx_dma_ctl : std_logic_vector(0 downto 0); + signal opb_rx_dma_num : std_logic_vector(15 downto 0); + + -- opb_m_if + signal opb_m_tx_en : std_logic; + signal opb_m_tx_data : std_logic_vector(C_SR_WIDTH-1 downto 0); + signal opb_m_rx_en : std_logic; + signal opb_m_rx_data : std_logic_vector(C_SR_WIDTH-1 downto 0); + +-- shift_register + signal sr_tx_clk : std_logic; + signal sr_tx_en : std_logic; + signal sr_tx_data : std_logic_vector(C_SR_WIDTH-1 downto 0); + signal sr_rx_clk : std_logic; + signal sr_rx_en : std_logic; + signal sr_rx_data : std_logic_vector(C_SR_WIDTH-1 downto 0); + + signal sclk_ibuf : std_logic; + signal sclk_bufr : std_logic; + + signal opb_fifo_flg : std_logic_vector(C_NUM_FLG-1 downto 0); + signal opb_irq_flg : std_logic_vector(C_NUM_INT-1 downto 0) := (others => '0'); + signal rst : std_logic; + + + signal opb_dgie : std_logic; + signal opb_ier : std_logic_vector(C_NUM_INT-1 downto 0); + signal opb_isr : std_logic_vector(C_NUM_INT-1 downto 0); + signal opb_isr_clr : std_logic_vector(C_NUM_INT-1 downto 0); + + -- opb_spi_slave + signal fifo_tx_en : std_logic; + signal fifo_tx_data : std_logic_vector(C_SR_WIDTH-1 downto 0); + signal fifo_rx_en : std_logic; + signal fifo_rx_data : std_logic_vector(C_SR_WIDTH-1 downto 0); + +begin -- behavior + + --* + virtex4_slk_buf : if C_FAMILY = "virtex4" generate + --* If C_FAMILY=Virtex-4 use "IBUF" + IBUF_1 : IBUF + port map ( + I => sclk, + O => sclk_ibuf); + +--* If C_FAMILY=Virtex-4 use "BUFR" + BUFR_1 : BUFR + generic map ( + BUFR_DIVIDE => "BYPASS", + SIM_DEVICE => "VIRTEX4") + port map ( + O => sclk_bufr, + CE => '0', + CLR => '0', + I => sclk_ibuf); + end generate virtex4_slk_buf; + + generic_sclk_buf : if C_FAMILY /= "virtex4" generate + sclk_bufr <= sclk; + end generate generic_sclk_buf; + + --* OPB-Slave Interface(Register-Interface) + opb_if_2 : opb_if + generic map ( + C_BASEADDR => C_BASEADDR, + C_HIGHADDR => C_HIGHADDR, + C_USER_ID_CODE => C_USER_ID_CODE, + C_OPB_AWIDTH => C_OPB_AWIDTH, + C_OPB_DWIDTH => C_OPB_DWIDTH, + C_FAMILY => C_FAMILY, + C_SR_WIDTH => C_SR_WIDTH, + C_FIFO_SIZE_WIDTH => C_FIFO_SIZE_WIDTH, + C_DMA_EN => C_DMA_EN) + port map ( + OPB_ABus => OPB_ABus, + OPB_BE => OPB_BE, + OPB_Clk => OPB_Clk, + OPB_DBus => OPB_DBus, + OPB_RNW => OPB_RNW, + OPB_Rst => OPB_Rst, + OPB_select => OPB_select, + OPB_seqAddr => OPB_seqAddr, + Sln_DBus => Sln_DBus, + Sln_errAck => Sln_errAck, + Sln_retry => Sln_retry, + Sln_toutSup => Sln_toutSup, + Sln_xferAck => Sln_xferAck, + opb_s_tx_en => opb_s_tx_en, + opb_s_tx_data => opb_s_tx_data, + opb_s_rx_en => opb_s_rx_en, + opb_s_rx_data => opb_s_rx_data, + opb_ctl_reg => opb_ctl_reg, + tx_thresh => tx_thresh, + rx_thresh => rx_thresh, + opb_fifo_flg => opb_fifo_flg, + opb_dgie => opb_dgie, + opb_ier => opb_ier, + opb_isr => opb_isr, + opb_isr_clr => opb_isr_clr, + opb_tx_dma_addr => opb_tx_dma_addr, + opb_tx_dma_ctl => opb_tx_dma_ctl, + opb_tx_dma_num => opb_tx_dma_num, + opb_rx_dma_addr => opb_rx_dma_addr, + opb_rx_dma_ctl => opb_rx_dma_ctl, + opb_rx_dma_num => opb_rx_dma_num); + + --* OPB-Master-Interface + --* + --* (DMA Read/Write Transfers to TX/RX-FIFO) + + dma_enable : if (C_DMA_EN = true) generate + opb_m_if_1 : opb_m_if + generic map ( + C_BASEADDR => C_BASEADDR, + C_HIGHADDR => C_HIGHADDR, + C_USER_ID_CODE => C_USER_ID_CODE, + C_OPB_AWIDTH => C_OPB_AWIDTH, + C_OPB_DWIDTH => C_OPB_DWIDTH, + C_FAMILY => C_FAMILY, + C_SR_WIDTH => C_SR_WIDTH, + C_MSB_FIRST => C_MSB_FIRST, + C_CPOL => C_CPOL, + C_PHA => C_PHA, + C_FIFO_SIZE_WIDTH => C_FIFO_SIZE_WIDTH) + port map ( + OPB_Clk => OPB_Clk, + OPB_Rst => OPB_Rst, + OPB_DBus => OPB_DBus, + M_request => M_request, + MOPB_MGrant => MOPB_MGrant, + M_busLock => M_busLock, + M_ABus => M_ABus, + M_BE => M_BE, + M_DBus => M_DBus, + M_RNW => M_RNW, + M_select => M_select, + M_seqAddr => M_seqAddr, + MOPB_errAck => MOPB_errAck, + MOPB_retry => MOPB_retry, + MOPB_timeout => MOPB_timeout, + MOPB_xferAck => MOPB_xferAck, + opb_m_tx_req => opb_fifo_flg(3), + opb_m_tx_en => opb_m_tx_en, + opb_m_tx_data => opb_m_tx_data, + opb_tx_dma_ctl => opb_tx_dma_ctl, + opb_tx_dma_addr => opb_tx_dma_addr, + opb_tx_dma_num => opb_tx_dma_num, + opb_tx_dma_done => opb_fifo_flg(13), + opb_m_rx_req => opb_fifo_flg(6), + opb_m_rx_en => opb_m_rx_en, + opb_m_rx_data => opb_m_rx_data, + opb_rx_dma_ctl => opb_rx_dma_ctl, + opb_rx_dma_addr => opb_rx_dma_addr, + opb_rx_dma_num => opb_rx_dma_num, + opb_rx_dma_done => opb_fifo_flg(14)); + end generate dma_enable; + + dma_disable : if (C_DMA_EN = false) generate + M_request <= '0'; + M_busLock <= '0'; + M_ABus <= (others => '0'); + M_BE <= (others => '0'); + M_DBus <= (others => '0'); + M_RNW <= '0'; + M_select <= '0'; + M_seqAddr <= '0'; + opb_m_tx_en <= '0'; + opb_m_tx_data <= (others => '0'); + opb_fifo_flg(13) <= '0'; + opb_m_rx_en <= '0'; + opb_fifo_flg(14) <= '0'; + end generate dma_disable; + + --* Shift-Register + shift_register_1 : shift_register + generic map ( + C_SR_WIDTH => C_SR_WIDTH, + C_MSB_FIRST => C_MSB_FIRST, + C_CPOL => C_CPOL, + C_PHA => C_PHA) + port map ( + rst => rst, + opb_ctl_reg => opb_ctl_reg, + sclk => sclk_bufr, + ss_n => ss_n, + mosi => mosi, + miso_o => miso_o, + miso_i => miso_i, + miso_t => miso_t, + sr_tx_clk => sr_tx_clk, + sr_tx_en => sr_tx_en, + sr_tx_data => sr_tx_data, + sr_rx_clk => sr_rx_clk, + sr_rx_en => sr_rx_en, + sr_rx_data => sr_rx_data); + + --* Transmit FIFO + tx_fifo_1 : fifo + generic map ( + C_FIFO_WIDTH => C_SR_WIDTH, + C_FIFO_SIZE_WIDTH => C_FIFO_SIZE_WIDTH, + C_SYNC_TO => "WR") + port map ( + -- global + rst => rst, + prog_full_thresh => tx_thresh(C_FIFO_SIZE_WIDTH-1 downto 0), + prog_empty_thresh => tx_thresh((2*C_FIFO_SIZE_WIDTH)-1 downto C_FIFO_SIZE_WIDTH), + -- write port + wr_clk => OPB_Clk, + wr_en => fifo_tx_en, + din => fifo_tx_data, + -- flags + prog_full => opb_fifo_flg(0), + full => opb_fifo_flg(1), + overflow => opb_fifo_flg(2), + -- read port + rd_clk => sr_tx_clk, + rd_en => sr_tx_en, + dout => sr_tx_data, + -- flags + prog_empty => opb_fifo_flg(3), + empty => opb_fifo_flg(4), + underflow => opb_fifo_flg(5)); + + fifo_tx_en <= opb_s_tx_en or opb_m_tx_en; + fifo_tx_data <= opb_m_tx_data when (opb_tx_dma_ctl(0) = '1') else + opb_s_tx_data; + + --* Receive FIFO + rx_fifo_1 : fifo + generic map ( + C_FIFO_WIDTH => C_SR_WIDTH, + C_FIFO_SIZE_WIDTH => C_FIFO_SIZE_WIDTH, + C_SYNC_TO => "RD") + port map ( + -- global + rst => rst, + prog_full_thresh => rx_thresh(C_FIFO_SIZE_WIDTH-1 downto 0), + prog_empty_thresh => rx_thresh((2*C_FIFO_SIZE_WIDTH)-1 downto C_FIFO_SIZE_WIDTH), + -- write port + wr_clk => sr_rx_clk, + wr_en => sr_rx_en, + din => sr_rx_data, + -- flags + prog_full => opb_fifo_flg(6), + full => opb_fifo_flg(7), + overflow => opb_fifo_flg(8), + -- read port + rd_clk => opb_clk, + rd_en => fifo_rx_en, + dout => fifo_rx_data, + -- flags + prog_empty => opb_fifo_flg(9), + empty => opb_fifo_flg(10), + underflow => opb_fifo_flg(11)); + + fifo_rx_en <= opb_s_rx_en or opb_m_rx_en; + opb_s_rx_data <= fifo_rx_data; + opb_m_rx_data <= fifo_rx_data; + + rst <= OPB_Rst or opb_ctl_reg(C_OPB_CTL_REG_RST); + + opb_fifo_flg(12) <= ss_n; + + + + + -- Bit 0 : TX_PROG_EMPTY + opb_irq_flg(0) <= opb_fifo_flg(3); + -- Bit 1 : TX_EMPTY + opb_irq_flg(1) <= opb_fifo_flg(4); + -- Bit 2 : TX_Underflow + opb_irq_flg(2) <= opb_fifo_flg(5); + -- Bit 3 : RX_PROG_FULL + opb_irq_flg(3) <= opb_fifo_flg(6); + -- Bit 4 : RX_FULL + opb_irq_flg(4) <= opb_fifo_flg(7); + -- Bit 5 : RX_Overflow + opb_irq_flg(5) <= opb_fifo_flg(9); + -- Bit 6: CS_H_TO_L + opb_irq_flg(6) <= not opb_fifo_flg(12); + -- Bit 7: CS_L_TO_H + opb_irq_flg(7) <= opb_fifo_flg(12); + -- Bit 8: TX DMA Done + opb_irq_flg(8) <= opb_fifo_flg(13); + -- Bit 9: RX DMA Done + opb_irq_flg(9) <= opb_fifo_flg(14); + + --* IRQ Enable, Detection and Flags Control + irq_gen : for i in 0 to C_NUM_INT-1 generate + irq_ctl_1 : irq_ctl + generic map ( + C_ACTIVE_EDGE => '1') + port map ( + rst => rst, + clk => OPB_Clk, + opb_fifo_flg => opb_irq_flg(i), + opb_ier => opb_ier(i), + opb_isr => opb_isr(i), + opb_isr_clr => opb_isr_clr(i)); + end generate irq_gen; + + -- assert irq if one Interupt Status bit set + opb_irq <= '1' when (conv_integer(opb_isr) /= 0 and opb_dgie = '1') else + '0'; + + + +end behavior; Index: trunk/pcore/opb_spi_slave_v1_00_a/hdl/vhdl/fifo_prog_flags.vhd =================================================================== --- trunk/pcore/opb_spi_slave_v1_00_a/hdl/vhdl/fifo_prog_flags.vhd (nonexistent) +++ trunk/pcore/opb_spi_slave_v1_00_a/hdl/vhdl/fifo_prog_flags.vhd (revision 2) @@ -0,0 +1,96 @@ +------------------------------------------------------------------------------- +--* +--* @short Generate fifo flags +--* +--* @generic C_FIFO_SIZE_WIDTH RAM Size = 2**C_FIFO_SIZE_WIDTH +--* @generic C_SYNC_TO Sync FIFO Flags to read or write clock +--* +--* @author: Daniel Köthe +--* @version: 1.0 +--* @date: 2007-11-11 +--/ +------------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; +use ieee.std_logic_arith.all; + + +entity fifo_prog_flags is + generic ( + C_FIFO_SIZE_WIDTH : integer := 4; + C_SYNC_TO : string := "WR"); + port ( + rst : in std_logic; + clk : in std_logic; + cnt_grey : in std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); + cnt : in std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); + prog_full_thresh : in std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); + prog_empty_thresh : in std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); + prog_empty : out std_logic; + prog_full : out std_logic); + +end fifo_prog_flags; +architecture behavior of fifo_prog_flags is + + -- sync register for clock domain transfer + signal cnt_grey_reg : std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); + + type rom_t is array (0 to (2**C_FIFO_SIZE_WIDTH)-1) of std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); + + --* convert from gray to binary + component gray2bin + generic ( + width : integer); + port ( + in_gray : in std_logic_vector(width-1 downto 0); + out_bin : out std_logic_vector(width-1 downto 0)); + end component; + + signal cnt_bin_reg : std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); + +begin -- behavior + + --* Generate fifo flags + gen_flags_proc: process(rst, clk) + variable diff : std_logic_vector(C_FIFO_SIZE_WIDTH-1 downto 0); + begin + if (rst = '1') then + cnt_grey_reg <= (others => '0'); + prog_empty <= '1'; + prog_full <= '0'; + elsif rising_edge(clk) then + -- transfer to rd_clk domain + cnt_grey_reg <= cnt_grey; + -- fifo prog full/empty + if (C_SYNC_TO = "RD") then + -- diff := conv_grey_rom(conv_integer(cnt_grey_reg))- cnt; + diff := cnt_bin_reg - cnt; + else + -- diff := cnt - conv_grey_rom(conv_integer(cnt_grey_reg)); + diff := cnt - cnt_bin_reg; + end if; + + if (diff > prog_full_thresh) then + prog_full <= '1'; + else + prog_full <= '0'; + end if; + + if (diff < prog_empty_thresh) then + prog_empty <= '1'; + else + prog_empty <= '0'; + end if; + end if; + end process gen_flags_proc; + + --* convert gray to bin + gray2bin_1: gray2bin + generic map ( + width => C_FIFO_SIZE_WIDTH) + port map ( + in_gray => cnt_grey_reg, + out_bin => cnt_bin_reg); + +end behavior; Index: trunk/pcore/opb_spi_slave_v1_00_a/hdl/vhdl/opb_m_if.vhd =================================================================== --- trunk/pcore/opb_spi_slave_v1_00_a/hdl/vhdl/opb_m_if.vhd (nonexistent) +++ trunk/pcore/opb_spi_slave_v1_00_a/hdl/vhdl/opb_m_if.vhd (revision 2) @@ -0,0 +1,300 @@ +------------------------------------------------------------------------------- +--* +--* @short OPB-Master Interface +--* +--* Generics described in top entity. +--* +--* @see opb_spi_slave +--* @author: Daniel Köthe +--* @version: 1.0 +--* @date: 2007-11-11 +--/ +------------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; +use IEEE.STD_LOGIC_ARITH.all; +use IEEE.STD_LOGIC_UNSIGNED.all; +use IEEE.numeric_std.all; -- conv_integer() + +entity opb_m_if is + generic ( + C_BASEADDR : std_logic_vector(0 to 31) := X"00000000"; + C_HIGHADDR : std_logic_vector(0 to 31) := X"FFFFFFFF"; + C_USER_ID_CODE : integer := 0; + C_OPB_AWIDTH : integer := 32; + C_OPB_DWIDTH : integer := 32; + C_FAMILY : string := "virtex-4"; + C_SR_WIDTH : integer := 8; + C_MSB_FIRST : boolean := true; + C_CPOL : integer range 0 to 1 := 0; + C_PHA : integer range 0 to 1 := 0; + C_FIFO_SIZE_WIDTH : integer range 4 to 7 := 7); + + port ( + -- opb master interface + OPB_Clk : in std_logic; + OPB_Rst : in std_logic; + OPB_DBus : in std_logic_vector(0 to C_OPB_DWIDTH-1); + M_request : out std_logic; + MOPB_MGrant : in std_logic; + M_busLock : out std_logic; + M_ABus : out std_logic_vector(0 to C_OPB_AWIDTH-1); + M_BE : out std_logic_vector(0 to C_OPB_DWIDTH/8-1); + M_DBus : out std_logic_vector(0 to C_OPB_DWIDTH-1); + M_RNW : out std_logic; + M_select : out std_logic; + M_seqAddr : out std_logic; + MOPB_errAck : in std_logic; + MOPB_retry : in std_logic; + MOPB_timeout : in std_logic; + MOPB_xferAck : in std_logic; + --------------------------------------------------------------------------- + -- read transfer + -- read data from memory and fill fifo + opb_m_tx_req : in std_logic; + opb_m_tx_en : out std_logic; + opb_m_tx_data : out std_logic_vector(C_SR_WIDTH-1 downto 0); + -- enable/disable dma transfer + opb_tx_dma_ctl : in std_logic_vector(0 downto 0); + -- base adress for transfer + opb_tx_dma_addr : in std_logic_vector(C_OPB_DWIDTH-1 downto 0); + opb_tx_dma_num : in std_logic_vector(15 downto 0); + opb_tx_dma_done : out std_logic; + --------------------------------------------------------------------------- + -- write transfer + -- read fifo an write to memory + opb_m_rx_req : in std_logic; + opb_m_rx_en : out std_logic; + opb_m_rx_data : in std_logic_vector(C_SR_WIDTH-1 downto 0); + -- enable/disable dma transfer + opb_rx_dma_ctl : in std_logic_vector(0 downto 0); + -- base adress for transfer + opb_rx_dma_addr : in std_logic_vector(C_OPB_DWIDTH-1 downto 0); + opb_rx_dma_num : in std_logic_vector(15 downto 0); + opb_rx_dma_done : out std_logic); +end opb_m_if; + +architecture behavior of opb_m_if is + + type state_t is (idle, + wait_grant, + transfer_write, + transfer_read, + done); + + + signal state : state_t := idle; + + signal M_DBus_big_end : std_logic_vector(C_OPB_DWIDTH-1 downto 0); + signal M_ABus_big_end : std_logic_vector(C_OPB_DWIDTH-1 downto 0); + signal OPB_DBus_big_end : std_logic_vector(C_OPB_DWIDTH-1 downto 0); + + signal M_select_int : std_logic; + signal read_transfer : boolean; + + -- read transfer + signal opb_tx_dma_addr_int : std_logic_vector(C_OPB_DWIDTH-1 downto 0); + signal opb_tx_dma_en : std_logic; + signal opb_tx_dma_num_int : std_logic_vector(15 downto 0); + signal opb_tx_dma_done_int : std_logic; + + -- write transfer + signal opb_rx_dma_en : std_logic; + signal opb_rx_dma_addr_int : std_logic_vector(C_OPB_DWIDTH-1 downto 0); + signal opb_rx_dma_num_int : std_logic_vector(15 downto 0); + signal opb_rx_dma_done_int : std_logic; + + + +begin -- behavior + + --* convert M_DBus_big_end to little endian + process(M_DBus_big_end) + begin + for i in 0 to 31 loop + M_DBus(31-i) <= M_DBus_big_end(i); + end loop; -- i + end process; + + --* convert M_ABus_big_end to little endian + process(M_ABus_big_end) + begin + for i in 0 to 31 loop + M_ABus(31-i) <= M_ABus_big_end(i); + end loop; -- i + end process; + + --* convert OPB_DBus to bi endian + process(OPB_DBus) + begin + for i in 0 to 31 loop + OPB_DBus_big_end(31-i) <= OPB_DBus(i); + end loop; -- i + end process; + + -- for both sides + M_ABus_big_end <= opb_tx_dma_addr_int when (M_select_int = '1' and (read_transfer = true)) else + opb_rx_dma_addr_int when (M_select_int = '1' and (read_transfer = false)) else + (others => '0'); + M_select <= M_select_int; + + + + -- write transfer + opb_m_rx_en <= MOPB_xferAck when (M_select_int = '1' and (read_transfer = false)) else + '0'; + + M_DBus_big_end(C_SR_WIDTH-1 downto 0) <= opb_m_rx_data when (M_select_int = '1' and (read_transfer = false)) else + (others => '0'); + M_DBus_big_end(C_OPB_DWIDTH-1 downto C_SR_WIDTH) <= (others => '0'); + + opb_tx_dma_done <= opb_tx_dma_done_int; + + -- read transfer + opb_m_tx_en <= MOPB_xferAck when (M_select_int = '1' and (read_transfer = true)) else + '0'; + opb_m_tx_data <= OPB_DBus_big_end(C_SR_WIDTH-1 downto 0); + + opb_rx_dma_done <= opb_rx_dma_done_int; + + + +------------------------------------------------------------------------------- + opb_masteer_proc: process(OPB_Rst, OPB_Clk) + begin + if (OPB_Rst = '1') then + M_BE <= (others => '0'); + M_busLock <= '0'; + M_request <= '0'; + M_RNW <= '0'; + M_select_int <= '0'; + M_seqAddr <= '0'; + opb_tx_dma_done_int <= '0'; + opb_rx_dma_done_int <= '0'; + elsif rising_edge(OPB_Clk) then + case state is + when idle => + opb_tx_dma_en <= opb_tx_dma_ctl(0); + opb_rx_dma_en <= opb_rx_dma_ctl(0); + + if (opb_tx_dma_ctl(0) = '1' and opb_tx_dma_en = '0') then + opb_tx_dma_addr_int <= opb_tx_dma_addr; + opb_tx_dma_num_int <= opb_tx_dma_num; + opb_tx_dma_done_int <= '0'; + + end if; + + if (opb_rx_dma_ctl(0) = '1' and opb_rx_dma_en = '0') then + opb_rx_dma_addr_int <= opb_rx_dma_addr; + opb_rx_dma_num_int <= opb_rx_dma_num; + opb_rx_dma_done_int <= '0'; + end if; + + if (opb_tx_dma_en = '1' and opb_m_tx_req = '1' and opb_tx_dma_done_int = '0') then + -- read from memory to fifo + M_request <= '1'; + read_transfer <= true; + state <= wait_grant; + elsif (opb_rx_dma_en = '1' and opb_m_rx_req = '1'and opb_rx_dma_done_int = '0') then + -- read from fifo and write memory + M_request <= '1'; + read_transfer <= false; + state <= wait_grant; + else + state <= idle; + end if; + + when wait_grant => + if (MOPB_MGrant = '1') then + M_request <= '0'; + M_busLock <= '1'; + M_select_int <= '1'; + M_seqAddr <= '1'; + M_BE <= "1111"; + if (read_transfer) then + -- read + M_RNW <= '1'; + state <= transfer_read; + else + -- write + M_RNW <= '0'; + state <= transfer_write; + end if; + else + state <= wait_grant; + end if; + + when transfer_read => + if (MOPB_xferAck = '1') then + opb_tx_dma_addr_int <= opb_tx_dma_addr_int +4; + if (opb_tx_dma_addr_int(5 downto 2) = conv_std_logic_vector(14, 4)) then + -- cycle 14 + -- deassert buslock and seq_address 1 cycle before transfer complete + M_busLock <= '0'; + M_seqAddr <= '0'; + elsif (opb_tx_dma_addr_int(5 downto 2) = conv_std_logic_vector(15, 4)) then + -- cycle 15 + M_RNW <= '0'; + M_select_int <= '0'; + M_BE <= (others => '0'); + if (conv_integer(opb_tx_dma_num_int) = 0) then + opb_tx_dma_done_int <= '1'; + else + opb_tx_dma_num_int <= opb_tx_dma_num_int-1; + end if; + state <= done; + end if; + elsif (MOPB_retry = '1' or MOPB_errAck = '1' or MOPB_timeout = '1') then + -- cancel transfer + M_busLock <= '0'; + M_seqAddr <= '0'; + M_RNW <= '0'; + M_select_int <= '0'; + M_BE <= (others => '0'); + state <= done; + else + state <= transfer_read; + end if; + + when transfer_write => + if (MOPB_xferAck = '1') then + opb_rx_dma_addr_int <= opb_rx_dma_addr_int +4; + if (opb_rx_dma_addr_int(5 downto 2) = conv_std_logic_vector(14, 4)) then + -- cycle 14 + -- deassert buslock and seq_address 1 cycle before transfer complete + M_busLock <= '0'; + M_seqAddr <= '0'; + elsif (opb_rx_dma_addr_int(5 downto 2) = conv_std_logic_vector(15, 4)) then + -- cycle 15 + M_RNW <= '0'; + M_select_int <= '0'; + M_BE <= (others => '0'); + if (conv_integer(opb_rx_dma_num_int) = 0) then + opb_rx_dma_done_int <= '1'; + else + opb_rx_dma_num_int <= opb_rx_dma_num_int-1; + end if; + state <= done; + end if; + elsif (MOPB_retry = '1' or MOPB_errAck = '1' or MOPB_timeout = '1') then + -- cancel transfer + M_busLock <= '0'; + M_seqAddr <= '0'; + M_RNW <= '0'; + M_select_int <= '0'; + M_BE <= (others => '0'); + state <= done; + else + state <= transfer_write; + end if; + + when done => + + state <= idle; + + when others => + state <= idle; + end case; + end if; + end process opb_masteer_proc; +end behavior; Index: trunk/pcore/opb_spi_slave_v1_00_a/hdl/vhdl/bin2gray.vhd =================================================================== --- trunk/pcore/opb_spi_slave_v1_00_a/hdl/vhdl/bin2gray.vhd (nonexistent) +++ trunk/pcore/opb_spi_slave_v1_00_a/hdl/vhdl/bin2gray.vhd (revision 2) @@ -0,0 +1,45 @@ +------------------------------------------------------------------------------- +--* +--* @short convert binary input vector to gray +--* +--* @generic width with of input vector +--* +--* @author: Daniel Köthe +--* @version: 1.0 +--* @date: 2007-11-11 +--/ +------------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; +use ieee.std_logic_arith.all; + +entity bin2gray is + generic ( + width : integer := 4); + port ( + in_bin : in std_logic_vector(width-1 downto 0); + out_gray : out std_logic_vector(width-1 downto 0)); +end bin2gray; + +architecture behavior of bin2gray is + +begin -- behavior + + -- Sequence: 0,1,3,2,6,7,5,4,C,D,F,E,A,B,9,8 + --* convert binary input vector to gray + bin2gray_proc : process(in_bin) + begin + out_gray(width-1) <= in_bin(width-1); + -- out_gray(3) <= in_bin(3); + + for i in 1 to width-1 loop + out_gray(width-1-i) <= in_bin(width-i) xor in_bin(width-1-i); + end loop; -- i + end process bin2gray_proc; + + -- i=1 out_gray(2) <= in_bin(3) xor in_bin(2); + -- i=2 out_gray(1) <= in_bin(2) xor in_bin(1); + -- i=3 out_gray(0) <= in_bin(1) xor in_bin(0); + +end behavior; Index: trunk/pcore/opb_spi_slave_v1_00_a/hdl/vhdl/gray2bin.vhd =================================================================== --- trunk/pcore/opb_spi_slave_v1_00_a/hdl/vhdl/gray2bin.vhd (nonexistent) +++ trunk/pcore/opb_spi_slave_v1_00_a/hdl/vhdl/gray2bin.vhd (revision 2) @@ -0,0 +1,45 @@ +------------------------------------------------------------------------------- +--* +--* @short convert gray input vector to binary +--* +--* @generic width with of input vector +--* +--* @author: Daniel Köthe +--* @version: 1.0 +--* @date: 2007-11-11 +--/ +------------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; +use ieee.std_logic_arith.all; + +entity gray2bin is + generic ( + width : integer := 4); + port ( + in_gray : in std_logic_vector(width-1 downto 0); + out_bin : out std_logic_vector(width-1 downto 0)); +end gray2bin; + +architecture behavior of gray2bin is + + signal out_bin_int : std_logic_vector(width-1 downto 0); +begin -- behavior + + out_bin <= out_bin_int; + + -- Sequence: 0,1,3,2,6,7,5,4,C,D,F,E,A,B,9,8 + --* convert gray input vector to binary + gray2bin_proc: process(in_gray, out_bin_int) + begin + out_bin_int(width-1) <= in_gray(width-1); + -- out_gray(3) <= in_gray(3); + for i in 1 to width-1 loop + out_bin_int(width-1-i) <= out_bin_int(width-i) xor in_gray(width-1-i); + end loop ; -- i + end process gray2bin_proc; + -- i=1 out_bin(2) <= out_bin_int(3) xor out_bin(2); + -- i=2 out_bin(1) <= out_bin_int(2) xor out_bin(1); + -- i=3 out_bin(0) <= out_bin_int(1) xor out_bin(0); +end behavior; Index: trunk/pcore/opb_spi_slave_v1_00_a/hdl/vhdl/irq_ctl.vhd =================================================================== --- trunk/pcore/opb_spi_slave_v1_00_a/hdl/vhdl/irq_ctl.vhd (nonexistent) +++ trunk/pcore/opb_spi_slave_v1_00_a/hdl/vhdl/irq_ctl.vhd (revision 2) @@ -0,0 +1,52 @@ +------------------------------------------------------------------------------- +--* +--* @short Control Unit for IRQ detection, enable and clear +--* +--* @generic C_ACTIVE_EDGE Select active edge for IRQ-Source 0: H->L;1: L->H +--* +--* @author: Daniel Köthe +--* @version: 1.0 +--* @date: 2007-11-11 +--/ +------------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; + +entity irq_ctl is + generic ( + C_ACTIVE_EDGE : std_logic := '0'); + port ( + rst : in std_logic; + clk : in std_logic; + opb_fifo_flg : in std_logic; + opb_ier : in std_logic; + opb_isr : out std_logic; + opb_isr_clr : in std_logic); + +end irq_ctl; + +architecture behavior of irq_ctl is + + signal opb_fifo_flg_int : std_logic; + signal opb_fifo_flg_reg : std_logic; +begin -- behavior + + opb_fifo_flg_int <= opb_fifo_flg when (C_ACTIVE_EDGE = '1') else + not opb_fifo_flg; + + irq_ctl_proc: process(rst, clk) + begin + if (rst = '1') then + opb_isr <= '0'; + elsif rising_edge(clk) then + opb_fifo_flg_reg <= opb_fifo_flg_int; + if (opb_ier= '1' and opb_fifo_flg_int = '1' and opb_fifo_flg_reg = '0') then + opb_isr <= '1'; + elsif (opb_isr_clr = '1') then + opb_isr <= '0'; + end if; + end if; + end process irq_ctl_proc; + + +end behavior; Index: trunk/pcore/opb_spi_slave_v1_00_a/hdl/vhdl/opb_if.vhd =================================================================== --- trunk/pcore/opb_spi_slave_v1_00_a/hdl/vhdl/opb_if.vhd (nonexistent) +++ trunk/pcore/opb_spi_slave_v1_00_a/hdl/vhdl/opb_if.vhd (revision 2) @@ -0,0 +1,336 @@ +------------------------------------------------------------------------------- +--* +--* @short OPB-Slave Interface +--* +--* Generics described in top entity. +--* +--* @see opb_spi_slave +--* @author: Daniel Köthe +--* @version: 1.0 +--* @date: 2007-11-11 +--/ +------------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; +use IEEE.STD_LOGIC_ARITH.all; +use IEEE.STD_LOGIC_UNSIGNED.all; +use IEEE.numeric_std.all; -- conv_integer() + +library work; +use work.opb_spi_slave_pack.all; + +entity opb_if is + + generic ( + C_BASEADDR : std_logic_vector(0 to 31) := X"00000000"; + C_HIGHADDR : std_logic_vector(0 to 31) := X"FFFFFFFF"; + C_USER_ID_CODE : integer := 3; + C_OPB_AWIDTH : integer := 32; + C_OPB_DWIDTH : integer := 32; + C_FAMILY : string := "virtex-4"; + C_SR_WIDTH : integer := 8; + C_FIFO_SIZE_WIDTH : integer := 4; + C_DMA_EN : boolean := true); + port ( + -- OPB-Bus Signals + OPB_ABus : in std_logic_vector(0 to C_OPB_AWIDTH-1); + OPB_BE : in std_logic_vector(0 to C_OPB_DWIDTH/8-1); + OPB_Clk : in std_logic; + OPB_DBus : in std_logic_vector(0 to C_OPB_DWIDTH-1); + OPB_RNW : in std_logic; + OPB_Rst : in std_logic; + OPB_select : in std_logic; + OPB_seqAddr : in std_logic; + Sln_DBus : out std_logic_vector(0 to C_OPB_DWIDTH-1); + Sln_errAck : out std_logic; + Sln_retry : out std_logic; + Sln_toutSup : out std_logic; + Sln_xferAck : out std_logic; + -- fifo ports + opb_s_tx_en : out std_logic; + opb_s_tx_data : out std_logic_vector(C_SR_WIDTH-1 downto 0); + opb_s_rx_en : out std_logic; + opb_s_rx_data : in std_logic_vector(C_SR_WIDTH-1 downto 0); + -- control register + opb_ctl_reg : out std_logic_vector(C_OPB_CTL_REG_WIDTH-1 downto 0); + -- Fifo almost full/empty thresholds + tx_thresh : out std_logic_vector((2*C_FIFO_SIZE_WIDTH)-1 downto 0); + rx_thresh : out std_logic_vector((2*C_FIFO_SIZE_WIDTH)-1 downto 0); + opb_fifo_flg : in std_logic_vector(C_NUM_FLG-1 downto 0); + -- interrupts + opb_dgie : out std_logic; + opb_ier : out std_logic_vector(C_NUM_INT-1 downto 0); + opb_isr : in std_logic_vector(C_NUM_INT-1 downto 0); + opb_isr_clr : out std_logic_vector(C_NUM_INT-1 downto 0); + -- dma register + opb_tx_dma_addr : out std_logic_vector(C_OPB_DWIDTH-1 downto 0); + opb_tx_dma_ctl : out std_logic_vector(0 downto 0); + opb_tx_dma_num : out std_logic_vector(15 downto 0); + opb_rx_dma_addr : out std_logic_vector(C_OPB_DWIDTH-1 downto 0); + opb_rx_dma_ctl : out std_logic_vector(0 downto 0); + opb_rx_dma_num : out std_logic_vector(15 downto 0)); +end opb_if; + +architecture behavior of opb_if is + + + signal Sln_DBus_big_end : std_logic_vector(C_OPB_DWIDTH-1 downto 0); + signal OPB_ABus_big_end : std_logic_vector(C_OPB_DWIDTH-1 downto 0); + signal OPB_DBus_big_end : std_logic_vector(C_OPB_DWIDTH-1 downto 0); + + + type state_t is (idle, + done); + signal state : state_t := idle; + + -- internal signals to enable readback + + signal tx_thresh_int : std_logic_vector((2*C_FIFO_SIZE_WIDTH)-1 downto 0); + signal rx_thresh_int : std_logic_vector((2*C_FIFO_SIZE_WIDTH)-1 downto 0); + signal opb_ier_int : std_logic_vector(C_NUM_INT-1 downto 0); + signal opb_dgie_int : std_logic; + + signal opb_ctl_reg_int : std_logic_vector(C_OPB_CTL_REG_WIDTH-1 downto 0); + + + -- only used if C_DMA_EN=true + signal opb_tx_dma_addr_int : std_logic_vector(C_OPB_DWIDTH-1 downto 0); + signal opb_tx_dma_ctl_int : std_logic_vector(0 downto 0); + signal opb_tx_dma_num_int : std_logic_vector(15 downto 0); + signal opb_rx_dma_addr_int : std_logic_vector(C_OPB_DWIDTH-1 downto 0); + signal opb_rx_dma_ctl_int : std_logic_vector(0 downto 0); + signal opb_rx_dma_num_int : std_logic_vector(15 downto 0); + +begin -- behavior + + tx_thresh <= tx_thresh_int; + rx_thresh <= rx_thresh_int; + opb_ier <= opb_ier_int; + opb_dgie <= opb_dgie_int; + + opb_ctl_reg <= opb_ctl_reg_int; + + --* Signals for DMA-Engine control + u1 : if C_DMA_EN generate + opb_tx_dma_ctl <= opb_tx_dma_ctl_int; + opb_tx_dma_addr <= opb_tx_dma_addr_int; + opb_tx_dma_num <= opb_tx_dma_num_int; + opb_rx_dma_ctl <= opb_rx_dma_ctl_int; + opb_rx_dma_addr <= opb_rx_dma_addr_int; + opb_rx_dma_num <= opb_rx_dma_num_int; + end generate u1; + + +-- unused outputs + Sln_errAck <= '0'; + Sln_retry <= '0'; + Sln_toutSup <= '0'; + + --* convert Sln_DBus_big_end to little mode + conv_big_Sln_DBus_proc: process(Sln_DBus_big_end) + begin + for i in 0 to 31 loop + Sln_DBus(31-i) <= Sln_DBus_big_end(i); + end loop; -- i + end process conv_big_Sln_DBus_proc; + + --* convert OPB_ABus to big endian + conv_big_OPB_ABus_proc: process(OPB_ABus) + begin + for i in 0 to 31 loop + OPB_ABus_big_end(31-i) <= OPB_ABus(i); + end loop; -- i + end process conv_big_OPB_ABus_proc; + + --* convert OPB_DBus to little mode + conv_big_OPB_DBus_proc: process(OPB_DBus) + begin + for i in 0 to 31 loop + OPB_DBus_big_end(31-i) <= OPB_DBus(i); + end loop; -- i + end process conv_big_OPB_DBus_proc; + + --* control OPB requests + --* + --* handles OPB-read and -write request + opb_slave_proc: process (OPB_Rst, OPB_Clk) + begin + if (OPB_Rst = '1') then + -- OPB + Sln_xferAck <= '0'; + Sln_DBus_big_end <= (others => '0'); + -- FIFO + opb_s_rx_en <= '0'; + opb_s_tx_en <= '0'; + -- + state <= idle; + -- Register + tx_thresh_int <= (others => '0'); + rx_thresh_int <= (others => '0'); + opb_ier_int <= (others => '0'); + opb_dgie_int <= '0'; + opb_ctl_reg_int <= (others => '0'); + + if C_DMA_EN then + opb_tx_dma_ctl_int <= (others => '0'); + opb_tx_dma_addr_int <= (others => '0'); + opb_tx_dma_num_int <= (others => '0'); + opb_rx_dma_ctl_int <= (others => '0'); + opb_rx_dma_addr_int <= (others => '0'); + opb_rx_dma_num_int <= (others => '0'); + end if; + + + elsif (OPB_Clk'event and OPB_Clk = '1') then + case state is + when idle => + if (OPB_select = '1' and + ((OPB_ABus >= C_BASEADDR) and (OPB_ABus <= C_HIGHADDR))) then + -- *device selected + Sln_xferAck <= '1'; + state <= done; + if (OPB_RNW = '1') then + -- read acess + case OPB_ABus_big_end(7 downto 2) is + when C_ADR_CTL => + Sln_DBus_big_end(C_OPB_CTL_REG_WIDTH-1 downto 0) <= opb_ctl_reg_int; + + when C_ADR_RX_DATA => + opb_s_rx_en <= '1'; + Sln_DBus_big_end(C_SR_WIDTH-1 downto 0) <= opb_s_rx_data; + + when C_ADR_STATUS => + Sln_DBus_big_end(C_NUM_FLG-1 downto 0) <= opb_fifo_flg; + + when C_ADR_TX_THRESH => + Sln_DBus_big_end(C_FIFO_SIZE_WIDTH-1 downto 0) <= tx_thresh_int(C_FIFO_SIZE_WIDTH-1 downto 0); + Sln_DBus_big_end(16+C_FIFO_SIZE_WIDTH-1 downto 16) <= tx_thresh_int((2*C_FIFO_SIZE_WIDTH)-1 downto C_FIFO_SIZE_WIDTH); + + when C_ADR_RX_THRESH => + Sln_DBus_big_end(C_FIFO_SIZE_WIDTH-1 downto 0) <= rx_thresh_int(C_FIFO_SIZE_WIDTH-1 downto 0); + Sln_DBus_big_end(16+C_FIFO_SIZE_WIDTH-1 downto 16) <= rx_thresh_int((2*C_FIFO_SIZE_WIDTH)-1 downto C_FIFO_SIZE_WIDTH); + + when C_ADR_DGIE => + Sln_DBus_big_end(0) <= opb_dgie_int; + when C_ADR_IER => + Sln_DBus_big_end(C_NUM_INT-1 downto 0) <= opb_ier_int; + + when C_ADR_ISR => + Sln_DBus_big_end(C_NUM_INT-1 downto 0) <= opb_isr; + + when C_ADR_TX_DMA_CTL => + if C_DMA_EN then + Sln_DBus_big_end(0 downto 0) <= opb_tx_dma_ctl_int; + end if; + + when C_ADR_TX_DMA_ADDR => + if C_DMA_EN then + Sln_DBus_big_end(C_OPB_DWIDTH-1 downto 0) <= opb_tx_dma_addr_int; + end if; + + when C_ADR_TX_DMA_NUM => + if C_DMA_EN then + Sln_DBus_big_end(15 downto 0) <= opb_tx_dma_num_int; + end if; + + + when C_ADR_RX_DMA_CTL => + if C_DMA_EN then + Sln_DBus_big_end(0 downto 0) <= opb_rx_dma_ctl_int; + end if; + + when C_ADR_RX_DMA_ADDR => + if C_DMA_EN then + Sln_DBus_big_end(C_OPB_DWIDTH-1 downto 0) <= opb_rx_dma_addr_int; + end if; + + when C_ADR_RX_DMA_NUM => + if C_DMA_EN then + Sln_DBus_big_end(15 downto 0) <= opb_rx_dma_num_int; + end if; + + + + when others => + null; + end case; + else + -- write acess + case OPB_ABus_big_end(7 downto 2) is + when C_ADR_CTL => + opb_ctl_reg_int <= OPB_DBus_big_end(C_OPB_CTL_REG_WIDTH-1 downto 0); + + when C_ADR_TX_DATA => + opb_s_tx_en <= '1'; + opb_s_tx_data <= OPB_DBus_big_end(C_SR_WIDTH-1 downto 0); + + when C_ADR_TX_THRESH => + tx_thresh_int(C_FIFO_SIZE_WIDTH-1 downto 0) <= OPB_DBus_big_end(C_FIFO_SIZE_WIDTH-1 downto 0); + tx_thresh_int((2*C_FIFO_SIZE_WIDTH)-1 downto C_FIFO_SIZE_WIDTH) <= OPB_DBus_big_end(16+C_FIFO_SIZE_WIDTH-1 downto 16); + + when C_ADR_RX_THRESH => + rx_thresh_int(C_FIFO_SIZE_WIDTH-1 downto 0) <= OPB_DBus_big_end(C_FIFO_SIZE_WIDTH-1 downto 0); + rx_thresh_int((2*C_FIFO_SIZE_WIDTH)-1 downto C_FIFO_SIZE_WIDTH) <= OPB_DBus_big_end(16+C_FIFO_SIZE_WIDTH-1 downto 16); + + when C_ADR_DGIE => + opb_dgie_int <= OPB_DBus_big_end(0); + + when C_ADR_IER => + opb_ier_int <= OPB_DBus_big_end(C_NUM_INT-1 downto 0); + + when C_ADR_ISR => + opb_isr_clr <= OPB_DBus_big_end(C_NUM_INT-1 downto 0); + + when C_ADR_TX_DMA_CTL => + if C_DMA_EN then + opb_tx_dma_ctl_int <= OPB_DBus_big_end(0 downto 0); + end if; + + when C_ADR_TX_DMA_ADDR => + if C_DMA_EN then + opb_tx_dma_addr_int <= OPB_DBus_big_end(C_OPB_DWIDTH-1 downto 0); + end if; + + when C_ADR_TX_DMA_NUM => + if C_DMA_EN then + opb_tx_dma_num_int <= OPB_DBus_big_end(15 downto 0); + end if; + + when C_ADR_RX_DMA_CTL => + if C_DMA_EN then + opb_rx_dma_ctl_int <= OPB_DBus_big_end(0 downto 0); + end if; + + when C_ADR_RX_DMA_ADDR => + if C_DMA_EN then + opb_rx_dma_addr_int <= OPB_DBus_big_end(C_OPB_DWIDTH-1 downto 0); + end if; + + when C_ADR_RX_DMA_NUM => + if C_DMA_EN then + opb_rx_dma_num_int <= OPB_DBus_big_end(15 downto 0); + end if; + + when others => + null; + end case; + end if; -- OPB_RNW + else + -- not selected + state <= idle; + end if; + when done => + opb_ctl_reg_int(3) <= '0'; + opb_isr_clr <= (others => '0'); + opb_s_rx_en <= '0'; + opb_s_tx_en <= '0'; + Sln_xferAck <= '0'; + Sln_DBus_big_end <= (others => '0'); + state <= idle; + + when others => + state <= idle; + end case; + end if; + end process opb_slave_proc; +end behavior; Index: trunk/pcore/opb_spi_slave_v1_00_a/data/opb_spi_slave_v2_1_0.ucf =================================================================== --- trunk/pcore/opb_spi_slave_v1_00_a/data/opb_spi_slave_v2_1_0.ucf (nonexistent) +++ trunk/pcore/opb_spi_slave_v1_00_a/data/opb_spi_slave_v2_1_0.ucf (revision 2) @@ -0,0 +1,7 @@ +NET "mosi" TNM = "_mosi"; +TIMEGRP "_mosi" OFFSET = IN 5 ns VALID 10 ns BEFORE "sclk" HIGH ; + +NET "miso_o" TNM = "_miso_o"; +TIMEGRP "_miso_o" OFFSET = OUT 10 ns AFTER "sclk" LOW ; + + Index: trunk/pcore/opb_spi_slave_v1_00_a/data/opb_spi_slave_v2_1_0.pao =================================================================== --- trunk/pcore/opb_spi_slave_v1_00_a/data/opb_spi_slave_v2_1_0.pao (nonexistent) +++ trunk/pcore/opb_spi_slave_v1_00_a/data/opb_spi_slave_v2_1_0.pao (revision 2) @@ -0,0 +1,18 @@ +############################################################################## +## Filename: E:\Eigene_Dateien\Entwicklung\cpld\spi-core\edk\test_opb_spi_slave\pcores/opb_spi_slave_v1_00_a/data/opb_spi_slave_v2_1_0.pao +## Description: Peripheral Analysis Order +## Date: Mon Oct 29 20:54:19 2007 (by Create and Import Peripheral Wizard) +############################################################################## + +lib opb_spi_slave_v1_00_a opb_spi_slave_pack vhdl +lib opb_spi_slave_v1_00_a shift_register vhdl +lib opb_spi_slave_v1_00_a bin2gray vhdl +lib opb_spi_slave_v1_00_a gray2bin vhdl +lib opb_spi_slave_v1_00_a gray_adder vhdl +lib opb_spi_slave_v1_00_a fifo vhdl +lib opb_spi_slave_v1_00_a fifo_prog_flags vhdl +lib opb_spi_slave_v1_00_a irq_ctl vhdl +lib opb_spi_slave_v1_00_a opb_m_if vhdl +lib opb_spi_slave_v1_00_a opb_if vhdl +lib opb_spi_slave_v1_00_a opb_spi_slave vhdl +lib opb_spi_slave_v1_00_a ram vhdl Index: trunk/pcore/opb_spi_slave_v1_00_a/data/opb_spi_slave_v2_1_0.mpd =================================================================== --- trunk/pcore/opb_spi_slave_v1_00_a/data/opb_spi_slave_v2_1_0.mpd (nonexistent) +++ trunk/pcore/opb_spi_slave_v1_00_a/data/opb_spi_slave_v2_1_0.mpd (revision 2) @@ -0,0 +1,72 @@ +################################################################### +## +## Name : opb_spi_slave +## Desc : Microprocessor Peripheral Description +## : Automatically generated by PsfUtility +## +################################################################### + +BEGIN opb_spi_slave + +## Peripheral Options +OPTION IPTYPE = PERIPHERAL +OPTION IMP_NETLIST = TRUE +OPTION HDL = VHDL +OPTION CORE_STATE = ACTIVE +OPTION IP_GROUP = MICROBLAZE:PPC:USER + + +## Bus Interfaces +BUS_INTERFACE BUS = MSOPB, BUS_TYPE = MASTER_SLAVE, BUS_STD = OPB + +## Generics for VHDL or Parameters for Verilog +PARAMETER C_BASEADDR = 0x00000000, DT = std_logic_vector(0 to 31), BUS = MSOPB, ADDRESS = BASE, PAIR = C_HIGHADDR +PARAMETER C_HIGHADDR = 0xffffffff, DT = std_logic_vector(0 to 31), BUS = MSOPB, ADDRESS = HIGH, PAIR = C_BASEADDR +PARAMETER C_USER_ID_CODE = 0, DT = INTEGER +PARAMETER C_OPB_AWIDTH = 32, DT = INTEGER, BUS = MSOPB +PARAMETER C_OPB_DWIDTH = 32, DT = INTEGER, BUS = MSOPB +PARAMETER C_FAMILY = virtex-4, DT = STRING +PARAMETER C_SR_WIDTH = 8, DT = INTEGER +PARAMETER C_MSB_FIRST = true, DT = BOOLEAN +PARAMETER C_CPOL = 0, DT = INTEGER +PARAMETER C_PHA = 0, DT = INTEGER +PARAMETER C_FIFO_SIZE_WIDTH = 7, DT = INTEGER +PARAMETER C_DMA_EN = true, DT = BOOLEAN + +## Ports +PORT OPB_ABus = OPB_ABus, DIR = I, VEC = [0:(C_OPB_AWIDTH-1)], BUS = MSOPB +PORT OPB_BE = OPB_BE, DIR = I, VEC = [0:((C_OPB_DWIDTH/8)-1)], BUS = MSOPB +PORT OPB_Clk = "", DIR = I, BUS = MSOPB, SIGIS = CLK +PORT OPB_DBus = OPB_DBus, DIR = I, VEC = [0:(C_OPB_DWIDTH-1)], BUS = MSOPB +PORT OPB_RNW = OPB_RNW, DIR = I, BUS = MSOPB +PORT OPB_Rst = OPB_Rst, DIR = I, BUS = MSOPB, SIGIS = RST +PORT OPB_select = OPB_select, DIR = I, BUS = MSOPB +PORT OPB_seqAddr = OPB_seqAddr, DIR = I, BUS = MSOPB +PORT Sln_DBus = Sl_DBus, DIR = O, VEC = [0:(C_OPB_DWIDTH-1)], BUS = MSOPB +PORT Sln_errAck = Sl_errAck, DIR = O, BUS = MSOPB +PORT Sln_retry = Sl_retry, DIR = O, BUS = MSOPB +PORT Sln_toutSup = Sl_toutSup, DIR = O, BUS = MSOPB +PORT Sln_xferAck = Sl_xferAck, DIR = O, BUS = MSOPB +PORT M_ABus = M_ABus, DIR = O, VEC = [0:(C_OPB_AWIDTH-1)], BUS = MSOPB +PORT M_BE = M_BE, DIR = O, VEC = [0:((C_OPB_DWIDTH/8)-1)], BUS = MSOPB +PORT M_busLock = M_busLock, DIR = O, BUS = MSOPB +PORT M_DBus = M_DBus, DIR = O, VEC = [0:(C_OPB_DWIDTH-1)], BUS = MSOPB +PORT M_request = M_request, DIR = O, BUS = MSOPB +PORT M_RNW = M_RNW, DIR = O, BUS = MSOPB +PORT M_select = M_select, DIR = O, BUS = MSOPB +PORT M_seqAddr = M_seqAddr, DIR = O, BUS = MSOPB +PORT MOPB_errAck = OPB_errAck, DIR = I, BUS = MSOPB +PORT MOPB_MGrant = OPB_MGrant, DIR = I, BUS = MSOPB +PORT MOPB_retry = OPB_retry, DIR = I, BUS = MSOPB +PORT MOPB_timeout = OPB_timeout, DIR = I, BUS = MSOPB +PORT MOPB_xferAck = OPB_xferAck, DIR = I, BUS = MSOPB +PORT sclk = "", DIR = I, SIGIS = CLK +PORT ss_n = "", DIR = I +PORT mosi = "", DIR = I +PORT miso = "", DIR = IO, THREE_STATE = TRUE, TRI_I = miso_I, TRI_O = miso_O, TRI_T = miso_T +PORT miso_o = "", DIR = O +PORT miso_i = "", DIR = I +PORT miso_t = "", DIR = O +PORT opb_irq = "", DIR = O, SIGIS = INTERRUPT, SENSITIVITY = LEVEL_HIGH + +END

powered by: WebSVN 2.1.0

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