协同仿真死锁查看器 - 2021.2 Chinese

Vitis 高层次综合用户指南 (UG1399)

Document ID
UG1399
Release Date
2021-12-15
Version
2021.2 Chinese

所谓死锁指的是在某个 DATAFLOW 区域内,由于进程共享相同的通道,阻碍彼此读取或写入该区域,从而导致这两个进程都卡死。如果 DATAFLOW 内部存在 FIFO 通道或者混用 PIPO 和 FIFO 作为通道,那么这种状况很常见。

死锁查看器可以在静态数据流查看器上直观显示此死锁场景。它会高亮存在问题的进程和通道。此查看器还提供交叉探测功能,在有问题的数据通道与关联的源代码之间建立链接。用户可以使用这些信息来快速轻松解决问题。该查看器仅在协同仿真检测到死锁状况并且协同仿真运行完成后才会打开。

以下显示了一个小示例。数据流区域包含 2 个进程,这 2 个进程通过 PIPO 和 FIFO 来进行通信。proc_1 中的首个循环会在 data_array 中写入任何内容之前,先在 data_channel1 中写入 10 个数据项。由于 FIFO 深度不足,data_channel 无法完成,导致其余进程无法完成。随后,proc_2 也会阻塞,因为它无法从 data_channel2 读取数据(因为该通道为空),并且无法从 data_channel1 移除任何数据。这样就会造成死锁,需将 data_channel1 大小至少增大至 10。

void example(hls::stream<data_t>& A, hls::stream<data_t>& B){
#pragma HLS dataflow
..
..
hls::stream<int> data_channel;
int data_array[10];
#pragma HLS STREAM variable=data_channel depth=8 dim=1
    proc_1(A, data_channel, data_array);
    proc_2(B, data_channel, data_array);
}

void proc_1(hls::stream<data_t>& A, hls::stream<int>& data_channel, int data_array[10]){
  …
  for(i = 0; i < 10; i++){
    tmp = A.read();
    tmp.data = tmp.data.to_int();
    data_channel.write(tmp.data);
  }
  for(i = 0; i < 10; i++){
      data_array[i] = i + tmp.data.to_int();
  }
}

void proc_2(hls::stream<data_t>& B, hls::stream<int>& data_channel, int data_array[10]){
  int i;
  ..
  ..
  for(i = 0; i < 10; i++){
      if (i == 0){
        tmp.data = data_channel.read() + data_array[5];
      }
      else {
        tmp.data = data_channel.read();
      }
    B.write(tmp);
  }
协同仿真日志:
///////////////////////////////////////////////////////////////////////////////////
// Inter-Transaction Progress: Completed Transaction / Total Transaction
// Intra-Transaction Progress: Measured Latency / Latency Estimation * 100%
//
// RTL Simulation : "Inter-Transaction Progress" ["Intra-Transaction Progress"] @ "Simulation Time"
////////////////////////////////////////////////////////////////////////////////////
// RTL Simulation : 0 / 1 [0.00%] @ "105000"
//////////////////////////////////////////////////////////////////////////////
// ERROR!!! DEADLOCK DETECTED at 132000 ns! SIMULATION WILL BE STOPPED! //
//////////////////////////////////////////////////////////////////////////////
/////////////////////////
// Dependence cycle 1:
// (1): Process: example_example.proc_1_U0
//      Channel: example_example.data_channel1_U, FULL
// (2): Process: example_example.proc_2_U0
//      Channel: example_example.data_array_U, EMPTY
////////////////////////////////////////////////////////////////////////
// Totally 1 cycles detected!
////////////////////////////////////////////////////////////////////////
图 1. 死锁查看器