ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

002-CORDIC实现幅度相位求解

2019-10-06 21:01:22  阅读:308  来源: 互联网

标签:26 clk CORDIC 相位 signed ii 002 rst pha


2019年10月6日19:10:11

原理不再赘述,MATLAB:

function [pha, amp] = cordic(x, y)
%仅以第一象限为例
K = 0.607253;
atanTable = atand(2.^([0:-1:-15]))/180;
len = length(atanTable);
pha = 0;
for i = 0:len-1
    if (y>0)
        x_new = x + y*2^-i;%此处移位寄存器实现
        y_new = y - x*2^-i;%此处移位寄存器实现
        x = x_new;
        y = y_new;
        pha = pha + atanTable(i+1);
    else
        x_new = x-y*2^-i;%此处移位寄存器实现
        y_new = y+x*2^-i;%此处移位寄存器实现
        x = x_new;
        y = y_new;
        pha = pha-atanTable(i+1);
    end
end
amp = K * x;

  

实现思路与除法CORDIC类似,对应FPGA代码:

tb

`timescale 1ns / 1ps

module tb;
/************* PARAMETER ******************/
parameter LOOPS = 26;
parameter DATWIDTH = 26;
//parameter RESWIDTH = 12;
parameter PHAWIDTH = 26;
parameter AMPWIDTH = 26;
/**************** INPUT OUTOUT ************/
logic    signed    [DATWIDTH - 1:0]    fracDown;
logic    signed    [DATWIDTH - 1:0]    fracUp;
logic    signed    [AMPWIDTH - 1:0]    amp;
logic    signed    [PHAWIDTH - 1:0]    pha;
//logic    signed    [RESWIDTH - 1:0]    divRes;
/**************** INITIAL *****************/
logic    clk;
logic    rst;

initial begin
clk = 0;
rst = 1'b1;
fracDown = 0;
fracUp = 0;
#20
rst = 1'b0;
#200
fracDown = 26'd2000;
fracUp = 26'd2000;

#200
fracDown = 26'd4000;
fracUp = 26'd5000;

#200
fracDown = 26'd5000;
fracUp = 26'd4000;

#200
fracDown = 26'd5000;
fracUp = 26'd5000;

#1000
$stop;
end
always #2 clk = !clk;
/**************** CORDIC AMP PHA *********************/
cordicAmpPha UcordicAmpPha(
	.clk(clk), 
	.rst(rst), 
	.dataReal(fracDown), 
	.dataImag(fracUp), 
	.amp(amp), 
	.pha(pha)
);
/**************** CORDIV ******************/
/* cordic_div #(
	.LOOPS(LOOPS),
	.DATWIDTH(DATWIDTH),
	.RESWIDTH(RESWIDTH)
)
Ucordic_div(
	.clk(clk), 
	.rst(rst), 
	.fracDown(fracDown), 
	.fracUp(fracUp), 
	.divRes(divRes)
);
 */

 
glbl glbl();
endmodule

  cordicAmpPha

`timescale  1ns / 1ps

module cordicAmpPha(clk, rst, dataReal, dataImag, amp, pha);
/****************** PARAMETER *********************/
parameter DATAWIDTH = 26;
parameter AMPWIDTH = 26;
parameter PHAWIDTH = 26;
parameter LOOP = 26;
//localparam K = 12'h4DC;

