video_to_axi_stream
一、video转stream设计#include frame_top.hvoid video_to_axi_stream(pixel_t in_data,ap_uint1 vsync,ap_uint1 hsync,ap_uint1 de,hls::streamaxis_pkt_t output_stream) {#pragma HLS INTERFACE ap_ctrl_none portreturn#pragma HLS INTERFACE ap_none portin_data#pragma HLS INTERFACE ap_none portvsync#pragma HLS INTERFACE ap_none porthsync#pragma HLS INTERFACE ap_none portde#pragma HLS INTERFACE axis register both portoutput_streamstatic bool vsync_d1 true; // 上一拍 vsyncstatic bool de_d1 false; // 上一拍 destatic ap_uint12 pixel_cnt 0; // 行内像素计数static bool sof false; // 帧起始标志axis_pkt_t out_pkt;// ❶ 边沿检测在使用延迟值之后才更新延迟寄存器bool vsync_rise (vsync_d1 0) (vsync 1);bool de_rise (de 1) (de_d1 0);vsync_d1 vsync; // 更新延迟值de_d1 de;// ❷ vsync 上升沿新的一帧开始置位 sof 并复位行计数器if (vsync_rise) {sof true;pixel_cnt 0;}// ❸ de 上升沿新的一行有效数据开始复位行计数器if (de_rise) {pixel_cnt 0;}// ❹ 输出有效像素if (de 1) {out_pkt.data in_data;out_pkt.user sof (pixel_cnt 0); // 帧首第一个像素out_pkt.last (pixel_cnt (H_ACTIVE - 1)); // 行尾最后一个像素output_stream.write(out_pkt);if (sof pixel_cnt 0) sof false; // 帧首标志仅维持一拍pixel_cnt; // 计数}}上述代码是存在问题的其不满足综合设计要求的三大条件二、三大条件分析三条条件是条件一组合逻辑设计。条件二流水线设计且任务间隔为 1。条件三带有 array streaming 或 hls::stream 或 AXI4 stream 端口的 design。条件三并不是说你的数组按照hls::stream AXI4 stream设计就行这里默认了一个条件就是数据流设计就是你的输入和输出次数是意义对应的不是说你的接口数组设计为阻塞的流设计就行了如果你这么理解你就太肤浅了哈。void video_to_axi_stream(pixel_t in_data,ap_uint1 vsync,ap_uint1 hsync,ap_uint1 de,hls::streamaxis_pkt_t output_stream);这个接口虽然满足了条件三但是内部设计需要满足output_stream这个流能够及时的将pixel_t in_data,ap_uint1 vsync,ap_uint1 hsync,ap_uint1 de,这几个接口信号的数据处理掉才行如果处理不掉不好意思啊出问题了。因为上述的接口是free-run模式的参数更新后续的hls::streamaxis_pkt_t output_stream是阻塞的流是否能够将free-run内部的数据处理掉这个需要内部设计注意Vivado HLS 2018.3 对这条规则的实际解释是整个设计必须是一个纯粹的流处理流水线即主要功能是从流中消费数据、处理、再产出流。你的设计有以下不符合“流处理范式”的特征三、分析代码第一条不是组合逻辑因为有静态变量和状态机所以不满足。第二条使用 ap_ctrl_none 时函数像一个无限循环自由运行无法定义任务间隔HLS 不会将其综合为 II1 的可流水线化任务因为输入是 ap_none 且内部有状态通常综合为顺序逻辑但没有开始/完成握手无法以任务模型衡量 II。因此不满足。第三条虽然有 AXI4 stream 端口但设计并非“流处理”模型。工具的检查可能要求输入也应该是流接口并且整个设计是数据流驱动从流中读取、处理、写入流。而这里输入是 ap_none 的非流信号且内部依赖于外部自由运行的时钟状态机不符合流处理范式。Vivado HLS 2018.3 对第三条的解释较严格它要求设计是纯粹的流处理流水线而不是简单的带有 stream 端口的任意控制逻辑。因此会被拒绝。所以总结不满足第三条也不满足前两条。三条都不满足所以报错。规则一纯组合逻辑设计你的设计内部有 static 变量vsync_d1、de_d1、pixel_cnt、sof并且使用了状态机边沿检测、计数器这显然是时序逻辑而非组合逻辑。➜ 不满足规则二流水线设计且任务间隔为 1当使用 ap_ctrl_none 时工具将函数视为自由运行模块类似一个无限循环的硬件块没有明确的“任务”概念。虽然内部逻辑可以流水化但因为没有 ap_start/ap_done 等握手信号工具无法定义任务间隔II。更重要的是该设计每次调用的行为依赖于静态变量的历史不能简单地以一个确定的任务间隔来重复启动。因此它不能被归类为 II1 的流水线任务。➜ 不满足。规则三带有数组流 / hls::stream / AXI4‑Stream 端口的设计表面上看你的模块有 hls::streamaxis_pkt_t 输出似乎满足这条。但 Vivado HLS 2018.3 对这条规则的实际解释是整个设计必须是一个纯粹的流处理流水线即主要功能是从流中消费数据、处理、再产出流。你的设计有以下不符合“流处理范式”的特征输入不是流所有输入in_data, vsync, hsync, de都是 ap_none 的非流信号工具无法将它们建模为 FIFO 通道。行为本质上是一个自由运行的时序转换器并非“读取流 → 处理 → 写入流”的数据驱动模型。内部关键控制依赖于 vsync 和 de 的边沿以及计数器状态这属于控制密集型逻辑而不是数据流密集型。因此工具判定它不属于“具有流端口的流处理设计”拒绝协同仿真。➜ 不满足。四、修改为ap_ctrl_hs或者ap_ctrl_chain是否可行修改为ap_ctrl_hs也是解决不了问题的仿真可能还是出问题的需要你认真分析代码设计的问题解决了问题才行并不是ap_Ctrl_none不行你直接改为ap_Ctrl_hs就行有时候你可以这么干有时候不行这个要具体问题具体分析