FPGA系列--CORDIC IP核-Sin and Cos模式求e的复指数次方
本文介绍了在FPGA中使用CORDIC IP核计算e的复指数次方的方法。主要内容包括:1)通过欧拉公式将复指数运算转换为正余弦问题;2)CORDIC IP核的配置参数详解,包括工作模式选择、结构布局、流水线模式、数据格式;3)通过MATLAB和FPGA联合仿真验证,结果与MATLAB计算结果一致,验证了IP核的正确性。该方案为通信系统中的复指数运算提供了有效的硬件实现方法。
FPGA系列文章-IP核的使用
目录
1.2.1 Configuration Options(配置参数)
1.2.2 Input/Output Options(输入/输出选项)
1.2.3 Advanced Configuration Parameters(高级配置参数)
1.1 背景
在通信系统中,难免需要进行下式运算:
其中根据欧拉公式可得:
即可将求e的复指数次方问题准换为求正弦与余弦问题。
1.2 CORDIC IP核求Sin and Cos
在MATLAB中,求解e的复指数次方公式如下所示:
在FPGA中,则需要使用CORDIC IP核的Sin and Cos模式求e的复指数次方。假设IP核的输入为,则输出为
即
IP核配置如下图所示:

1.2.1 Configuration Options(配置参数)
Functional Selection(模式选择):选择IP核工作模式,此处选择Sin and Cos模式。
Architectural Configuration(结构布局):此处可以选择Word Serial(串行模式,消耗资源少但是延时更长)、Parallel(并行模式,消耗资源多但耗时短),默认选择Parallel。
Pipelining Mode(流水线模式):此处可以选择No Pipelining(不使用流水线,纯组合逻辑)、Optimal(最优值)、Maximum(最大值),默认选择Maximum。
Data Format(数据类型):固定为Signed Fraction(有符号小数)。
Phase Format(相位格式):此处可选择Radians(弧度模式,输出范围为 )、Scaled Radians(归一化后的结果,输出范围为-1~1 ,相当于除
)。
1.2.2 Input/Output Options(输入/输出选项)
输入输出位宽,根据需求设置位宽。
Round Mode(取整模式):此处可设置为Truncate(截断模式)、Round Pos Inf(向正无穷舍入)、Round Pos Neg Inf(四舍五入模式)、Nearest Even(向最接近的偶数舍入)。
Truncate:截断模式,直接保留高有效位,舍弃低位。
Round Pos Inf:向正无穷舍入,即正数时向上舍入(1.1->2、1.9->2),负数时直接截断(-1.1->-1)。
Round Pos Neg Inf:四舍五入模式。
Nearest Even:向最接近的偶数舍入,若低位为奇数则向上舍为偶数,偶数则保持不变,(小数部分向最接近的偶数舍入,如2.5->2、3.5->4)。
1.2.3 Advanced Configuration Parameters(高级配置参数)
Iterations(迭代次数):控制IP核内部迭代次数,迭代越高计算精度越高同时IP核所占用的资源及计算延迟都会增高,默认值为0:由IP和自动确定。
Precision(内部精度):控制内部数据路径的的位宽,以匹配外部输出要求,默认值为0:由IP核自动确定。
Coarse Rotation(粗旋转):勾选时输出范围为 ,不勾选时输出范围被限制在
,默认勾选。
Compensation Scaling(补偿缩放):IP核在Sin and Cos模式下不起作用。
1.2.4 AXI4配置及实施细节
下图右侧为AXI4选项,保持默认即可。
左侧为实施细节,根据细节可以看到其输出比输入延迟20个时钟周期。
输入数据格式为16Q13(其中最高位表示正负;整数位由于输入数据范围为,所以使用2位就可以进行表示,其余为小数位)。
输出为32位数据:其中,高16位为虚部数据(sin),格式为16Q14;低16位为实部数据(cos),格式为16Q14;输出格式为16Q14(最高位为符号位,整数位由于输出正余弦函数的值的范围为 ,所以1位即可表示,其余为小数位)。

1.3 IP核接口
| 名称 | 位宽 | 方向 | 说明 |
|---|---|---|---|
| aclk | [0:0] | 输入 | 时钟信号 |
| s_axis_phase_tvalid | [0:0] | 输入 | 输入数据有效信号 |
| s_axis_phase_tdata | [31:0] | 输入 | 输入数据(范围-pi~pi,格式16Q13) |
| m_axis_dout_tvalid | [0:0] | 输出 | 输出数据有效信号 |
| m_axis_dout_tdata | [15:0] | 输出 | 输出数据(0-15位为实部数据、16-31位为虚部数据,格式16Q14) |
1.4 仿真
使用MATLAB生成一个相位值,并求其 ,代码如下所示。
%定义公式中z值
phase_num = 2.123456;
%将其进行16Q13量化
phase_num = fixed_point(phase_num,16,13,1,0,1,1);
phase_num_fix = phase_num .* 2^13;
%求e的复指数次方
exp_phase = exp(1j*phase_num);
%将其进行16Q14量化
exp_phase = fixed_point(exp_phase,16,14,1,0,1,1);
exp_phase_fix = exp_phase .* 2^14;
首先定义一个相位值为2.123456,该值处于 之间,其经过16Q13定点量化后的值为17395;其e^x的值为-0.524963378906250+0.851135253906250i,经过16Q14定点量化后的值为-8601+13945i。
将定点化相位值送入IP核进行仿真,FPGA仿真代码如下所示:
//系统计数器
reg [31:0] Cnt_sys;
always @( posedge Main_CLK )begin
if( Reset )
Cnt_sys <= 0;
else if( Cnt_sys <= 32'd199)
Cnt_sys <= Cnt_sys + 1'b1;
else
Cnt_sys <= Cnt_sys;
end
reg phase_valid ;//相位数据使能
reg [15:0] phase_data ;//相位数据
always @( posedge Main_CLK or posedge Reset )begin
if( Reset )begin
phase_valid <= 1'b0 ;
phase_data <= 16'd0;
end
else if(Cnt_sys == 99)begin
phase_valid <= 1'b1 ;
phase_data <= 16'd17395;
end
else begin
phase_valid <= 1'b0 ;
phase_data <= 16'd0;
end
end
//测试Cordic_ip计算Sin and Cos
wire SinandCos_valid ;
wire [31:0] SinandCos_data ;
Cordic_ip U_Cordic_ip (
.aclk ( Main_CLK ),// input wire aclk
.s_axis_phase_tvalid ( phase_valid ),// input wire s_axis_phase_tvalid
.s_axis_phase_tdata ( phase_data ),// input wire [15 : 0] s_axis_phase_tdata
.m_axis_dout_tvalid ( SinandCos_valid ),// output wire m_axis_dout_tvalid
.m_axis_dout_tdata ( SinandCos_data ) // output wire [31 : 0] m_axis_dout_tdata
);
//输出结果拆分为Sin、Cos的值
wire [15:0] Sin_data;
wire [15:0] Cos_data;
assign Sin_data = SinandCos_data[31:16];
assign Cos_data = SinandCos_data[15: 0];
仿真结果如下图所示:

通过仿真结果可以看出,将MATLAB产生的数据输入到IP核后,经过20个时钟周期IP核输出结果,其结果为cos值为-8601、sin值为13944与MATLAB仿真结果相同(相差1是由于计算精度导致,可忽略不计)。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)