cordic ip核 vivado_Xilinx Vivado CORDIC IP求解atan 反正切
賽靈思官方提供了cordic(coordinate rotational digital?computer) ip核實(shí)現(xiàn)直角坐標(biāo)極坐標(biāo)變化,三角函數(shù)的操作。我介紹下它進(jìn)行反正切求解的使用:
新建個(gè)簡(jiǎn)單工程:bd如下
進(jìn)行ip設(shè)置,選擇運(yùn)算位反正切后,ip端口回自動(dòng)變?yōu)樯蠄D,再引出2個(gè)總線和時(shí)鐘,xilinx的ip核不少是基于AXI4-Stream總線,這里使用并不復(fù)雜,默認(rèn)只有2個(gè)信號(hào),一個(gè)數(shù)據(jù)線tdata,一個(gè)握手信號(hào)tvalid,tvalid拉高時(shí)數(shù)據(jù)信號(hào)有效。
確定了輸入輸出位寬后,系統(tǒng)會(huì)自動(dòng)求解出需要的延時(shí)latency。這里說(shuō)一句,AXI-Stream總線收發(fā)基于byte的,無(wú)論輸入什么位寬最后都是8的整數(shù)倍。所以需要參照UG,放置好有效輸入位和分解輸出位。
如果輸入輸出位寬恰好不是8的倍數(shù),那么tdata位寬是大于設(shè)定的值的。所以需要上圖提到進(jìn)行填充(PAD),比如我輸入20位,x和y加起來(lái)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ù)不是這個(gè)區(qū)間還需要進(jìn)行歸一化處理(可以用除法器div_gen ip核,這里不做介紹了)。上圖是一個(gè)簡(jiǎn)單的示例,介紹輸入輸出的定點(diǎn)小數(shù)格式。整數(shù)部分的第一位是符號(hào)位,小數(shù)部分沒(méi)有符號(hào)位是正的。※Q格式:小數(shù)點(diǎn)位于第 n 位元之右側(cè),稱(chēng)為Qn 格式。
這里關(guān)于二進(jìn)制小數(shù)表示,可以看下這個(gè)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
這里我覺(jué)得還有一個(gè)細(xì)節(jié)問(wèn)題。如果輸入的數(shù)值x或y是負(fù)數(shù)小數(shù),比如1100,常規(guī)默認(rèn)符號(hào)位第一位,第二位開(kāi)始就是小數(shù)部分了,所以1010就是1.010= -1+0.25= -0.75;這種符號(hào)位后一位就是小數(shù)部分的第一位的格式就是vivado 除法器ip輸出小數(shù)的格式。也可以說(shuō)這種是0Qn format,即符號(hào)位后0位就是小數(shù)。但是cordic ip輸入要求 1Qn format,符號(hào)位結(jié)束后1位才是小數(shù)格式(為了兼容恰好等于±1的情況),那么剛剛1010就不可以直接作為cordic ip核的輸入,1010按照1Qn format,第3位才是小數(shù)部分,1010就是10.10= -1.5 因?yàn)檎麛?shù)部分是10,反碼01,補(bǔ)碼10為2,因?yàn)槭秦?fù)數(shù)所以-2,小數(shù)部分是0.5,最終結(jié)果是-2+0.5=1.5。這樣就不符合cordic ip核輸入要求了。從0Qn改為1Qn為了滿足,如果是絕對(duì)值小于1的數(shù)只要在符號(hào)位后重復(fù)符號(hào)位就可以了,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");//打開(kāi)文件
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);//寫(xiě)數(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
給個(gè)簡(jiǎn)單的testbench
在modelsim中可以設(shè)置小數(shù)位數(shù),顯示出具體的數(shù)值。
如果自己參考文獻(xiàn),用HDL實(shí)現(xiàn)一個(gè)CORDIC算法的模塊,應(yīng)該是很不錯(cuò)了。但是我偷懶直接用現(xiàn)成IP了
總結(jié)
以上是生活随笔為你收集整理的cordic ip核 vivado_Xilinx Vivado CORDIC IP求解atan 反正切的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 美团骑手app如何操作
- 下一篇: es管理kabina_小白学ES 05