FPGA利用查找表实现sin正弦函数

FPGA利用查找表实现sin正弦函数

最近在看《基于FPGA的数字图像处理原理及应用》这本书,准备利用FPGA实现一些简单的数字图像处理。想把学习过程中遇到的一些问题以及解决方法与大家分享。

1.查找表的定义

在计算机科学中,查找表使用简单的查询操作替换运行时计算的数组或者associative array这样的数据结构。由于从内存中提取数值经常要比复杂的计算速度快很多,因此这样得到的速度提升是很显著的。
  一个经典的例子就是三角表。每次计算所需的正弦值在一些应用中可能会慢的无法忍受,为了避免这种情况,应用程序可以在刚开始的一段时间计算一定数量的角度正弦值,譬如计算每个整数角度的正弦值,在后面的程序需要正弦值的时候,使用查找表从内存中提取临近角度的正弦值而不是使用数学公式进行计算。
  由于查找表的高效率与方便易用性,它在实时性要求比较高的嵌入式系统中得到了广泛的应用。在FPGA中,主要是以下两种情况会用到查找表:一种是逻辑的时序要求非常高,例如,若用Cordic计算或是其他计算方式,则其延时不能满足要求时;另一种是计算的复杂度非常高,需要消耗相当一部分逻辑资源,而查找表只需建立一块的存储器,这可以用FPGA的片内存储器来构建,仅仅消耗一小部分逻辑资源。

2.利用查找表实现正弦函数

下面是一个用查找表来实现正弦函数sinx的示例。

①利用MATLAB生成mif文件

mif文件存放sinx的变量和函数值,在程序运行之前利用mif文件对ROM初始化。下面是生成sin函数查找表的MATLAB程序。
在这里插入图片描述
用MATLAB运行该程序会生成一个mif文件,文件内容如下。
在这里插入图片描述在这里插入图片描述
该mif文件里存放了sinx函数扩大了2^14的901个0-90°步长为0.1°的函数值
用quartus软件打开该mif文件:
在这里插入图片描述
  可以发现mif文件就是一个表格,对应的内容是地址位和十进制值,所以mif文件头一定不能写错。否则会在下一步初始化ROM时发生错误。

②FPGA例化一个ROM来实现查找表的存放

下面是调用quartus的IP核生成ROM的步骤。
  在这里插入图片描述
  在这里插入图片描述
  数据位宽和地址位宽根据前面生成的mif决定,这里选取数据位宽为14,地址位宽为10。
在这里插入图片描述
‘q’ output port一般不必勾选
在这里插入图片描述
在这里点击browse选择mif文件对ROM进行初始化,最后finish即可。

③利用modelsim进行仿真

下面是仿真测试程序

`timescale		1ns/1ns

module	tb_top;

//=====================================================================\
// ********** Define Parameter and Internal Signals *************
//=====================================================================/
parameter                       DW              =   15          ;
parameter                       AW              =   10          ;
parameter                       ADDR_MAX        =   900         ;
parameter                       const_half_pi   =   ADDR_MAX-1  ;
parameter                       const_pi        =   ADDR_MAX*2-1;
parameter                       const_double_pi =   ADDR_MAX*4-1;

reg                             clk                             ;
reg                             rst_n                           ;
reg     [AW+2-1:0]              address_tmp                     ;
reg     [AW-1:0]                address                         ;
wire    [DW-1:0]                q_tmp                           ;
reg     [DW+1-1:0]              q_tmp1                          ;
wire    [DW-1:0]                q                               ;

//======================================================================
// ***************      Main    Code    ****************
//======================================================================
always  #5      clk    =       ~clk;
initial begin
    clk <=  0;
    rst_n   <=  0;
    address_tmp <=  {AW+2{1'b0}};
    #100
    rst_n   <=  1;
end

always  @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        address_tmp <=  {AW+2{1'b0}};
        
    end
    else if(address_tmp == const_double_pi)begin
        address_tmp <=  {AW+2{1'b0}};
    end
    else begin
        address_tmp <=  address_tmp + 1'b1;
    end
end

always  @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        address <=  {AW{1'b0}};
    end
    else if(address_tmp == const_double_pi)begin
        address <=  {AW{1'b0}};
    end
    else if(address_tmp <= const_half_pi)begin
        address <=  address_tmp[AW-1:0];
    end
    else if(address_tmp <=  const_pi)begin
        address <=  const_pi - address_tmp;
    end
    else if(address_tmp <= const_half_pi+const_pi)begin
        address <=  address_tmp - const_pi; 
    end
    else begin
        address <=  const_double_pi - address_tmp;
    end
end

always  @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        q_tmp1  <=  {DW+1{1'b0}};
    end
    else if(address_tmp <= const_pi)begin
        q_tmp1  <=  {1'b0, q_tmp};
    end
    else begin
        q_tmp1  <=  {DW+1{1'b0}} - {1'b0, q_tmp};
    end
end

assign  q   =   q_tmp1[DW-1:0]                                  ;

//例化
sin_lut sin_lut_inst(
	.address(address),
	.clock(clk),
	.q(q_tmp)
);

endmodule

仿真结果如下图所示。
在这里插入图片描述
以上就是通过FPGA利用查找表实现正弦函数的全部内容。

  • 23
    点赞
  • 181
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值