数据驱动的 TLP 设计使用 hls::task
持续运行直至复位。这些模块支持未同步的 I/O,无论模块是在执行中还是处于空闲状态,这些 I/O 均可随时更改;与此不同的是,在控制驱动的 TLP 中,空闲状态下只有输入会发生更改。模块设计师对更改的时机并无特定要求,只要模块能在某个时间点看到更新后的数据即可。
未同步的 I/O 有两种类型:
- 标量:主机定期检查寄存器的状态,查看值是否有更改
- 存储器 I/O:模块接收来自主机代码的 DRAM 缓冲器,并对其进行私下管理
未同步的 I/O 应在 KPN 上下文中标记为 stable
,如以下代码示例所示。
void write_process(hls::stream<int>& in,
hls::stream<int>& out,
int* mem)
{
#pragma HLS PIPELINE off
int val;
static int addr = 0;
in.read(val);
if (addr >= 32)
addr = 0;
//hls::print("writing %d\n", addr);
mem[addr] = val;
addr++;
val = mem[addr-1];
out.write(val);
}
...
...
...
...
void stable_pointer(int* mem,
hls::stream<int>& in,
hls::stream<int>& out)
{
#pragma HLS DATAFLOW
#pragma HLS INTERFACE mode=s_axilite port=mem offset=30
#pragma HLS INTERFACE mode=m_axi bundle=gmem depth=256 max_read_burst_length=16 \
max_widen_bitwidth=512 max_write_burst_length=16 num_read_outstanding=16 \
num_write_outstanding=16 port=mem
#pragma HLS stable variable=mem
hls_thread_local hls::stream<int> int_fifo("int_fifo");
#pragma HLS STREAM depth=512 type=fifo variable=int_fifo
hls_thread_local hls::stream<int> int_fifo2("int_fifo2");
#pragma HLS STREAM depth=512 type=fifo variable=int_fifo2
hls_thread_local hls::task t1(process_23, in, int_fifo);
hls_thread_local hls::task t2(process_11, int_fifo, int_fifo2);
hls_thread_local hls::task t3(write_process, int_fifo2, out, mem);
}
对于 C/RTL 协同仿真,需通过 cosim.enable_tasks_with_m_axi
命令为 hls::task
和 M_AXI 接口启用未同步的访问,如 协同仿真配置 中所述。