浮點具有更大的數據動態范圍,從而在很多算法中只需要一種數據類型的優勢。 本文介紹如何使用Vivado HLS實現浮點復數矩陣分解。使用HLS可以快速,高效地實現各種矩陣分解算法,極大地提高生產效率, 降低開發者的算法FPGA實現難度。
?
void matrix_dcmp
(
cf_t in_u[(R_DIM+Y_DIM)/DIV_NUM][DIV_NUM],
cf_t pd_err_in,
float lamda,
float lamda_sqrt,
float diag[R_DIM],
cf_t r[R_DIM][X_DIM],
cf_t p[R_DIM]
)
{
coef_cal(lamda_sqrt,lamda,diag[i],pre_in_u,pd_err_in,&s_o,&s_conj_o,&la
mda_sqrtxs_o,&c_o,&lamda_sqrtxc_o,&diag_out,&p_o,&pd_err);
cal_core(u_tmp, r_tmp, s_n, i, j, k, c_o, lamda_sqrtxc_o, lamda_sqrtxs_o,
s_conj_o, &in_u_w2, &r[i][r_addr]);
}
void coef_calc
(
float lamda_sqrt,
float lamda,
float r_diag,
cf_t u_diag,
cf_t pd_err_in,
cf_t *s,
cf_t *s_conj,
cf_t *lamda_sqrtxs,
float *c,
float *lamda_sqrtxc,
float *diag,
cf_t *p_o,
cf_t *pd_err
)
void calc_core
(
cf_t in_u,
cf_t r,
int s_n,
int i,
unsigned char j,
unsigned char k,
float c_o,
float lamda_sqrtxc_o,
cf_t lamda_sqrtxs_o,
cf_t s_conj_o,
cf_t* u_ret,
cf_t* r_ret
)
Vivado-HLS生成的RTL代碼在默認情況下保留原有c代碼的層次結構,在構建c代碼層次時,可以采用由上至下,從下至上相結合的模塊劃分方式。對基本的浮點運算如加,減,乘,除,平方根等寫成最底層的子函數,并對其加pipeline, 甚至對輸出打一拍register以獲得更好的時序性能。如下例:
template T reg(T x) {
#pragma HLS inline self off
#pragma HLS interface ap_none register port=return
return x;
}
cf_t mult( cf_t in1, cf_t in2 ) {
#pragma HLS PIPELINE
cf_t out;
float in1_re_in2_re, in1_im_in2_im, in1_re_in2_im, in1_im_in2_re;
in1_re_in2_re = hfmult(in1.re,in2.re);
in1_im_in2_im = hfmult(in1.im,in2.im);
in1_re_in2_im = hfmult(in1.re,in2.im);
in1_im_in2_re = hfmult(in1.im,in2.re);
out.re = (in1_re_in2_re - in1_im_in2_im);
out.im = (in1_re_in2_im + in1_im_in2_re);
return reg(out);
}
float hfmult
(
float in1,
float in2
)
{
#pragma HLS PIPELINE
float out;
out = in1 * in2;
return reg(out);
}
另外為了提高運算的并行度,需要對matrix_dcmp中in_u及r數組(HLS綜合成FPGA的BRAM或分布式RAM)加數組分割這個directive,這樣數據才可以并行進來到并行處理單元。
#pragma HLS ARRAY_PARTITION variable=in_u complete dim=2
#pragma HLS ARRAY_PARTITION variable=r complete dim=2
3,Vivado-HLS矩陣分解時序優化
為了使in_u綜合出的RAM時序更好,可以對in_u綜合的RAM加resource directive來控制其為3 stage,這樣生成的RAM輸入,輸出都會打一拍register。
#pragma HLS RESOURCE variable=in_u core=RAM3S
同樣我們也可以通過設置充足的latency directive給DSP48,這樣有足夠的時鐘節拍給到DSP48內部打拍register。
如果對上述的單精度浮點乘法hfmult latency設置為3,這樣分配到每個DSP48 內部只有2級latency, 那么綜合總合出來代碼DSP48內部的A_reg 或 P_reg不會打一拍, 這樣對時序性能有很大下降。
derive_core fmul_der -base FMul_maxdsp -latency 3 -fixed
set_directive_resource -core fmul_der hfmult out
?
或
?
為了達到較好的時序性能,對上述的單精度浮點乘法hfmult latency至少設置為4,這樣分配到每個DSP48 內部只有3級latency, 那么綜合總合出來代碼DSP48內部的A_reg 或 P_reg都會各打一拍。
derive_core fmul_der -base FMul_maxdsp -latency 4 -fixed
set_directive_resource -core fmul_der hfmult out
?
4,Vivado-HLS矩陣分解設計結果
這個設計中矩陣的大小是128x128的單精度浮點,復數。
采用了串行與并行結合的實現方式。
評論
查看更多