由於Verilog/Vhdl沒有計算exp指數函數的庫函數,所以在開發過程中可利用cordic IP核做exp函數即e^x值;
但前提要保證輸入范圍在(-pi/4—pi/4)
在cordic核中e^x = sinh + cosh所以在配置cordic時點選sinh and cosh即可 如下圖:
input width配置為16位,表示輸入數據的第16位是符號位,第15,14位是整數位,其他位表示小數位,相當於13位有符號定點小數;
output width配置16位,高16位表示sinh結果 其中第16位符號位,第15位整數位,其它小數位,相當於13位有符號定點小數;
低16位表示cosh結果 其中第16位符號位,第15位整數位,其它小數位,相當於13位有符號定點小數;
其它選項都按上圖顯示配置;
編寫testbench測試文件:
Testbench:
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
// Create Date: 2018/11/28 09:08:45
// Design Name:
// Module Name: test_bench_IP_cordic_ex
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
// 利用cordic IP核 做pi/5和-pi/4做exp 定義(可自選)
//需自己將仿真結果高16位提出作為sinh值 數據格式為第16位為符號位 第15位是整數位 后邊其他是小數
//將仿真結果低16位提出作為cosh值 數據格式為第16位為符號位 第15位是整數位 后邊其他是小數
//得到結果exp(x)=sinh+cosh
// Dependencies:
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//////////////////////////////////////////////////////////////////////////////////
module test_bench_IP_cordic_ex(
);
//inputs
reg clk;
reg[15:0] s_axis_phase_tdata;
reg s_axis_phase_tvalid;
//outputs
wire m_axis_dout_tvalid;
wire[31:0] m_axis_dout_tdata;
//others
wire[15:0] sinh;
wire[15:0] cosh;
wire[15:0] exp;
assign sinh = m_axis_dout_tdata[31:16];
assign cosh = m_axis_dout_tdata[15:0];
assign exp = sinh + cosh;
cordic_0 cordic_m0(
.aclk(clk),
//.rst(rst),
.s_axis_phase_tdata(s_axis_phase_tdata),
//.s_axis_phase_tready(s_axis_phase_tready),
.s_axis_phase_tvalid(s_axis_phase_tvalid),//s_axis_phase_tvalid),
.m_axis_dout_tvalid(m_axis_dout_tvalid),
.m_axis_dout_tdata(m_axis_dout_tdata)
);
always #5 clk = ~clk;
initial begin
clk = 0;
s_axis_phase_tvalid = 0;
s_axis_phase_tdata = 0;
#150
s_axis_phase_tvalid = 1;
s_axis_phase_tdata = 16'b0001010000011011;//pi * 1/5
#10
s_axis_phase_tdata = 16'b1110011011011110;//-pi * 1/4
#10
s_axis_phase_tvalid = 0;
#40000 $finish;
end
endmodule
仿真結果如下圖:
圖中標紅區域值分別為:
e(pi/5)=1.87432861328125
e(-pi/4)=0.45587158203125
利用Matlab仿真結果如下圖:
對比可知仿真結果一致;