一、why FPGA
1.FPGA可以自定义数据类型
2.FPGA可以自定义数据路径,dataflow or pipeline
3.有效的memory访问,可以random access,FIFO,stack
4.parallelism并行化没有限制
二、FPGA开发趋于简单化
1.可以使用c/c++/system c,opencl,python来开发FPGA
2.tenssorflow
三、HLS代码结构
1.top-level函数定义
2.interface接口定义
3.dataflow the processing
4.internal streaming variable变量声明
5.synchronize to start of frame帧同步开始
6.covert from axi stream to xf::Mat
四、HLS让FPGA开发变得简单
五、并行化
并行化有两种
1.data-level parallesim
2.task-level parallelism
3.Instruction(operator) level parallelsim
在HLS设计中需要考虑的data-level和task-level的并行化,
不需要考虑指令或者操作的并行化,指令和操作的并行化是HLS帮我们做了。
六、CPU和FPGA
1.cpu使用得地址空间都是虚拟的地址空间
2.FPGA使用的地址空间都是physical address space
七、组合逻辑 + 时序逻辑模型设计
1.单个组合逻辑+时序逻辑设计模型
void comb_sequential_top
(
ap_uint<32> in1,
ap_uint<32> in2,
ap_uint<32> *out
){
#pragma HLS INTERFACE ap_ctrl_none port=return
#pragma HLS INTERFACE ap_none port=in1
#pragma HLS INTERFACE ap_none port=in2
#pragma HLS INTERFACE ap_none port=out
static int L;//flip-flop
*out = in1 * L;//read current-L
L = in2 + L;//assign next-L
}
2.多个组合逻辑+时序逻辑模型
void sub1_func(
ap_uint<32> in1,
ap_uint<32> in2,
ap_uint<32> *out
){
#pragma HLS INLINE off
static int L;//flip-flop
*out = in1 * L;//read current-L
L = in2 + L;//assign next-L
}
void sub2_func(
ap_uint<32> in1,
ap_uint<32> in2,
ap_uint<32> *out
){
#pragma HLS INLINE off
static int L;//flip-flop
*out = in1 * L;//read current-L
L = in2 + L;//assign next-L
}
void comb_sequential_top
(
ap_uint<32> in1,
ap_uint<32> *out
){
#pragma HLS INTERFACE ap_ctrl_none port=return
#pragma HLS INTERFACE ap_none port=in1
#pragma HLS INTERFACE ap_none port=out
ap_uint<32> tmp1;
ap_uint<32> tmp2;
sub1_func(in1,tmp2,&tmp1);
sub2_func(tmp1,tmp1,&tmp2);
*out = tmp2;
}
上述这个代码综合设计,发现综合的rtl代码,并没有实现两次组合逻辑+时序逻辑模块,为什么??
template<int N>
void sub1_func(
ap_uint<32> in1,
ap_uint<32> in2,
ap_uint<32> *out
){
#pragma HLS INLINE off
static int L;//flip-flop
*out = in1 * L;//read current-L
L = in2 + L;//assign next-L
}
template<int N>
void sub2_func(
ap_uint<32> in1,
ap_uint<32> in2,
ap_uint<32> *out
){
#pragma HLS INLINE off
static int L;//flip-flop
*out = in1 * L;//read current-L
L = in2 + L;//assign next-L
}
void comb_sequential_top
(
ap_uint<32> in1,
ap_uint<32> *out
){
#pragma HLS INTERFACE ap_ctrl_none port=return
#pragma HLS INTERFACE ap_none port=in1
#pragma HLS INTERFACE ap_none port=out
ap_uint<32> tmp1;
ap_uint<32> tmp2;
sub1_func<1>(in1,tmp2,&tmp1);
sub1_func<2>(tmp1,tmp1,&tmp2);
*out = tmp2;
}
使用模板函数好像实现的功能也不太对!!!
这个后续专门对这块设计进行说明!!!
3.two-module
void comb_sequential_top
(
ap_uint<32> in1,
ap_uint<32> *out
){
#pragma HLS INTERFACE ap_ctrl_none port=return
#pragma HLS INTERFACE ap_none port=in1
#pragma HLS INTERFACE ap_none port=out
ap_uint<32> tmp1;
ap_uint<32> tmp2;
sub1_func(in1,in1,&tmp1);
sub1_func(tmp1,tmp1,&tmp2);
*out = tmp2;
}