verilog实现开方运算/基于迭代法的平方根计算算法/FPGA实现开根号算法

news/2024/11/29 15:56:43/

        因老师要我们用verilog实现一个算法,涉及到开根号运算,正好学习一下算法,记录一下我的学习记录

主要算法

    

要求:

        输入信号:input signed [15:0] a,      //数据a 

        输入信号:input signed [15:0] b,        //数据b

        输入信号:input [15:0] n,                   //数据个数

        输入信号:valid,                              //数据有效

        

        输出信号:output [15:0] result_int,        //输出结果整数部分

        输出信号:output [15:0] result_dec,        //输出结果小数部分

输入信号a,b为有符号数。

要求算法结果保留到小数点后三位

完整工程文件下载:verilog实现开根号算法完整工程 (点击蓝色字体获取)

1. 引言

  • 背景与动机: 平方根计算在硬件中的重要性,如在图像处理、信号处理、数字滤波器等领域的应用。
  • 设计目标: 实现一个高效的硬件平方根计算器,采用迭代法(如牛顿迭代法)来进行计算。
  • 文章结构: 概述文章结构,明确每一部分的内容,告诉读者你将从算法原理、硬件设计实现、性能分析等方面进行讨论。

2. 开发工具

开发平台:vivado

仿真平台:modelsim

3. 平方根计算的基本原理

3.1 平方根的定义

平方根是指一个数的平方等于给定数。例如,平方根计算问题可以表述为:给定一个非负数 SS,找到一个数 xx,使得 x2=Sx2=S。

3.2 牛顿迭代法

牛顿迭代法是一种常用的逼近函数根的方法,在求解平方根问题时具有广泛应用。牛顿迭代法用于平方根的计算公式如下:

Xn+1=1/2(Xn+S/Xn)

其中:

  • S 是我们要求平方根的数;
  • Xn​ 是第 n 次迭代的近似值;
  • Xn+1​ 是下一个迭代的近似值。

这个公式表示:通过当前的近似值 Xn 和 S,我们可以得到一个新的更接近的平方根值 Xn+1​。

3.3 迭代法的优点

牛顿迭代法具有以下优点:

  • 快速收敛: 牛顿法的收敛速度非常快,通常经过几次迭代即可获得很高的精度;
  • 实现简单: 只需要基本的加法、除法和位移操作,适合在硬件中实现。

4. verilog实现

总体设计框架

主要分为3大模块:

square_calculator:判断输入数据正负,并对其平方,组合逻辑

accumulator:对平方的数据进行求和,并除以n+1

sqrt:对上一个模块的结果,进行开根号运算,且在data_vaild为高的时候才算

4.1 square_calculator模块

        此模块主要是来判断输入数据正负,并对其进行平方,使用的是组合逻辑,所以并不需要时钟输入

代码设计:

module square_calculator (input signed[15:0] I,input signed[15:0] Q,output [31:0] I_squIre,output [31:0] Q_squIre
);reg signed [15:0] abs_I;reg signed [15:0] abs_Q;always @(*) beginif (I < 0)abs_I = -I;elseabs_I = I;endalways @(*) beginif (Q < 0)abs_Q = -Q;elseabs_Q = Q;endassign I_squIre = abs_I * abs_I;assign Q_squIre = abs_Q * abs_Q;
endmodule

4.2 accumulator模块

        此模块主要用来计算根号内容,并输出对应的valid信号,但是为了满足精确到小数点后三位,需要把输入数据乘上1000_000,然后再开完根号之后再除以1000即可得到小数部分和整数部分。

部分代码设计:

module accumulator (input clk,input rst,input valid,input [15:0] n,input [31:0] in,output reg data_valid,output [63:0] sum
);reg [15:0] cnt;reg [63:0] sum_r;reg [63:0] sum_r2;always @(posedge clk or posedge rst) beginif (rst)beginsum_r <= 0;cnt <= 0;endelse if (valid)begincnt <= cnt + 1;sum_r <= sum_r + in * 32'd1000000;                endelse if (cnt == n)beginsum_r <= 0;cnt <= 0;endendalways @(posedge clk or posedge rst) beginif (rst)begindata_valid <= 0;sum_r2 <= 0;endelse if (cnt == n)begindata_valid <= 1;sum_r2 <= sum_r;end else data_valid <= 0;endassign sum = sum_r2;endmodule

4.3 sqrt模块

        此模块主要根据上个模块输出的数据和valid来进行开根号运算,并且分离出来整数部分和小数部分

部分代码设计:

