设计一:
#include "ap_int.h"
#define DATA_WIDTH 8
void uart_tx(
ap_uint<DATA_WIDTH> s_axis_tdata, // AXI Stream 数据
ap_uint<1> s_axis_tvalid, // AXI Stream 有效
ap_uint<1> &s_axis_tready, // AXI Stream 就绪
ap_uint<1> &txd, // UART 发送
ap_uint<1> &busy, // 忙标志
ap_uint<16> prescale // 波特率分频因子(每个位周期 = prescale * 8 个时钟)
) {
#pragma HLS INTERFACE ap_none port=s_axis_tdata
#pragma HLS INTERFACE ap_none port=s_axis_tvalid
#pragma HLS INTERFACE ap_none port=s_axis_tready
#pragma HLS INTERFACE ap_none port=txd
#pragma HLS INTERFACE ap_none port=busy
#pragma HLS INTERFACE ap_none port=prescale
#pragma HLS INTERFACE ap_ctrl_none port=return
static ap_uint<1> s_axis_tready_reg = 0;
static ap_uint<1> txd_reg = 1;
static ap_uint<1> busy_reg = 0;
static ap_uint<DATA_WIDTH+1> data_reg = 0;
static ap_uint<19> prescale_reg = 0; // 支持 prescale<<3
static ap_uint<4> bit_cnt = 0;
// 组合输出
s_axis_tready = s_axis_tready_reg;
txd = txd_reg;
busy = busy_reg;
if (prescale_reg > 0) {
// 位周期计数中
s_axis_tready_reg = 0;
prescale_reg = prescale_reg - 1;
} else if (bit_cnt == 0) {
s_axis_tready_reg = 1;
busy_reg = 0;
if (s_axis_tvalid) {
s_axis_tready_reg = 0;
prescale_reg = (prescale << 3) - 1;
bit_cnt = DATA_WIDTH + 1;
data_reg = (1 << DATA_WIDTH) | s_axis_tdata;
txd_reg = 0;
busy_reg = 1;
}
} else {
if (bit_cnt > 1) {
bit_cnt = bit_cnt - 1;
prescale_reg = (prescale << 3) - 1;
txd_reg = data_reg0;
data_reg = data_reg >> 1;
} else if (bit_cnt == 1) {
// 发送停止位
bit_cnt = bit_cnt - 1;
prescale_reg = prescale << 3;
txd_reg = 1;
}
}
}
设计二:
#include <hls_stream.h>
#include <ap_int.h>
#define DATA_WIDTH 8
void uart_tx(
hls::stream<ap_uint<DATA_WIDTH> >& s_axis, // AXI4-Stream 输入(数据)
ap_uint<1> &txd, // UART 发送线
ap_uint<1> &busy, // 忙标志
ap_uint<16> prescale // 波特率分频因子(每个位周期 = prescale * 8 个时钟)
) {
#pragma HLS INTERFACE axis port=s_axis
#pragma HLS INTERFACE ap_none port=txd
#pragma HLS INTERFACE ap_none port=busy
#pragma HLS INTERFACE ap_none port=prescale
#pragma HLS INTERFACE ap_ctrl_none port=return
static ap_uint<1> txd_reg = 1;
static ap_uint<1> busy_reg = 0;
static ap_uint<DATA_WIDTH+1> data_reg = 0;
static ap_uint<19> prescale_reg = 0;
static ap_uint<4> bit_cnt = 0;
txd = txd_reg;
busy = busy_reg;
if (prescale_reg > 0) {
prescale_reg = prescale_reg - 1;
} else if (bit_cnt == 0) {
busy_reg = 0;
txd_reg = 1;
ap_uint<DATA_WIDTH> rx_data;
if (s_axis.read_nb(rx_data)) {
prescale_reg = (prescale << 3) - 1;
bit_cnt = DATA_WIDTH + 1;
data_reg = (1 << DATA_WIDTH) | rx_data;
txd_reg = 0;
busy_reg = 1;
}
} else {
if (bit_cnt > 1) {
bit_cnt = bit_cnt - 1;
prescale_reg = (prescale << 3) - 1;
txd_reg = data_reg0;
data_reg = data_reg >> 1;
} else if (bit_cnt == 1) {
bit_cnt = bit_cnt - 1;
prescale_reg = prescale << 3;
txd_reg = 1;
}
}
}