Simple UART
The intention of this module is to implement a high speed uart, at the expense of logical cores and 1-bit ports. Other modules provide lower-speed uarts that are logical core-efficient, or that may use fewer 1-bit ports. This module will support a 10 Mbaud rate with 100 MIPS logical cores, and correspondingly less with lower MIPS per logical core.
Resource Requirements
Resource
Usage
Code Memory
2110
Ports
2 x 1b
ChannelEnds
2
Logical Cores
2
Evaluation Platforms
Recommended Hardware
This module may be evaluated using the Slicekit Modular Development Platform, available from digikey. Required board SKUs are:
- XP-SKC-L2 (Slicekit L2 Core Board) plus XA-SK-XTAG2 (Slicekit XTAG adaptor) plus XTAG2 (debug adaptor), OR
- XK-SK-L2-ST (Slicekit Starter Kit, containing all of the above).
Demonstration Application
Example usage of this module can be found within the XSoftIP suite as follows:
- Package: sc_uart
- Application: app_uart_fast
API and Programming Guide
API
-
void uart_rx_fast(in port p, streaming chanend c, int clocks)
This function implements a fast UART.
It needs an unbuffered 1-bit port, a streaming channel end, and a number of port-clocks to wait between bits. It receives a start bit, 8 bits, and a stop bit, and transmits the 8 bits over the streaming channel end as a single token. On a 62.5 MIPS thread this function should be able to keep up with a 10 MBit UART sustained (provided that the streaming channel can keep up with it too).
This function does not return.
Parameters
p
input port, 1 bit port on which data comes in
c
output streaming channel - read bytes of this channel (or words if you want to read 4 bytes at a time)
clocks
number of clock ticks between bits. This number depends on the clock that you have attached to port p; assuming it is the standard 100 Mhz reference clock then clocks should be at least 10.
-
void uart_tx_fast(out port p, streaming chanend c, int clocks)
This function implements a fast UART.
It needs an unbuffered 1-bit port, a streaming channel end, and a number of port-clocks to wait between bits. It waits for a token on the streaming channel, and then sends a start bit, 8 bits, and a stop bit. On a 62.5 MIPS thread this function should be able to keep up with a 10 MBit UART sustained (provided that the streaming channel can keep up with it too).
This function does not return.
Parameters
p
output port, 1 bit port on which data should be transmitted
c
input streaming channel - output bytes of this channel (or words if you want to output 4 bytes at a time)
clocks
number of clock ticks between bits. This number depends on the clock that you have attached to port p; assuming it is the standard 100 Mhz reference clock then clocks should be at least 10.
Example Usage
Declare ports (and clock blocks if you do not want to run the ports of the reference clock):
clock refClk = XS1_CLKBLK_REF; in port rx = XS1_PORT_1A; out port tx = XS1_PORT_1B;
A function that produces data (just bytes 0..255 in this example)
void produce(streaming chanend c) { for(int i = 0; i < 256; i++) { c <: (unsigned char) i; } }
A function that consumes data (and in this example throws it away)
void consume(streaming chanend c) { unsigned char buf[256]; unsigned char foo; for(int i = 0; i < 256; i++) { c :> buf[i]; } for(int i = 0; i < 256; i++) { printhexln(buf[i]); } }
A main par that starts the logical cores:
int main(void) { streaming chan c, d; configure_out_port_no_ready(tx, refClk, 1); configure_in_port_no_ready(rx, refClk); clearbuf(rx); par { produce(d); consume(c); uart_tx_fast(tx, d, 10); uart_rx_fast(rx, c, 10); } }
Example Application
These modules can be evaluated wired back to back using app_uart_fast. To prepare the Slicekit core board to run this app connect wires between the 0.1” testpoints on the Triangle slot (or solder suitable headers on as shown in the picture below), such that ports 1A and 1E are connected. The headers corresponding to these ports are marked D0 and D12 respectively.
The app can then be built and run.