高层次综合中PE处理单元
一、PE概念1.PE也就是Processing Element处理单元。2.PE本质上是一个独立执行特定计算任务的硬件模块。3.PE在vivado hls设计中不是预先定义好的固定结构而是通过c/c代码进行设计并配合pragmas指令来定义的PE结构。二、PE的特点1.PE首先是模块化设计每个PE需要有清晰的输入和输出接口2.PE具备可复制性PE的实例化可以实现多个单元的并行设计三、PE的案例void mac_pe(float a, float b, float *acc) {#pragma HLS INLINE off#pragma HLS PIPELINE II1*acc a * b;}对函数使用inline off和pipeline进行优化其中inline off用于保证函数的独立性这个是PE的前提其中pipeline是对PE的性能进行优化设计。#pragma HLS PIPELINE II1则指定了流水线初始化间隔为1意味着每个时钟周期都能开始一次新的计算。四、PE的接口使用什么协议1.stream和pingpang-buffer是PE单元最理想的接口设计五、生产者-消费者模型#include hls_stream.hvoid producer(hls::streamint data_out) {#pragma HLS PIPELINE II1for(int i0; i1024; i) {data_out.write(i); // 写入数据到Stream}}void consumer(hls::streamint data_in) {#pragma HLS PIPELINE II1for(int i0; i1024; i) {int val data_in.read(); // 从Stream读取数据// 处理数据...}}void top_function() {#pragma HLS DATAFLOWhls::streamint data_stream;#pragma HLS STREAM variabledata_stream depth8producer(data_stream);consumer(data_stream);}六、PE实现的方式1.通过函数实例化多个PE2.通过循环分块将内存映射为PE3.使用dataflow和stream连接PE形成流水线或者网络常用结构vector向量PE矩阵阵列PE;七、使用函数来实现PE1.将PE封装为一个子函数2.将子函数使用inline off关闭内联3.PE内部使用pipeline进行优化设计4.多个PE之间使用#pragma hls dataflow进行优化八、循环展开映射PE1.可以将循环体的单次迭代封装为一个PE2.使用unroll将循环展开3.这样实现循环内部多个PE并行处理void top_parallel_dot(hls::streamint a[4], hls::streamint b[4],hls::streamint result[4], int len) {#pragma HLS DATAFLOWpe_dot_product(a[0], b[0], result[0], len);pe_dot_product(a[1], b[1], result[1], len);pe_dot_product(a[2], b[2], result[2], len);pe_dot_product(a[3], b[3], result[3], len);}