FPGA利用IP核计算反正切的方法

(毕竟新手,请各位不吝赐教)

因为FPGA计算反正切可以用IP核进行,但是IP核需要输入二进制小数,一般我们得到的数都是十进制数,所以要先进行一些处理:


1:把十进制数变成浮点数


2:进行浮点数除法,除以相对应的位数最大值以便得到小数,比如说8位的就除以255。


3:进行反正切运算


4:如果需要转换为角度需要把浮点数转换为定点数之后乘以255.


以下为程序:

module float_3(
	CLK,
	data_in_1,
	data_in_2,
	data_out_1,
	data_out_2,
	data_dividend_1,
	data_dividend_2,
	data_divisor,
	cnt,
	CE_1,
	CE_2,
	nRESET,
	phase_out
    );
	 
	input CLK,nRESET;
	input [31:0]data_in_1,data_in_2;
	output [31:0]data_out_1,data_out_2,data_dividend_1,data_dividend_2,data_divisor,phase_out;
	output reg [7:0]cnt;
	output reg CE_1,CE_2;
	
	always@(posedge CLK or negedge nRESET)
	begin
		if(!nRESET)
		begin
			cnt <= 8'd0;
			CE_1 <= 8'd0;
			CE_2 <= 8'd0;
		end
		
		else
		begin
			if(cnt == 8'd15)
			begin
				CE_1 <= 8'd1;
				cnt <= cnt + 8'd1;                 // 计算浮点数时的延时
			end
			
			else if(cnt == 8'd50)
			begin
				CE_2 <= 8'd1;
				cnt <= cnt + 8'd1;                 // 计算反正切时的延时
			end
			
			else
				cnt <= cnt + 8'd1;
		end
	end
	
	
	jkjlk A1
	(
	.clk(CLK),
	.a(data_in_1),
	.result(data_dividend_1)    //第一个数转化为浮点数的IP核
	);
  
	jkjlk A2
	(
	.clk(CLK),
	.a(32'd255),
	.result(data_divisor)	    //255转换为浮点数的IP核
	);
	
	jkjlk A3
	(
	.clk(CLK),
	.a(data_in_2),
	.result(data_dividend_2)	// 第二个数转换为浮点数的IP核
	);
	
	divided A4
	(
        .clk(CLK), 
        .ce(CE_1), 
        .a(data_dividend_1), 
        .b(data_divisor), 
        .result(data_out_1)		// 第一个数转换为小数0-1之间
	);
	
	divided A5
	(
       .clk(CLK), 
       .ce(CE_1), 
       .a(data_dividend_2), 
       .b(data_divisor), 
       .result(data_out_2)		// 第二个数转换为0-1之间的小数 
	);
	
	angle A6
	(
	.clk(CLK), 
	.ce(CE_2),
	.x_in(data_out_1), 
	.y_in(data_out_2), 
	.phase_out(phase_out)       //反正切运算
	);
	
	
endmodule


仿真结果如图所示:

FPGA利用IP核计算反正切的方法_第1张图片


以上:输入两个数都为48. 输出的结果为45°


好吧... 还是有问题

修补1:2017年5月17日

因为反正切核的输入要求是定点数,所以上述使用的整形就可以,小数就有些许问题,所以要把结果转化成定点数再进行反正切运算。

代码如下:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date:    10:39:15 05/15/2017 
// Design Name: 
// Module Name:    float_1 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//
module float_3(
	CLK,
	data_in_1,
	data_in_2,
	data_out_1,
	data_out_2,
	data_dividend_1,
	data_dividend_2,
	angle_in_1,
	angle_in_2,
	data_divisor,
	cnt,
	CE_1,
	CE_2,
	CE_3,
	nRESET,
	phase_out
    );
	 
	input CLK,nRESET;
	input [31:0]data_in_1,data_in_2;
	output [31:0]data_out_1,data_out_2,data_dividend_1,data_dividend_2,data_divisor,phase_out,angle_in_1,angle_in_2;
	output reg [7:0]cnt;
	output reg CE_1,CE_2,CE_3;
	
	always@(posedge CLK or negedge nRESET)
	begin
		if(!nRESET)
		begin
			cnt <= 8'd0;
			CE_1 <= 8'd0;
			CE_2 <= 8'd0;
			CE_3 <= 8'd0;
		end
		
		else
		begin
			if(cnt == 8'd15)
			begin
				CE_1 <= 8'd1;
				cnt <= cnt + 8'd1;
			end
			
			else if(cnt == 8'd55)
			begin
				CE_2 <= 8'd1;
				cnt <= cnt + 8'd1;
			end
			
			else if(cnt == 8'd45)
			begin
				CE_3 <= 8'd1;
				cnt <= cnt + 8'd1;	
			end
			
			else
				cnt <= cnt + 8'd1;
		end
	end
	
	
	jkjlk A1
	(
	.clk(CLK),
	.a(data_in_1),
	.result(data_dividend_1)
	);
  
	jkjlk A2
	(
	.clk(CLK),
	.a(32'd255),
	.result(data_divisor)	
	);
	
	jkjlk A3
	(
	.clk(CLK),
	.a(data_in_2),
	.result(data_dividend_2)	
	);
	
	divided A4
	(
       .clk(CLK), 
       .ce(CE_1), 
       .a(data_dividend_1), 
       .b(data_divisor), 
       .result(data_out_1)		
	);
	
	divided A5
	(
       .clk(CLK), 
       .ce(CE_1), 
       .a(data_dividend_2), 
       .b(data_divisor), 
       .result(data_out_2)		
	);
	
	fixed B1
	(
	.clk(CLK),
	.a(data_out_1),
	.result(angle_in_1),
	.ce(CE_3)
	);
	
	fixed B2
	(
	.clk(CLK),
	.a(data_out_2),
	.result(angle_in_2),
	.ce(CE_3)
	);
	
	angle A6
	(
	.clk(CLK), 
	.ce(CE_2),
	.x_in(angle_in_1), 
	.y_in(angle_in_2), 
	.phase_out(phase_out)
	);
	
	
endmodule


仿真结果:

FPGA利用IP核计算反正切的方法_第2张图片

你可能感兴趣的:(FPGA,XILINX,testbench)