硬件高效的C语言设计

张开发
2026/5/19 6:37:04 15 分钟阅读
硬件高效的C语言设计
1. Vivado HLS 综合的 C 语言代码将在 FPGA 上执行提供与 C 语言仿真相同的功能。某些情况下开发者的工作在此阶段完成。2.在要综合的代码中使用 __SYNTHESIS__ 宏3.请勿在测试激励文件中使用该宏因为 C 语言仿真或 C RTL 协同仿真不会遵循其指示进行操作。4.局部数组将使用内部 FPGA 块 RAM 来实现5.local局部数组初始化问题6.hls::stream 对象可采用与数组相同的方式来存储数据采样。hls::stream 中的数据只能按顺序访问。在 C 语言代码中hls::stream 的行为与无限深度的 FIFO 相似。所以在Tb顶层中将hls::stream当作无限的深度的FIFO:hls::stream my_stream1;hls::stream my_stream2;for(){my_stream i;}top(my_stream1,my_stream2);for(){my_stream data;}当然你并一定总是要将hls::stream当作无限深度的FIFO虽然这个FIFO是无限深的但是我可以不用这么深我把他的深度当作1你不能让我不用吧for(){my_stream i;top(my_stream1,my_stream2);my_stream data;}这样用不是也可以嘛!!!7.在任务内广泛使用条件是不影响流水线执行的。这使任务在流水线化后可持续不断处理数据且条件结果不会影响流水线的执行不推荐在条件语句中使用任务或者pipeline流水线设计。Border:for (int i 0; i height; i) {for (int j 0; j width; j) {T pix_in, l_edge_pix, r_edge_pix, pix_out;#pragma HLS PIPELINEif (i 0 || (i border_width i height - border_width)) {if (j width - (K - 1)) {pix_in vconv.read();borderbuf[j] pix_in;}if (j 0) {l_edge_pix pix_in;}if (j width - K) {r_edge_pix pix_in;}}if (j border_width) {pix_out l_edge_pix;} else if (j width - border_width - 1) {pix_out r_edge_pix;} else {pix_out borderbuf[j - border_width];}dst pix_out;}}}这种设计是不会影响流水线设计的。8.assert的使用templatetypename T, int Kstatic void convolution_strm(int width,int height,hls::streamT src,hls::streamT dst,const T *hcoeff,const T *vcoeff){hls::streamT hconv(hconv);hls::streamT vconv(vconv);// These assertions let HLS know the upper bounds of loopsassert(height MAX_IMG_ROWS);assert(width MAX_IMG_COLS);assert(vconv_xlim MAX_IMG_COLS - (K - 1));// Horizontal convolutionHConvH:for(int col 0; col height; col) {HConvW:for(int row 0; row width; row) {HConv:for(int i 0; i K; i) {}}}// Vertical convolutionVConvH:for(int col 0; col height; col) {VConvW:for(int row 0; row vconv_xlim; row) {VConv:for(int i 0; i K; i) {}}Border:for (int i 0; i height; i) {for (int j 0; j width; j) {}}9. hls::stream模拟的是硬件中常见的FIFO先进先出队列。单向流动数据只能从一头写入write从另一头读出read。消耗性读取一次read()操作会将该数据从流中永久移除。 后续的任何模块或代码都无法再次读取同一个数据。无索引访问你不能用下标stream[5]来访问某个特定元素只能按顺序读取。10.FPGA中高速缓存“FPGA高速缓存”并不是指CPU的L1/L2 Cache而是指FPGA上能支持多路并发访问的片上存储资源通常是Block RAM (BRAM) 或寄存器阵列。void process(hls::streamfloat matrix_stream, hls::streamfloat vector_stream) {// 步骤1定义一块高速缓存综合为BRAM或寄存器阵列float vector_cache[N];// 告诉HLS将此数组完全分割为独立寄存器以实现最大并发访问#pragma HLS ARRAY_PARTITION variablevector_cache complete dim1// 步骤2将流数据写入缓存同时消费了流LOAD_VECTOR: for (int i 0; i N; i) {#pragma HLS PIPELINEvector_cache[i] vector_stream.read();}// 步骤3后续逻辑可以自由、反复地使用 vector_cache 中的任意元素PROCESS_LOOP: while (!matrix_stream.empty()) {// ... 读取矩阵元素并随时访问 vector_cache 进行运算 ...float temp matrix_stream.read() * vector_cache[5]; // 可以随机访问第5个元素}}

更多文章