问题简述
基于FPGA实现Sobel算法,计算出像素水平和铅直方向的微分dx,dy后,需要计算向量{dx,dy}的模与其夹角,即实现
肯定不能使用乘法器或者除法器呀,那太费资源了。遂使用CORDIC算法,该算法的原理部分不再赘述。
cordic IP核的详细介绍和使用
该内容大部分来自于xilinx cordic IP核官方文档。
基本思路是根据6.0版本的cordic核中各个配置和功能进行记录。
配置选项
配置参数
- Functional Selection(功能选择):旋转,坐标变换,双曲正弦函数(sinh),双曲余弦函数(cosh),反正切(arctan),反正切双曲函数(arctanh),平方根。
在sobel算子中使用到的是arctan和square root。针对这两个功能着重记录。 - Architecture Configuration (配置构架):
Parall(并行):占用更多而逻辑资源,其内部实现的电路规模与迭代次数和输出精度的乘积成正比。但具有单周期的吞吐量,即N位宽度的输出需要N个时钟周期延迟才可以实现,每个时钟周期都会有一个输出。
Word Serial(串行):相比之下使用更少的逻辑资源,其内部实现的电路规模与输出精度成正比,多周期的吞吐量,即N位宽度的输出需要N个时钟周期延迟才可以实现,并且每N个时钟周期才可以输出一个数据。
注:延迟周期除了与架构有关,AXI总线的通信协议影响更大。 - Pipelining Mode(流水线模式)
NONE:无流水线,Latency = 0,可能需要很多的LUTS.
Optimal:CORDIC核心是通过尽可能多的阶段来实现的,而不需要使用任何额外的LUTs。
Maximum:CORDIC核心是在每个shift-add子阶段之后通过管道实现的(不太懂)。 - 数据格式:arctan默认为有符号数,square_root为可选。
- 相位格式
IP核中针对相位格式有两个选项:
Radians(弧度制),范围为(-pi,pi)。
Scaled Radians(归一化的弧度制),范围为(-1,1)。
AXI-4 Stream
Stream 即是去掉了地址项,允许无限制的数据突发传输,由AXI-FULL和AXI-LITE的读写变成了对数据的收发。
输入\输出选项
- 输入\输出位宽
- 近似模式:
a. Truncate(截断)
b. Positive Infinity(向正无穷跑): 对于正数来说就是四舍五入,对于负数来说就是截断。
c. Pos Neg Infinity(分开跑):四舍五入。
d. Nearest Even:跑向最近的偶数。
其他选项
- 迭代次数和精度:不写就会根据你的其他设定,自动设置。
- Coarse Rotation
如果关闭Sin,Cos,Arctin 输出的角度将被局限在一象限
(-Pi/4,+ Pi/4)。粗旋转通过将输入样本旋转到第一象限并将输出样本反向旋转回适当的象限,将CORDIC操作范围扩展到整个圆。
AXI-Stream选项
从此图可以看到ready信号显示在模块端口中,但无法enable(不是我没有选,就是没有)。估计是assign ready= valid。
其中,有两种模式选择:NON BLOCKING和BLOCKING
如下图所示:
non_blocking模式的特点和时序图
针对两个输入,该模式输出的数据就是两个信号的valid和ready同时有效处的值。
blocking模式的特点和时序图
针对两个信号,此模式会将有效信号(valid和ready同时拉高)进行排序,配对,a信号的第一个有效数据配对b信号第一个有效数据。
具体功能
arctan
输入采用Q1格式的有符号定点数(首位为符号位,之后一位整数位,其余为小数位),输出采用Q2格式的有符号定点数(首位为符号位,之后两位整数位,其余为小数位)。在仿真过程中我的Xin与Yin有很多都不满足这个条件但都计算出了正确值。。。
Square Root
平方根操作的data format有两种选择:
- Unsigned Fraction(无法号分数),整数位宽为1位
- Unsigned Integer(无符号整数)
输入位宽确定后输出位宽自动确定。