FPGA篇(一) 基于verilog的定点开方运算(1)-逐次逼近算法
目录
1.逐次逼近算法描述
2.Verilog实现
3.Testbench编写
1.逐次逼近算法描述
逐次逼近算法流程如图 1所示,首先数据输入data[7:0],接着设置实验值D_z[3:0]和确定值D_q[3:0],然后按照从高往低的顺序,依次将每一位置1(如D_z[3]置1),再将实验值平方后与输入数据比较,若实验值的平方大于输入值(D_z^2 > data),则此位为0(D_q[3]为0),反之((D_z^2 ≤ data)),此位为1(D_q[3]为1);以此迭代到最后一位。
可见,如果是n bit的数据,那么需要n/2次迭代,每次计算如果一个周期,则需要n/2个周期。
图 1逐次逼近算法框图
2.Verilog实现
//
//
// 逐次逼近算法
//
module sqrt_1#( parameter d_width = 8,parameter q_width = d_width/2 - 1,parameter r_width = q_width + 1 )(input wire clk,input wire rst,input wire i_vaild,input wire [d_width:0] data_i, //输入output reg o_vaild,output reg [q_width:0] data_o, //输出output reg [r_width:0] data_r //余数);
//--------------------------------------------------------------------------------reg [d_width:0] D [r_width:1]; //被开方数reg [q_width:0] Q_z [r_width:1]; //临时reg [q_width:0] Q_q [r_width:1]; //确认reg ivalid_t [r_width:1];
//--------------------------------------------------------------------------------always@(posedge clk or posedge rst)beginif(rst)beginD[r_width] <= 0;Q_z[r_width] <= 0;Q_q[r_width] <= 0;ivalid_t[r_width] <= 0;endelse if(i_vaild)beginD[r_width] <= data_i; //被开方数据Q_z[r_width] <= {1'b1,{q_width{1'b0}}}; //实验值设置Q_q[r_width] <= 0; //实际计算结果ivalid_t[r_width] <= 1;endelsebeginD[r_width] <= 0;Q_z[r_width] <= 0;Q_q[r_width] <= 0;ivalid_t[r_width] <= 0;endend
//-------------------------------------------------------------------------------
// 迭代计算过程
//-------------------------------------------------------------------------------generategenvar i;for(i=r_width-1;i>=1;i=i-1)begin:Ualways@(posedge clk or posedge rst)beginif(rst)beginD[i] <= 0;Q_z[i] <= 0;Q_q[i] <= 0;ivalid_t[i] <= 0;endelse if(ivalid_t[i+1])beginif(Q_z[i+1]*Q_z[i+1] > D[i+1])beginQ_z[i] <= {Q_q[i+1][q_width:i],1'b1,{{i-1}{1'b0}}};Q_q[i] <= Q_q[i+1];endelsebeginQ_z[i] <= {Q_z[i+1][q_width:i],1'b1,{{i-1}{1'b0}}};Q_q[i] <= Q_z[i+1];endD[i] <= D[i+1];ivalid_t[i] <= 1;endelsebeginivalid_t[i] <= 0;D[i] <= 0;Q_q[i] <= 0;Q_z[i] <= 0;endendendendgenerate
//--------------------------------------------------------------------------------
// 计算余数与最终平方根
//--------------------------------------------------------------------------------always@(posedge clk or posedge rst) beginif(rst)begindata_o <= 0;data_r <= 0;o_vaild <= 0;endelse if(ivalid_t[1])beginif(Q_z[1]*Q_z[1] > D[1])begindata_o <= Q_q[1];data_r <= D[1] - Q_q[1]*Q_q[1];o_vaild <= 1;endelsebegindata_o <= {Q_q[1][q_width:1],Q_z[1][0]};data_r <= D[1] - {Q_q[1][q_width:1],Q_z[1][0]}*{Q_q[1][q_width:1],Q_z[1][0]};o_vaild <= 1;endendelsebegindata_o <= 0;data_r <= 0;o_vaild <= 0;endend
//--------------------------------------------------------------------------------
3.Testbench编写
//--------------------------------------------------------------------------------`define d_w 8`define q_w `d_w / 2`define r_w `q_w + 1
//--------------------------------------------------------------------------------
module tb_sqrt;
//--------------------------------------------------------------------------------// Inputsreg clk;reg rst;reg i_vaild;reg [`d_w-1:0] data_i;// Outputswire o_vaild;wire [`q_w-1:0] data_o;wire [`r_w-1:0] data_r;//--------------------------------------------------------------------------------// Instantiate the Unit Under Test (UUT)sqrt_1 #(.d_width ( `d_w-1 ),.q_width ( `q_w-1 ),.r_width ( `r_w-1 ) )uut (.clk ( clk ), .rst ( rst ), .i_vaild ( i_vaild ), .data_i ( data_i ), .o_vaild ( o_vaild ), .data_o ( data_o ), .data_r ( data_r ));
//--------------------------------------------------------------------------------initial begin// Initialize Inputsclk = 0;rst = 1;// Wait 100 ns for global reset to finish#100;rst = 0; // Add stimulus hereendalways #5 clk = ~ clk ;reg [`d_w:0] cnt ;reg [31:0] a ;
//--------------------------------------------------------------------------------always@(posedge clk or posedge rst)beginif(rst)begini_vaild <= 0;data_i <= 0;cnt <= 0;endelse if(cnt < 10)begini_vaild <= 1;data_i <= {$random} % 255;cnt <= cnt + 1;endelsebegini_vaild <= 0;data_i <= 0;cnt <= cnt;endend
//--------------------------------------------------------------------------------
endmodule
用语句 data_i <= {$random} % 255; 产生一个0~255的随机数进行测试。
仿真结果如图 2所示,计算周期为4个时钟周期,输入数据data_i,开方结果data_o,余数data_r。
图 2 仿真结果
FPGA篇(一) 基于verilog的定点开方运算(1)-逐次逼近算法相关推荐
- 基于Verilog搭建一个卷积运算单元的简单实现
目录 前言 1. 图片的缓存与读取 2. 滑窗的构建 3. 权值的读取 3.1 行列计数器的构建 3.2 权重数据的取存 4. 卷积运算 4.1 乘法运算 4.2 加法运算 4.3 卷积输出有效位 前 ...
- 基于Verilog的DDS波形发生器的分析与实现(三角波、正弦波)
原文作者:FPGA设计论坛 基于Verilog的DDS波形发生器的分析与实现(三角波.正弦波) 最近学习了一下关于DDS的相关知识,本篇概要记录一下自己的理解与实现. DDS信号发生器采用直接数字频率 ...
- FPGA学习——基于Verilog实现的多功能时钟
FPGA基于Verilog实现的多功能时钟 时钟实现的功能: 1.数码管显示时间 2.有计时功能 3.可实现定点报时 多功能时钟共两种工作状态: 1.正常的时钟显示时间 2.计时状态 由于部分原因,本 ...
- 基于FPGA,解扰码器Verilog的实现,以及扰码器与解扰码器的联合仿真。附上仿真结果。
文章目录 前言 一.扰码器 二.解扰码器 三.Descrambler的Verilog实现 1.descrambler.v 2.descrambler_tb.v 四.扰码器与解扰码器的联合仿真 1.sc ...
- FPGA篇(三)基于FPGA的几种排序算法
目录 1 冒泡法和比较排序法 1.1 算法原理 1.2 仿真结果 1.3 算法优缺点 2 并行全比较排序法 2.1 算法原理 ...
- FPGA学习之路—应用程序—基于Verilog设计单总线8位ALU
FPGA学习之路--基于Verilog设计单总线8位ALU 定义 ALU(arithmetic and logic unit) 算术逻辑单元,简称ALU,是计算机的数学运算核心,也就是负责运算的组件, ...
- 国产智多晶FPGA基于Verilog的设计开发流程
大家好,我是小梅哥,这里给大家介绍国产FPGA厂家"西安智多晶"微电子的FPGA基于Verilog进行逻辑设计的开发流程,步骤详细,可作为大家的评估参考.本博客将陆续发表更多国产F ...
- 【Zedboard】FPGA边缘提取 图像处理 基于ZYNQ完成 灰度图像 在VGA显示与 边缘提取 二值化 Verilog代码实现
[Zedboard]FPGA边缘提取 图像处理 基于ZYNQ完成 灰度图像 在VGA显示与 边缘提取 二值化 Verilog代码实现 在项目开始到目前为止已经完成了在Zedboard的PL部分即FPG ...
- 基于FPGA开发板使用Verilog设计PWM呼吸灯实验
基于FPGA开发板使用Verilog设计PWM呼吸灯实验 1,实验原理 2,实验模块设计 2.1 RTL设计,呼吸灯模块设计 2.2,测试数据,下载到FPGA开发板板级的数据 2.3,两个模块综合的n ...
最新文章
- 新日光Q3收入亏损8400万美元缩水33.85%
- mysql带BETTEEN ADN 关键字的查询
- 程序语言(编程语言)汇总大全
- JavaWeb黑马旅游网-学习笔记09【旅游线路收藏】
- 知识管理中的矛盾分析
- 利用 dbghelp.dll 生成 dump 文件
- 存储过程/函数权限的问题解决(The user specified as a definer ('root'@'%') does not exist)...
- C++ 位图及位图的实现
- 【leetcode】Permutations
- LeetCode之Find Eventual Safe States(Kotlin)
- ThinkPHP 3.2.3方法函数总结
- fscapture下载收费吗?_听歌要收费,下载又要付费?国内的音乐app还想干什么?...
- leetcode 859. Buddy Strings
- 【FFmpeg】srs引入ffmpeg转码
- mfc入门基础(三)创建对话框
- 本地软件仓库配置及NFS安装
- C语言循环逻辑之if语句
- 关于m3u8中的IV参数
- R:怎么在混合模型中分析随机效应的显著性
- java用户界面课程设计_java课程设计《消息公布体系》用户界面设计模板.doc