一、前言
在FPGA上进行开方运算,除了可以自己写开方算法,如上一篇文章:verilog 整数开方算法实现(逐次逼近法)。还有一种更加简单的方式就是直接调用IP核,下面就使用Xilinx官方提供的cordic IP核来实现开方运算。
二、IP核配置
三、程序设计
module square(
input clk,
input rst_n,
input data_in_valid,
input [15:0] data_in,
output data_out_valid,
output [15:0] data_out
);
root2 u_root (
.aclk(clk),
.aresetn(rst_n),
.s_axis_cartesian_tvalid(data_in_valid),
.s_axis_cartesian_tdata(data_in),
.m_axis_dout_tvalid(data_out_valid),
.m_axis_dout_tdata(data_out)
);
endmodule
四、设计仿真
`timescale 1ns / 1ps
module tb_square;
// square Parameters
parameter PERIOD = 10;
// square Inputs
reg clk = 0 ;
reg rst_n = 0 ;
reg data_in_valid = 0 ;
reg [15:0] data_in = 0 ;
// square Outputs
wire data_out_valid ;
wire [15:0] data_out ;
initial
begin
forever #(PERIOD/2) clk=~clk;
end
initial
begin
#12 rst_n = 1;
end
square u_square (
.clk ( clk ),
.rst_n ( rst_n ),
.data_in_valid ( data_in_valid ),
.data_in ( data_in [15:0] ),
.data_out_valid ( data_out_valid ),
.data_out ( data_out [15:0] )
);
reg [4:0] cnt ;
//----------------------------------------------------------------------
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
data_in_valid <= 0;
data_in <= 0;
cnt <= 0;
end
else if(cnt < 10)
begin
data_in_valid <= 1;
data_in <= {$random} % {8{1'b1}};
cnt <= cnt + 1;
end
else
begin
data_in_valid <= 0;
data_in <= 0;
cnt <= cnt;
end
end
//----------------------------------------------------------------------
endmodule
五、注意事项
我在仿真的时候发现,该IP核在进行开方计算时,只有采集到rst_n为高无效之后的一个周期采集到的数据才会被计算。如果是和rst_n同周期被采集到的数据,是不会被计算的,至少我测试的是这样的,下面看一下仿真结果!!!