(毕竟新手,请各位不吝赐教)
因为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
仿真结果如图所示:
以上:输入两个数都为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
仿真结果: