cordic ip核 vivado_Xilinx Vivado CORDIC IP求解atan 反正切
賽靈思官方提供了cordic(coordinate rotational digital?computer) ip核實現(xiàn)直角坐標(biāo)極坐標(biāo)變化,三角函數(shù)的操作。我介紹下它進(jìn)行反正切求解的使用:
新建個簡單工程:bd如下
進(jìn)行ip設(shè)置,選擇運算位反正切后,ip端口回自動變?yōu)樯蠄D,再引出2個總線和時鐘,xilinx的ip核不少是基于AXI4-Stream總線,這里使用并不復(fù)雜,默認(rèn)只有2個信號,一個數(shù)據(jù)線tdata,一個握手信號tvalid,tvalid拉高時數(shù)據(jù)信號有效。
確定了輸入輸出位寬后,系統(tǒng)會自動求解出需要的延時latency。這里說一句,AXI-Stream總線收發(fā)基于byte的,無論輸入什么位寬最后都是8的整數(shù)倍。所以需要參照UG,放置好有效輸入位和分解輸出位。
如果輸入輸出位寬恰好不是8的倍數(shù),那么tdata位寬是大于設(shè)定的值的。所以需要上圖提到進(jìn)行填充(PAD),比如我輸入20位,x和y加起來40位,那么輸入S_AXIS的位寬是48,我要在0-19放x,20-23放填充數(shù)據(jù)(隨意,我用0),24-43放y,44-47放填充數(shù)據(jù)。必須保證0-19和24-25分別是我的x和y。
atan=y/x,要求輸入必須是[-1,1],所以如果數(shù)據(jù)不是這個區(qū)間還需要進(jìn)行歸一化處理(可以用除法器div_gen ip核,這里不做介紹了)。上圖是一個簡單的示例,介紹輸入輸出的定點小數(shù)格式。整數(shù)部分的第一位是符號位,小數(shù)部分沒有符號位是正的。※Q格式:小數(shù)點位于第 n 位元之右側(cè),稱為Qn 格式。
這里關(guān)于二進(jìn)制小數(shù)表示,可以看下這個https://blog.csdn.net/AaricYang/article/details/87882868。整數(shù)的每一位權(quán)重是2^(n-1) 111就是2^2+2^1+2^0=7,小數(shù)部分的權(quán)重是2^(-n) 0.111就是2^(-1)+2^(-2)+2^(-3)=0.875
這里我覺得還有一個細(xì)節(jié)問題。如果輸入的數(shù)值x或y是負(fù)數(shù)小數(shù),比如1100,常規(guī)默認(rèn)符號位第一位,第二位開始就是小數(shù)部分了,所以1010就是1.010= -1+0.25= -0.75;這種符號位后一位就是小數(shù)部分的第一位的格式就是vivado 除法器ip輸出小數(shù)的格式。也可以說這種是0Qn format,即符號位后0位就是小數(shù)。但是cordic ip輸入要求 1Qn format,符號位結(jié)束后1位才是小數(shù)格式(為了兼容恰好等于±1的情況),那么剛剛1010就不可以直接作為cordic ip核的輸入,1010按照1Qn format,第3位才是小數(shù)部分,1010就是10.10= -1.5 因為整數(shù)部分是10,反碼01,補碼10為2,因為是負(fù)數(shù)所以-2,小數(shù)部分是0.5,最終結(jié)果是-2+0.5=1.5。這樣就不符合cordic ip核輸入要求了。從0Qn改為1Qn為了滿足,如果是絕對值小于1的數(shù)只要在符號位后重復(fù)符號位就可以了,1 010改為11 010,這樣就可以正常輸入到cordic中了。
`timescale 1 ns / 1psmodulecordic_tb_top;regaclk;wire [31:0]M_AXIS_DOUT_0_tdata;wireM_AXIS_DOUT_0_tvalid;reg [47:0]S_AXIS_CARTESIAN_0_tdata;regS_AXIS_CARTESIAN_0_tvalid;integer handle;
initial beginaclk=0;
S_AXIS_CARTESIAN_0_tvalid=1'b0;
S_AXIS_CARTESIAN_0_tdata='b0;
end
initial handle = $fopen("D:/FPGAcode/_file/cordic.txt");//打開文件
always #10 aclk=~aclk;localparam PAD=(48-20*2)/2;always@(posedge aclk) beginS_AXIS_CARTESIAN_0_tvalid<=1'b1;
S_AXIS_CARTESIAN_0_tdata<={{PAD{1'b0}},{3'b000,17'b0},{PAD{1'b0}},{3'b111,17'b0}};end
always@(posedge aclk) begin
if(M_AXIS_DOUT_0_tvalid)
$fdisplay(handle,"%b",M_AXIS_DOUT_0_tdata);//寫數(shù)據(jù)
enddesign_1_wrapper design_1_i
(.M_AXIS_DOUT_0_tdata(M_AXIS_DOUT_0_tdata),
.M_AXIS_DOUT_0_tvalid(M_AXIS_DOUT_0_tvalid),
.S_AXIS_CARTESIAN_0_tdata(S_AXIS_CARTESIAN_0_tdata),
.S_AXIS_CARTESIAN_0_tvalid(S_AXIS_CARTESIAN_0_tvalid),
.aclk_0(aclk));endmodule
給個簡單的testbench
在modelsim中可以設(shè)置小數(shù)位數(shù),顯示出具體的數(shù)值。
如果自己參考文獻(xiàn),用HDL實現(xiàn)一個CORDIC算法的模塊,應(yīng)該是很不錯了。但是我偷懶直接用現(xiàn)成IP了
總結(jié)
以上是生活随笔為你收集整理的cordic ip核 vivado_Xilinx Vivado CORDIC IP求解atan 反正切的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 美团骑手app如何操作
- 下一篇: es管理kabina_小白学ES 05