wire    [0:LOOP - 1][PHAWIDTH - 1:0]    atanTable = {
26'h800000,
26'h4B9014,
26'h27ECE1,
26'h144447,
26'h0A2C35,
26'h051760,
26'h028BD8,
26'h0145F1,
26'h00A2F9,
26'h00517D,
26'h0028BE,
26'h00145F,
26'h000A30,
26'h000518,
26'h00028C,
26'h000146,
26'h0000A3,
26'h000051,
26'h000029,
26'h000014,
26'h00000A,
26'h000005,
26'h000003,
26'h000001,
26'h000001,
26'h000000
};
/****************** INPUT OUTPUT ******************/
input    clk;
input    rst;
input    signed    [DATAWIDTH - 1:0]    dataReal;	
input    signed    [DATAWIDTH - 1:0]    dataImag;
output    signed    [AMPWIDTH - 1:0]    amp;
output    signed    [PHAWIDTH - 1:0]    pha;	
/****************** CORDIC ******************/
wire    signed    [LOOP:0][DATAWIDTH - 1:0]    datasReal;
wire    signed    [LOOP:0][DATAWIDTH - 1:0]    datasImag;
wire    signed    [LOOP:0][PHAWIDTH - 1:0]    phas;
//reg    signed    [2*AMPWIDTH - 1:0]    amp1;

assign datasReal[0] = dataReal;
assign datasImag[0] = dataImag;
assign phas[0] = {PHAWIDTH{1'b0}};

genvar ii;
generate
for (ii = 0; ii < LOOP; ii = ii + 1)
begin:cordic_ii
	cordicAmpPhaUnit #(
	.DATAWIDTH(DATAWIDTH),
	.PHAWIDTH(PHAWIDTH),
	.STAGE(ii)
	)
	UcordicAmpPhaUnit(
	.clk(clk),
	.rst(rst),
	.xin(datasReal[ii]),
	.yin(datasImag[ii]),
	.phaOut(phas[ii + 1]),
	.phaIn(phas[ii]),
	.xout(datasReal[ii + 1]),
	.yout(datasImag[ii + 1]),
	.atanCoef(atanTable[ii])
	);
end
endgenerate

/* always @(posedge clk) begin
	if(rst) begin
		amp1 <= {{2*AMPWIDTH -1}{1'b0}};
	end
	else begin
		amp1 <= datasReal[LOOP] * K;
	end
end
assign amp = {amp1[2*AMPWIDTH - 1], amp1[AMPWIDTH - 2:0]}; */
assign amp = datasReal[LOOP];
assign pha = phas[LOOP];

endmodule

module cordicAmpPhaUnit(clk, rst, xin, yin, phaOut, phaIn, xout, yout, atanCoef);
/****************** PARAMETER ******************/
parameter DATAWIDTH = 12;
parameter PHAWIDTH = 12;
parameter STAGE = 0;
/****************** INPUT OUTPUT ******************/
input    clk;
input    rst;
input    signed    [DATAWIDTH - 1:0]    xin;
input    signed    [DATAWIDTH - 1:0]    yin;
input    signed    [PHAWIDTH - 1:0]    phaIn;
input    signed    [PHAWIDTH - 1:0]    atanCoef;

output    reg    signed    [DATAWIDTH - 1:0]    xout;
output    reg    signed    [DATAWIDTH - 1:0]    yout;
output    reg    signed    [PHAWIDTH - 1:0]    phaOut;
/****************** CORDIC UNIT ******************/
always @(posedge clk or negedge rst) begin
	if(rst) begin
		xout <= {DATAWIDTH{1'b0}};
		yout <= {DATAWIDTH{1'b0}};
		phaOut <= {PHAWIDTH{1'b0}};
	end
	else begin
		if(yin[DATAWIDTH - 1]) begin
			xout <= xin - (yin >>> STAGE);
			yout <= yin + (xin >>> STAGE);
			phaOut <= phaIn - atanCoef;
		end
		else begin
			xout <= xin + (yin >>> STAGE);
			yout <= yin - (xin >>> STAGE);
			phaOut <= phaIn + atanCoef;		
		end
	end
end

endmodule

仿真结果:

 

对于幅度,考虑到只是比例不同,K = 0.607253没有计算,例如:abs(2000 + 2000i) ≈ 4660 * K

对于相位,26位有符号数,8390402/2^25 = 0.2501 ≈ 0.25 ,即1/4个pi ,度量为pi。

对于其他象限,提前加一个转化过程即可。

标签:26,clk,CORDIC,相位,signed,ii,002,rst,pha
来源: https://www.cnblogs.com/mia1004/p/11628409.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有