Background
In my last blog there was an example of a AXI Stream between the DMA IP and UART IP, here the module definition (from github)
module uart_axis #( parameter CLKS_PER_BIT = 16 )
(
/*
*/
input wire axis_aclk,
input wire axis_reset,
/*
* AXI input
*/
input wire [7:0] s_axis_tdata,
input wire s_axis_tvalid,
output wire s_axis_tready,
/** AXI output */
output wire [7:0] m_axis_tdata,
output wire m_axis_tvalid,
input wire m_axis_tready,
output wire m_axis_tlast,
/*
* UART: 1200000 bps, 8N1
*/
input wire uart_rxd,
output wire uart_txd
);
DMA IP connects to m_axis_* and s_axis, and uses tready as flow control. It is possible to chain several of these modules together m_axis to s_axis. Instead of having one big file, connect each one back to back.
Serial protocol
The microblaze handles a lot of the encoding/decoding/CRC of the packet, see basicProtocol::onRecv and basicProtocol::sendPacket protocol.h in github. So, I have been working breaking up the code into 3 AXI streams
- CRC AXI Stream module to do append a CRC at the end of the data (this replace computing the CRC in basicProtocol::sendPacket.
- There is a good Verilog code generator to create the proper code to calculate a CRC in parallel for a user defined polynomial. For code example see github here is a simple test-bench
- Wrapped the CRC code to reset the CRC back to 0xFFFF and add it to the end of the stream when TLAST is asserted. See github)
- AXI Stream to perform the packet formatting, the last part of the function basicProtocol::sendPacket.
- The first byte of the packet must be SOP (0x7E)
- If the SOP, EOP or ESC is in data stream replace with ESC and add the data xor'ed with 0x20.
- AXI Stream for TX serial.
I have been working on a single test bench using verilator to use the C++ code to generate ping (without CRC and ESC processing) send it to the Verilog stream for calculating the CRC and ESC formatting then pipe the bytes back to C++ for decoding. (That will be the next blog) Here is a start of the test bench.