URL
https://opencores.org/ocsvn/wbuart32/wbuart32/trunk
Subversion Repositories wbuart32
[/] [wbuart32/] [trunk/] [doc/] [src/] [spec.tex] - Rev 25
Go to most recent revision | Compare with Previous | Blame | View Log
\documentclass{gqtekspec} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% Filename: spec.tex %% %% Project: wbuart32, a full featured UART with simulator %% %% Purpose: To describe, for LaTeX, how to build the specification file %% for the wbuart32 core(s). This file is not nearly as %% interesting as the file it creates, so I suggest you read spec.pdf %% first, before deciding you are really interested in this file. %% %% Creator: Dan Gisselquist, Ph.D. %% Gisselquist Technology, LLC %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% Copyright (C) 2015-2016, Gisselquist Technology, LLC %% %% This program is free software (firmware): you can redistribute it and/or %% modify it under the terms of the GNU General Public License as published %% by the Free Software Foundation, either version 3 of the License, or (at %% your option) any later version. %% %% This program is distributed in the hope that it will be useful, but WITHOUT %% ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or %% FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License %% for more details. %% %% You should have received a copy of the GNU General Public License along %% with this program. (It's in the $(ROOT)/doc directory, run make with no %% target there if the PDF file isn't present.) If not, see %% <http://www.gnu.org/licenses/> for a copy. %% %% License: GPL, v3, as defined and found on www.gnu.org, %% http://www.gnu.org/licenses/gpl.html %% %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% \usepackage{import} \usepackage{bytefield} \usepackage{amsmath} \project{WBUART32} \title{Specification} \author{Dan Gisselquist, Ph.D.} \email{dgisselq (at) ieee.org} \revision{Rev.~1.0} \begin{document} \pagestyle{gqtekspecplain} \titlepage \begin{license} Copyright (C) 2016--2017, Gisselquist Technology, LLC. This project is free software (firmware): you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see \texttt{http://www.gnu.org/licenses/} for a copy. \end{license} \begin{revisionhistory} 1.01 & 6/02/2017 & D. Gisselquist & Clarified register descriptions\\\hline 1.0 & 2/20/2017 & D. Gisselquist & Added Hardware Flow Control\\\hline 0.2 & 1/03/2017 & D. Gisselquist & Added test-bench information\\\hline 0.1 & 8/26/2016 & D. Gisselquist & Initial Draft Specification\\\hline \end{revisionhistory} % Revision History % Table of Contents, named Contents \tableofcontents \listoffigures \listoftables \begin{preface} It may be that building a UART is a mandatory coming of age task for any HDL designer. The task is simple, easy, and there's not all that much to it. This project comes out of some of my first experiences with Verilog. Since then, it has been augmented with quite a few useful capabilities for simulating a UART connection when using Verilator. It is this, perhaps unusual, addition to the core set that makes this core worth taking note of. I hope you find it useful. \end{preface} \chapter{Introduction}\label{ch:intro} \pagenumbering{arabic} \setcounter{page}{1} % % Introduction % % This section contains the introduction to the core, describing both its % use and its features. % % What is old The Universal Asynchronous Serial Transport, or UART, has become quite the common protocol between devices. It is simple to wire up, easy to use, and easy to process. This core provides one implementation of the logic necessary to use such a communications scheme. % What does the old lack? % What is new % What does the new have that the old lacks % What performance gain can be expected? While you are likely to find many UART examples out there, this particular UART implementation offers something many of these other examples do not: a Verilator simulation capability. This will allow the user to connect, via a TCP/IP port or a telnet application, to the UART of their desired chip. As a result, full two-way interaction can be had between a simulation and a terminal or other port. Indeed, this may even be sufficient to connect a CPU, capable of running Linux, to a terminal to verify that yes it can truly run Linux--all within Verilator. As a final addition, there are four files in the test bench section which can be used as top--level design files to prove whether or not the serial port on a given circuit board works. \chapter{Architecture}\label{ch:arch} The HDL portion of the core itself consists of four basic files: {\tt rxuart.v}, {\tt txuart.v}, {\tt ufifo.v} and {\tt wbuart.v}. These are, respectively, the receive UART code, the transmit UART code, a fairly generic FIFO, and a fully wishbone compliant UART peripheral. This latter file demonstrates one example of how the receiver, transmitter, and a pair of FIFOs may be connected to a Wishbone bus. A fifth file, {\tt wbuart-insert.v}, demonstrates how the {\tt rxuart.v} and {\tt txuart.v} files may be included into a module implementing a simpler wishbone interface without the FIFO. Each of the core files, {\tt rxuart.v} and {\tt txuart.v}, are fully capable. They each accept a 30--bit setup value specifying baud rate, the number of bits per byte (between 5 and 8), whether hardware flow control is off, or whether or not parity is used, and if so whether that parity is even, odd, or fixed mark or fixed space. This setup register will be discussed further in Chap.\ref{ch:registers}. A further note on the {\tt rxuart.v} module is in order. This module double latches the input, in the proper two buffer fashion to avoid problems with metastability. Then, upon the detection of the start bit (i.e. a high to low transition), the port waits a half of a baud, and then starts its baud clock so as to sample in the middle of every baud following. The result of this is a timing requirement: after $N+2$ baud intervals ($N+3$ if parity is used), where $N$ is the number of bits per byte, this calculated middle sample must still lie within the associated bit period. This leaves us with the criteria that, \begin{eqnarray} \left|\left(N+2\right) \left(\frac{f_{\mbox{\tiny SYS}}}{f_{\mbox{\tiny BAUD}}} -{\mbox{\tt CKS}}\right)\right| &<& \frac{f_{\mbox{\tiny SYS}}}{2f_{\mbox{\tiny BAUD}}}, \label{eqn:baudlimit}. \end{eqnarray} where $f_{\mbox{\tiny SYS}}$ is the system clock frequency, $f_{\mbox{\tiny BAUD}}$ is the baud rate or frequency, {\tt CKS} is the number of clocks per baud as set in the configuration register, and $N$ is the number of bits per byte. What this means is that, for transmission rates where $f_{\mbox{\tiny BAUD}}$ approaches $f_{\mbox{\tiny SYS}}$, the number of data rates that can actually be synthesized becomes limited. Connecting to either {\tt txuart.v} or {\tt rxuart.v} is quite simple. Both files have a data port and a strobe. To transmit, set the data and strobe lines. Drop the strobe line on the clock after the busy line was low. Likewise, to connect to the {\tt rxuart.v} port, there is a data and a strobe. This time, though, these two wires are outputs of the receive module as opposed to inputs. When the strobe is high, the data is valid. It will only be high for one clock period. If you wish to connect this output to a bus, a register will be needed to hold the strobe high until the data is read, as in {\tt wbuart-insert.v}. Also, while the strobe is high, the {\tt o\_frame\_err} will indicate whether or not there was a framing error (i.e., no stop bit), and {\tt o\_parity\_err} will indicate whether or not the parity matched. Finally, the {\tt o\_break} line will indicate whether the receiver is in a ``break'' state, The {\tt tx\_busy} line may be inverted and connected to a transmit interrupt line. In a similar fashion, the {\tt rx\_stb} line, or the bus equivalent of {\tt rx\_ready}, may be used for receive interrupt lines--although it will need to be latched as both {\tt wbuart.v} and {\tt wbuart-insert.v} demonstrate. An simple example of how to put this configuration together is found in {\tt wbuart-insert.v}. In this example given, the {\tt rx\_data} register will have only the lower eight bits set if the data is valid, higher bits will be set upon error conditions, and cleared automatically upon the next byte read. In a similar fashion, the {\tt tx\_data} register can be written to with a byte in order to transmit that byte. Writing bit ten will place the transmitter into a ``break'' condition, which will only be cleared by writing a zero to that bit later. Reading from the {\tt tx\_data} register can also be used to determine if the transmitter is busy (via polling), whether it is currently in a break condition, or even what bit is currently being placed to the output port. A more comprehensive example of how these UART modules may be used together can be found in {\tt wbuart.v}. This file provides a full wishbone interface allowing interaction with the core using four registers: a setup register, receive register and transmit register as before, as well as a FIFO health register through which the size and fill of the FIFO can be queried. The C++ simulation portion of the code revolves around the file {\tt bench/cpp/uartsim.cpp} and its associated header. This file defines a class, {\tt UARTSIM}, which can be used to connect the UART to a TCP/IP stream. When initialized, this class takes, as input, the TCP/IP port number that the class is to connect with. Setting the port to zero connects the UART to the standard input and output file facilities. Once connected, using this simulator is as simple as calculating the receive input bit from the transmit output bit when the clock is low, and the core takes care of everything else. Finally, there are a series of example files found in the bench/verilog directory. {\tt helloworld.v} presents an example of a simple UART transmitter sending the ``Hello, World {\textbackslash}r{\textbackslash}n'' message over and over again. This example uses only the {\tt txuart.v} module, and can be simulated in Verilator. A second test file, {\tt echotest.v}, works by echoing every received character to the transmit port. This tests both {\tt txuart.v} and {\tt rxuart.v}. A third test file, {\tt linetest.v}, works by waiting for a line of data to be received, after which it parrots that line back to the terminal. A fourth test file, {\tt speechfifo.v} tests both the wishbone interface as well as the FIFO, by filling the UART, 10~samples at a time, with text from Abraham Lincoln's Gettysburg address. All three of these example files may be used as stand-alone top--level design files to verify your own UART hardware functionality. \chapter{Operation}\label{ch:ops} % This section describes the operation of the core. Specific sequences, such % as startup sequences, as well as the modes and states of the block should be % described. % To use the core, a couple of steps are required. First, wire it up. This includes wiring the {\tt i\_uart} and {\tt o\_uart} ports, as well as any {\tt i\_cts\_n} and/or {\tt o\_rts\_n} hardware flow control. The {\tt rxuart.v} and {\tt txuart.v} files may be wired up for use individually, or as part of a large module such as the example in{\tt wbuart-insert.v}. Alternatively, the {\tt wbuart.v} file may be connected to a straight 32--bit wishbone bus. Second, set the UART configuration register. This is ideally set by setting the {\tt INITIAL\_SETUP} parameter of {\tt rxuart}, {\tt txuart} or even {\tt wbuart} Alternatively, you can write to the setup register at a later time, as is done within the {\tt speechfifo.v} bench test. From a simulation standpoint, it will also need to be ``wired'' up inside your C++ main Verilator file. Somewhere, internal to the top--level Verilator C++ simulation file, you'll want to have some setup lines similar to, \begin{tabbing} \hbox to 3.0in{\tt \#include "uartsim.h"} \= {\em // Tell compiler about UARTSIM}\\ \vdots \\ {\tt UARTSIM *uartsim;} \> {\em // Declare a variable to hold the simulator}\\ {\tt uartsim = new UARTSIM(ip\_port);} \> {\em // Create/initialize it with your TCP/IP port \#} \\ {\tt uartsim->setup(setup\_register\_value);} \> {\em // Tell it the line coding to expect}\\ \end{tabbing} and then another set of lines within your clocked section that look something like, \begin{tabbing} {\tt if (!clk)} \= \\ \> {\tt tb->i\_uart\_rx} {\tt = } {\tt uartsim(tb->o\_uart\_tx);} \end{tabbing} You should be able to find several examples of this in the {\tt helloworld.cpp}, {\tt linetest.cpp}, and {\tt speechtest.cpp} files. These C++ implementations, though, are also complicated by the need for a self--contained testing program to be able to capture and know what was placed onto the standard input and output streams, hence many of them fork() into two processes so that one process can verify the output of the other. Both {\tt speechtest.cpp} and {\tt linetest.cpp} allow a {\em -i} option to run in an interactive mode without forking. Either way, forking the simulation program shouldn't be needed for normal usages of these techniques, but you may find it helpful to know should you examine this code or should you wish to build your own test file that proves its own output. To use the transmitter, set the {\tt i\_stb} and {\tt i\_data} wires. Drop the strobe line any time after {\tt (i\_stb)\&\&(!o\_busy)}. To use the receiver, grab the data any time {\tt o\_stb} is true. From the standpoint of the bus, there are two ways to handle receiving and transmitting: polling and interrupt based, although both work one character at a time. To poll, repeatedly read the receive data register until only bits from the bottom eight are set. This is an indication that the byte is valid. Alternatively, you could wait until the an interrupt line is set and then read. In the {\tt wbuart-insert.v} example as well as the {\tt wbuart.v} implementation, the {\tt o\_uart\_rx\_int} line will be set ({\tt rx\_int} for {\tt wbuart-insert.v}), and automatically cleared upon any read. To write, one can read from the transmit data register until the eighth bit, the {\tt tx\_busy} bit, is cleared, and then transmit. Alternatively, this negation of this bit may be connected to an interrupt line, {\tt o\_uart\_tx\_int}. Writing to the port while the transmitter is idle will start it transmitting. Writing to the port while it is busy will fill a one word buffer that will get sent as soon as the port is idle for one clock. \chapter{Registers}\label{ch:registers} % This section specifies all internal registers. It should completely cover % the interface between the CPU and the host as seen from the software point % of view. % List of Registers % Register 1 Description % % You shall choose the style of register you prefer. Do not use both options % in one and the same document. (Table of bits, vs. byetarray type of % description). The {\tt wbuart} core supports four registers, shown in Tbl.~\ref{tbl:reglist}. \begin{table}\begin{center}\begin{reglist} {\tt SETUP} & 2'b00 & 30 & R/W & UART configuration/setup register.\\\hline {\tt FIFO} & 2'b01 & 32 & R & Returns size and status of the FIFOs\\\hline {\tt RX\_DATA}& 2'b10 & 13 & R & Read data, reads from the UART.\\\hline {\tt TX\_DATA}& 2'b11 & 15 & (R/)W & Transmit data: writes send out the UART. \\\hline \end{reglist}\caption{UART Registers}\label{tbl:reglist} \end{center}\end{table} We'll cover the format of all of these registers here, as they are defined by {\tt wbuart.v}. \section{Setup Register} The setup register is perhaps the most critical of all the registers. This is shown in Fig.\ref{fig:SETUP}. \begin{figure}\begin{center} \begin{bytefield}[endianness=big]{32} \bitheader{0-31}\\ \bitbox{1}{0} \bitbox{1}{H} \bitbox{2}{N} \bitbox{1}{S} \bitbox{1}{P} \bitbox{1}{F} \bitbox{1}{T} \bitbox{24}{Baud CLKS} \end{bytefield} \caption{SETUP Register fields}\label{fig:SETUP} \end{center}\end{figure} It is designed so that, for any 8N1 protocol (eight data bits, no parity, one stop bit, hardware flow control on), all of the upper bits will be set to zero so that only the number of clocks per baud interval needs to be set. The top bit is unused, making this a 31--bit number. The other fields are: $H$ which, when set, turns off any hardware flow control. $N$ sets the number of bits per word. A value of zero corresponds to 8--bit words, a value of one to seven bit words, and so forth up to a value of three for five bit words. $S$ determines the number of stop bits. Set this to one for two stop bits, or leave it at zero for a single stop bit. $P$ determines whether or not a parity bit is used (1~for parity, 0~for no parity), while $F$ determines whether or not the parity is fixed. Tbl.~\ref{tbl:parity} lists how $P$, $F$, and $T$ affect which parity is being used. \begin{table}\begin{center} \begin{tabular}{ccc|l} P&F&T&Setting \\\hline\hline 1 & 0 & 0 & Odd parity \\\hline 1 & 0 & 1 & Even parity \\\hline 1 & 1 & 0 & Parity bit is a Space (1'b0)\\\hline 1 & 1 & 1 & Parity bit is a Mark (1'b1)\\\hline 0 & & & No parity \\\hline \end{tabular}\caption{Parity setup}\label{tbl:parity} \end{center}\end{table} The final portion of this register is the baud {\tt CLKS}. This is the number of ticks of your system clock per baud interval, \begin{eqnarray*} {\tt CLKS} &=& \left\lfloor \frac{f_{\mbox{\tiny SYS}}}{f_{\mbox{\tiny BAUD}}} \right\rfloor. \end{eqnarray*} Rounding to the nearest integer is recommended. Hence, if you have a system clock of 100~MHz and wish to achieve 115,200~Baud, you would set {\tt CLKS} to \begin{eqnarray*} {\tt CLKS}_{\tiny{\tt Example}} &=& \frac{100 \cdot 10^6}{115200} \frac{\mbox{Clocks per Second}}{\mbox{Baud Intervals per Second}} \approx 868 \mbox{ Clocks per Baud Interval} \end{eqnarray*} Changes to this setup register will take place in the transmitter as soon as the transmitter is idle and ready to accept another byte. Changes to this setup register in {\tt rxuart.v} also take place between bytes. However, within the {\tt wbuart.v} context, any changes to the setup register will also reset the receiver and receive FIFO together. Once reset, the receiver will insist on a minimum of sixteen idle baud intervals before receiving the next byte. \section{FIFO Register} The FIFO register is a read--only register containing information about the status of both receive and transmit FIFOs within it. The transmit FIFO information is kept in the upper 16--bits, and the receiver FIFO information in the lower 1-bits, as shown in Fig.~\ref{fig:FIFO}. \begin{figure}\begin{center} \begin{bytefield}[endianness=big]{32} \bitheader{0-31}\\ \bitbox[rlt]{4}{LGLN} \bitbox[rlt]{10}{TX Fill} \bitbox[rlt]{1}{H} \bitbox[rlt]{1}{Z} \bitbox[rlt]{4}{} \bitbox[rlt]{10}{} \bitbox[rlt]{1}{} \bitbox[rlt]{1}{} \\ \bitbox[rlb]{4}{} \bitbox[rlb]{10}{} \bitbox[rlb]{1}{} \bitbox[rlb]{1}{} \bitbox[rlb]{4}{LGLN} \bitbox[rlb]{10}{RX Fill} \bitbox[rlb]{1}{H} \bitbox[rlb]{1}{Z} \\ \end{bytefield} \caption{RXDATA Register fields}\label{fig:FIFO} \end{center}\end{figure} We'll discuss each of these bits individually. The {\tt LGLN} field indicates the log base two of the FIFO length. Hence an {\tt LGLN} field of four would indicate a FIFO length of sixteen values. The FIFO fill for the transmitter indicates the number of available spaces within the transmit FIFO, while the FIFO fill in the receiver indicates the current number of spaces within the FIFO having valid data. The $H$ bit will be true if the high order FIFO fill bit is set. Finally, the $Z$ bit will be true for the transmitter if there is at least one open space in the FIFO, and true in the receiver if there is at least one value needing to be read. The $H$ and $Z$ bits also mirror the interrupt bits generated by {\tt wbuart.v}. Interrupts will be generated any time the FIFO is half full (on receive), or less than half full (on transmit). The same logic applies for the $Z$ bit. An interrupt will be generated any time the FIFO in non-empty (on receive), or not full (on transmit). Writes to this FIFO status register are quietly ignored. \section{RX\_DATA Register} Fig.~\ref{fig:RXDATA} \begin{figure}\begin{center} \begin{bytefield}[endianness=big]{32} \bitheader{0-31}\\ \bitbox[rlt]{19}{19'h00} \bitbox{1}{E} \bitbox[rlt]{1}{B} \bitbox[rlt]{1}{F} \bitbox[rlt]{1}{P} \bitbox[rlt]{1}{S} \bitbox[rlt]{8}{RWORD} \\ \bitbox[lrb]{19}{} \bitbox{1}{-} \bitbox[lrb]{1}{} \bitbox[lrb]{1}{} \bitbox[lrb]{1}{} \bitbox[lrb]{1}{} \bitbox[lrb]{8}{} \end{bytefield} \caption{RXDATA Register fields}\label{fig:RXDATA} \end{center}\end{figure} breaks out the various bit fields of the receive data register used in {\tt wbuart.v}. In particular, the $B$ field indicates that the receive line is in a break condition. The $F$ and $P$ fields indicate that a frame error or parity error has been detected. These bits are not self clearing, but rather are cleared by writing to 1's to them. The $S$ field will be false when the {\tt RWORD} is valid. Hence, if {\tt (RWORD \& ~0x0ff)} is zero there is a word ready to be received without error. The $E$ bit is an error bit. When set, it indicates that the FIFO has overflowed sometime since the last reset. This bit is also a reset bit. In other words, writing a {\tt 1'b1} to this bit will command a receive reset: clearing the FIFO, and waiting for the line to be idle before receiving another byte. This bit is not implemented in {\tt wbuart-insert.v}, but exists in the {\tt wbuart.v} implementation. \section{TX\_DATA Register} Fig.~\ref{fig:TXDATA} \begin{figure}\begin{center} \begin{bytefield}[endianness=big]{32} \bitheader{0-31}\\ \bitbox[lrt]{16}{16'h00} \bitbox{1}{R} \bitbox{1}{H} \bitbox{1}{Z} \bitbox{1}{E} \bitbox[lrt]{1}{C} \bitbox[lrt]{1}{O} \bitbox[lrt]{1}{B} \bitbox[lrt]{1}{S} \bitbox[lrt]{8}{TWORD} \\ \bitbox[lrb]{17}{} \bitbox{3}{3'h0} \bitbox[lrb]{1}{} \bitbox[lrb]{1}{} \bitbox[lrb]{1}{} \bitbox[lrb]{1}{} \bitbox[lrb]{8}{} \end{bytefield} \caption{TXDATA Register fields}\label{fig:TXDATA} \end{center}\end{figure} breaks out the various bit fields of the transmit data register used in {\tt wbuart.v}. The $C$ field indicates whether or not the receive data line is high or low, the $O$ field indicates the same for the transmit line. These aren't particularly useful or valuable, but the $C$ bit doesn't fit in the receive data register since it would violate the error condition detector. These two bits are thrown in here for whatever useful purpose one might find. The $B$ field, when set, transmits a break condition. Further, writes to the TXDATA register while in a break condition and with the $B$ field clear, will clear the transmitter from any break condition without transmitting anything. The $S$ field is similar to the RXDATA strobe register. It is a read--only bit that will be true any time the transmitter is busy. It will be clear only when the transmitter is idle. Finally, the upper $R$ bit at the top of the register is the instantaneous value of the received ready-to-send (RTS) value. The final three bits, $H$, $Z$, and $E$, are present only in {\tt wbuart.v}. These bits indicate $H$ if the FIFO is at least half full, $Z$ if the FIFO is not full, and $E$ if the FIFO has experienced an overflow condition since the last reset. Writing a {\tt 1'b1} to the $E$ bit will reset the transmit FIFO, both clearing any error indication in the FIFO as well as clearing the FIFO itself. To use the transmitter, simply write a byte to the TXDATA register with the upper 24--bits clear to transmit. \chapter{Clocks}\label{ch:clocks} The UART has been tested with a clock as fast as 200~MHz (Tbl.~\ref{tbl:clocks}). \begin{table}\begin{center} \begin{clocklist} {\tt i\_clk} & (System) & 200~MHz & & System clock\\\hline \end{clocklist} \caption{Clock Requirements}\label{tbl:clocks} \end{center}\end{table} It should be able to use slower clocks, but only subject to the ability to properly set the baud rate as shown in Eqn.~\eqref{eqn:baudlimit} on Page~\pageref{eqn:baudlimit}. I do not recommend using this core with a baud rate greater than a quarter of the system clock rate. % This section specifies all of the clocks. All clocks, clock domain passes % and the clock relations should be described. % Name | Source | Rates (MHz) | Remarks | Description % | Max|Min|Resolution| \chapter{Wishbone Datasheet}\label{ch:wishbone} Tbl.~\ref{tbl:wishbone} \begin{table}[htbp]\begin{center}\begin{tabular}{|p{2.5in}|p{3.5in}|}\hline \rowcolor[gray]{0.85} Description & Specification \\\hline\hline Revision level of wishbone & WB B4 spec \\\hline Type of interface & Slave, Read/Write, pipeline reads supported \\\hline Port size & 32--bit \\\hline Port granularity & 32--bit \\\hline Maximum Operand Size & 32--bit \\\hline Data transfer ordering & (Irrelevant) \\\hline Clock constraints & None.\\\hline Signal Names & \begin{tabular}{lll} {\tt wbuart.v} & {\tt wbuart-insert.v} & WB Equivalent \\\hline {\tt i\_clk} & {\tt i\_wb\_clk} & {\tt CLK\_I} \\ {\tt i\_rst} & & {\tt RST\_I} \\ {\tt i\_wb\_cyc} & {\tt i\_wb\_cyc} & {\tt CYC\_I} \\ {\tt i\_wb\_stb} & {\tt i\_wb\_stb} & {\tt STB\_I} \\ {\tt i\_wb\_we} & {\tt i\_wb\_we} & {\tt WE\_I} \\ {\tt i\_wb\_addr} & {\tt i\_wb\_addr} & {\tt ADR\_I} \\ {\tt i\_wb\_data} & {\tt i\_wb\_data} & {\tt DAT\_I} \\ {\tt o\_wb\_ack} & {\tt o\_wb\_ack} & {\tt ACK\_O} \\ {\tt o\_wb\_stall} & {\tt o\_wb\_stall} & {\tt STALL\_O} \\ {\tt o\_wb\_data} & {\tt o\_wb\_data} & {\tt DAT\_O} \end{tabular}\\\hline \end{tabular} \caption{Wishbone Datasheet}\label{tbl:wishbone} \end{center}\end{table} is required by the wishbone specification in order to declare the core as wishbone compliant, and so it is included here. It references the connections used in {\tt wbuart.v} as well as those exemplified by {\tt wbuart-insert.v}. The big thing to notice is that this core acts as a wishbone slave, and that all accesses to the core registers are 32--bit reads and writes to this interface---not the 8--bit reads or writes that might be expected from any other 8'bit serial interface. What this table doesn't show is that all accesses to the port take a single clock for {\tt wbuart-insert.v}, or two clocks for {\tt wbuart.v}. That is, if the {\tt i\_wb\_stb} line is high on one clock, the {\tt i\_wb\_ack} line will be high the next for single clock access, or the clock after that for two clock access. Further, the {\tt o\_wb\_stall} line is tied to zero. Also, this particular wishbone implementation assumes that if {\tt i\_wb\_stb}, then {\tt i\_wb\_cyc} will be high as well. Hence it only checks whether or not {\tt i\_wb\_stb} is true to determine if a transaction has taken place. If your bus does not meet this requirement, you'll need to AND {\tt i\_wb\_stb} with {\tt i\_wb\_cyc} before using the core. \chapter{I/O Ports}\label{ch:ioports} % This section specifies all of the core IO ports In it's simplest form, the UART offers simply two I/O ports: the {\tt i\_uart\_rx} line to receive, and the {\tt o\_uart\_tx} line to transmit. These lines need to be brought to the outside of your design. Within Verilator, they need to be connected inside your Verilator test bench, as in: \begin{tabbing} {\tt if (!clk)} \= \\ \> {\tt tb->i\_uart\_rx} {\tt = } {\tt uartsim(tb->o\_uart\_tx);} \end{tabbing} For those interested in hardware flow control, the core also offers an {\tt i\_cts\_n} input to control the flow out of our transmitter, and an {\tt o\_rts\_n} output to indicate when the receiver is full. Both of these wires are active low. For those not interested in flow control there are three possibilities. First, one can set the module parameter {\tt HARDWARE\_FLOW\_CONTROL\_PRESENT} to zero which will disable hardware flow control. This will also permanently set the hardware flow control is off bit in the setup register. Second, hardware flow control can be disabled by connecting a {\tt 1'b0} wire to {\tt i\_cts\_n} and by ignoring the {\tt o\_rts\_n} output. In this case, the hardware flow control setup bit becomes an unused flip flop within the driver. The third way to disable hardware flow control is to simply disable it within the setup register. In general, these approaches will only affect the transmitter's operation and how the {\tt o\_rts\_n} bit gets set. A more detailed discussion of the connections associated with these modules can begin with Tbl.~\ref{tbl:rxports}, \begin{table}\begin{center}\begin{portlist} {\tt i\_clk} & 1 & Input & The system clock \\\hline {\tt i\_reset} & 1 & Input & A positive, synchronous reset \\\hline {\tt i\_setup} & 31 & Input & The 31--bit setup register \\\hline {\tt i\_uart} & 1 & Input & The input wire from the outside world. \\\hline {\tt o\_wr} & 1 & Output & True if a word was received. At this time, {\tt o\_data}, {\tt o\_break}, {\tt o\_parity\_err}, and {\tt o\_frame\_err} will also be valid. \\\hline {\tt o\_data} & 8 & Output & The received data, valid if {\tt o\_wr} \\\hline {\tt o\_break} & 1 & Output & True in the case of a break condition \\\hline {\tt o\_parity\_err} & 1 & Output & True if a parity error was detected \\\hline {\tt o\_frame\_err} & 1 & Output & True if a frame error was detected \\\hline {\tt o\_ck\_uart} & 1 & Output & A synchronized copy of {\tt i\_uart} \\\hline \end{portlist}\caption{RXUART port list}\label{tbl:rxports} \end{center}\end{table} detailing the I/O ports of the UART receiver, Tbl.~\ref{tbl:txports}, \begin{table}\begin{center}\begin{portlist} {\tt i\_clk} & 1 & Input & The system clock \\\hline {\tt i\_reset} & 1 & Input & A positive, synchronous reset \\\hline {\tt i\_setup} & 31 & Input & The 31--bit setup register \\\hline {\tt i\_break} & 1 & Input & Set to true to place the transmit channel into a break condition\\\hline {\tt i\_wr} & 1 & Input & An input strobe. Set to one when you wish to transmit data, clear once it has been accepted\\\hline {\tt i\_data} & 8 & Input & The data to be transmitted, ignored unless {\tt (i\_wr)\&\&(!o\_busy)} \\\hline {\tt i\_cts\_n} & 1 & Input & A hardware flow control wire, true if the transmitter is cleared to send, active low\\\hline {\tt o\_uart} & 1 & Output & The wire to be connected to the external port\\\hline {\tt o\_busy} & 1 & Output & True if the transmitter is busy, false if it will receive data\\\hline \end{portlist}\caption{TXUART port list}\label{tbl:txports} \end{center}\end{table} detailing the I/O ports of the UART transmitter, and Tbl.~\ref{tbl:wbports} \begin{table}\begin{center}\begin{tabular}{|p{1.15in}|p{0.1in}|p{0.75in}|p{3.375in}|} \rowcolor[gray]{0.85} Port & W & Direction & Description \\\hline\hline {\tt i\_uart\_rx}& 1 & Input & The receive wire coming from the external port\\\hline {\tt o\_uart\_tx}& 1 & Output & The transmit wire to be connected to the external port\\\hline {\tt i\_cts\_n}& 1 & Input & The hardware flow control {\tt clear-to-send} input for the transmitter, active low\\\hline {\tt o\_rts\_n}& 1 & Output & The hardware flow control {\tt ready-to-send} (receive) output, also active low\\\hline {\tt o\_uart\_rx\_int} & 1 & Output & True if a byte may be read from the receiver\\\hline {\tt o\_uart\_tx\_int} & 1 & Output & True if a byte may be sent to the transmitter\\\hline {\tt o\_uart\_rxfifo\_int}&1& Output & True if the receive FIFO is half full\\\hline {\tt o\_uart\_txfifo\_int}&1& Output & True if the transmit FIFO is half empty\\\hline \end{tabular}\caption{WBUART port list}\label{tbl:wbports} \end{center}\end{table} detailing the non--wishbone I/O ports of the wishbone controller. % Appendices % A. May be added to outline different specifications. (??) % Index \end{document}
Go to most recent revision | Compare with Previous | Blame | View Log