//状态控制
always @(posedge clk or negedge rst_n) beginif (~rst_n) beginsqrt_en <= 1'b0;icnt <= iteration_number - 1;end else if (!sqrt_en) begin  // 等待中if (din_valid_i) beginsqrt_en <= 1'b1;icnt <= iteration_number - 1;din_reg <= {{(DW % 2){1'b0}}, din_i};  // 输入扩展到偶数sqrt_data <= 0;rem_data <= 0;endend else begin  // 迭代中icnt <= icnt - 1;din_reg <= {din_reg[din_width-3:0], 2'b00};sqrt_data <= {sqrt_data[sqrt_width-2:0], sqrt_next};rem_data <= rem_next;if (icnt == 0) sqrt_en <= 1'b0;  // 结束迭代end
end

5. 仿真验证

编写仿真文件tb_sqrt_mean_calculator

`timescale 1ns / 1ps
module tb_sqrt_mean_calculator;reg clk, rst, valid;reg signed[15:0] I, Q, n;wire [15:0] result_int,result_dec;wire [31:0] result;sqrt_mean_calculator uut (.clk(clk),.rst(rst),.valid(valid),.I(I),.Q(Q),.n(n),.result(result),.result_int(result_int),.result_dec(result_dec));initial beginclk = 0;rst = 1;valid = 0;#10 rst = 0;n = 16'd3;  // 数据总数为n+1// 输入数据#10 valid = 1; I = 16'd1; Q = 16'd2;  // 第1组数据#10 I = -16'd11; Q = 16'd12;  // 第2组数据#10 I = 16'd100; Q = -16'd112;  // 第3组数据#10 I = -16'd212; Q = -16'd252;  // 第4组数据#10 valid = 0;#600/*// 输入数据#10 vIlid = 1; I = 16'd4; Q = 16'd2;  // 第1组数据#10 I = 16'd7; Q = 16'd3;  // 第2组数据#10 I = 16'd3; Q = 16'd4;  // 第3组数据#10 I = 16'd2; Q = 16'd1;  // 第4组数据#10 I = 16'd5; Q = -16'd1;  // 第5组数据#10 vIlid = 0;#600*/$stop;endalways #5 clk = ~clk;
endmodule

5.1 理论值

首先先拿计算器运算一下,模拟数据

可以看出来,根据公式算出来为181.150,

5.2 实际值

接下来我们打开modelsim仿真看一下,得出的结果和计算值是否一致

由仿真结果可得,结果和计算值一样

制作不易,记得三连哦,给我动力,持续更新!!!


http://www.ppmy.cn/news/1550934.html

相关文章

mybatis plus如何使用mybatis xml拼接sql

在 MyBatis Plus 中&#xff0c;如果你想使用 MyBatis 的 XML 文件来拼接 SQL&#xff0c;可以结合使用 MyBatis 和 MyBatis Plus 的功能。MyBatis Plus 是一个增强 MyBatis 的工具&#xff0c;它提供了很多便捷的操作&#xff0c;但有时你可能需要使用 XML 文件来定义更复杂的…

【MySQL】数据库的基本认识和使用

为什么要使用数据库呢&#xff1f;我们知道Linux是有文件系统的&#xff0c;为什么不使用文件系统呢&#xff1f; 因为OS只负责把我们交给它的数据存储起来&#xff0c;存到某个文件中&#xff0c;它并不负责管理数据的具体内容&#xff0c;也就是说&#xff0c;我们交给OS什么…

【Ubuntu 24.04】How to Install and Use NVM

参考 下载 curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash激活 Activate NVM: Once the installation script completes, you need to either close and reopen the terminal or run the following command to use nvm immediately. exp…

机器学习之DeepMind推出的DreamerV3

开放域任务强化学习(Open-Ended Task Reinforcement Learning)的目标是使智能体能够在多样化且未见过的任务中表现出色,同时能够实现任务间的迁移学习。这类研究的重点在于开发通用的学习算法,能够在没有明确任务定义的情况下,从环境中学习并推广到新任务。DeepMind的Drea…

Mybatis:Mybatis快速入门

Mybatis的官方文档是真的非常好&#xff01;非常好&#xff01; 点一下我呗&#xff1a;Mybatis官方文档 MyBatis 是一款优秀的持久层框架&#xff0c;它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可…

基于Python的飞机大战复现

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

Linux入门系列--用户与权限

一、前言 1.注意&#xff1a; 【】用户是Linux系统工作中重要的一环&#xff0c;用户管理包括 用户 与 组账号 的管理 【】在Linux系统中&#xff0c;不论是由本机或是远程登录(SSH)系统&#xff0c;每个系统都必须拥有一个账号&#xff0c;并且对于不同的系统资源拥有不同的使…

Android使用UVCCamera打开USBCamera-预览

导入libuvccamera.aar 写一个管理类封装UVCCamera相关API import android.content.Context import android.hardware.usb.UsbDevice import android.os.Handler import android.os.HandlerThread import android.os.Message import android.util.Log import android.view.Surf…