verilog求倒数-ROM实现方法
采用线性逼近法结合32段线性查找表的方式来实现1/z的计算。
首先将1/32-1/64的定点化数据存放到ROM中,ROM中存放的是扩大了2^20 次方的数字四舍五入后的整数部分。n值越大,精度越大,误差越小。这里取n=20;
ROM中存储的数据是1/(32+i)*2^20的四舍五入的整数部分。
32-64间的数据可以通过查表来实现,其他的数据则采用的是线性逼近的方法。
线性逼近的步骤为:
1.确定最高非零比特位的位置
2.对z进行左移或者右移,得到zp
3.zp查找ROM,得到1/zp,以及1/(zp+1),
4.求的1/zp-1/(zp+1),为误差A
5.N=z-zp*2^(m-5)
6.B=A/2^(m-5)*N
7.将扩大的部分缩小回去,或者缩小了的放大回去,那么1/z=(1/zp-B)*(1/2^(m-5))
代码插入:
module top_inv(
input clk,syn_rst,
input [:]dataa,
input [:]datab,
//input [20:0]ampout,
output reg [:]inv
// output reg done
);
reg [:] address1;
reg [: ]address2;
wire [:] m;
// wire done;
reg [:]invr;
reg [:] ampout_r;
reg [:] ampout_r1;
wire [:] ampout;
reg [:] ampoutr1,ampoutr2,ampoutr3,ampoutr4;
wire [:] inv_r1;
wire [:] inv_r2;
reg [:] diff_r;
reg [:] diffr;
reg [:] diff;
reg [:] N;
reg [:] N1;
reg en; always @(posedge clk or negedge syn_rst)
begin
if(~syn_rst)
begin
ampoutr1<='d0;
ampoutr2<='d0;
ampoutr3<='d0;
ampoutr4<='d0;
end
else
ampoutr1<=ampout;
ampoutr2<=ampoutr1;
ampoutr3<=ampoutr2;
ampoutr4<=ampoutr3;
end
reg [:] inv_r1t1,inv_r1t2,inv_r1t3;
always@(posedge clk or negedge syn_rst)
begin
if(~syn_rst)
begin
inv_r1t1<=;
inv_r1t2<=;
inv_r1t3<=;
end
else
begin
inv_r1t1<=inv_r1;
inv_r1t2<=inv_r1t1;
inv_r1t3<=inv_r1t2;
end
end
reg [:] mt1,mt2,mt3,mt4,mt5;
always@(posedge clk or negedge syn_rst)
begin
if(~syn_rst)
begin
mt1<=;
mt2<=;
mt3<=;
mt4<=;
mt5<=;
end
else
begin
mt1<=m;
mt2<=mt1;
mt3<=mt2;
mt4<=mt3;
mt5<=mt4;
end
end
reg sel;
reg selr1,selr2;
always @(posedge clk or negedge syn_rst)
begin
if(~syn_rst)
begin
diff<=;
diffr <= ;
ampout_r<='b0;
ampout_r1<=;
address1<='b0;
address2<='b0;
en<=;
sel<=;
end
else
begin
// if(done)
//begin
if((ampout>=)&&(ampout<=))
begin
ampout_r<=;
ampout_r1<=;
address1<=ampoutr3-;
address2<= ;
diff <= ;
diffr <= ;
N <= ;
N1<= ;
en<=;//不需要计算m的值
sel<=;
selr1<=;
selr2<=;
end
else
begin
en<=;//需要计算m的值
if(m>)
begin
// ampoutrr<=ampout;
ampout_r<=ampoutr1>>(m-);
ampout_r1<=ampout_r;//zp
address1<=ampout_r-;///inv_r1
address2<=ampout_r-;///inv_r2
diff <= inv_r1-inv_r2;
diffr <=diff;
N1<=ampout_r1<<(mt2-);
N<=ampoutr4-N1;
selr1<=;
selr2 <= selr1;
sel <= selr2;
end
if(m<)
begin
//ampoutrr<=ampout;
ampout_r<=ampoutr1<<(-m);// mt4 mt3 mt2
ampout_r1 <= ampout_r;// N N1 ampout_r1
address1<=ampout_r-;///mt4 inv_r1
address2<=ampout_r-;//inv_r1t3 inv_r2 mt1
diff <= inv_r1-inv_r2;//diff_r<<diffr<<diff<<address<<ampout_r<< m <<ampout
diffr <=diff; // ampoutr3 ampoutr2 ampoutr1
N1<=ampout_r1>>(-mt2);
N<=ampoutr4-N1;
selr1<=;
selr2 <= selr1;
sel <= selr2;
end
end
end
// end
end
// assign diff=sel?(inv_r1-inv_r2):'b0;
//assign N=sel?(ampout-N1):0;
//assign diff_r = en?(diff*N>>(m-5)):0;
//assign diff_r = (m>5)?(diff*N>>(m-5)):(diff*N<<(5-m));
// assign inv = sel?(inv_r1-diff_r)>>(m-5):inv_r1; always@(posedge clk or negedge syn_rst)
begin
if(~syn_rst)
begin
invr<=;
// done<=0;
diff_r<=;
end
else
begin
if(sel) begin if(m>)begin
diff_r <= diffr*N>>(mt4-);
invr<=(inv_r1t3-diff_r)>>(mt5-);
// done<=1;
end
else begin
diff_r <= diffr*N<<(-mt4);
invr<=(inv_r1t3-diff_r)<<(-mt5);
// done<=1;
end
end
else
begin
diff_r<=;
invr<=inv_r1t3;
end
end
end
always@(posedge clk or negedge syn_rst)
begin
if(~syn_rst)
begin
inv<=;
end
else
begin
if(invr)
inv<= invr;
else
inv<=inv;
end
end
//ROM 核的例化 rom u_rom(.clk(clk),
.address1(address1),
.address2(address2),
.inv_r1(inv_r1),
.inv_r2(inv_r2)//,
//.c(c)
);
//例化寻找最高非零位
not_0 u_not_0 (
// port map - connection between master ports and signals/registers
.ampout(ampout),
.clk(clk),
.m(m),
.en(en),
.syn_rst(syn_rst)
);
complex_abs u_comlex_abs(
.clk(clk),
.syn_rst(~syn_rst),
.dataa(dataa),
.datab(datab),
.ampout(ampout)
);
endmodule
那么最终的仿真结果:如果直接查询的话,结果输出延时一个时钟周期,如果线性逼近的方法得到,延时3-5个时钟周期,这里周期设定为20ns;

占用资源报告:

增加一个求平方根的模块以后的仿真结果(数据输入后,一共需要约10个时钟周期才可以计算出一个平方更求导数值)。有一个小疑问就是怎么添加一个标志信号,让我们知道哪里输出的inv 信号是有效的

verilog求倒数-ROM实现方法的更多相关文章
- 25.按要求编写一个Java应用程序: (1)编写一个矩形类Rect,包含: 两个属性:矩形的宽width;矩形的高height。 两个构造方法: 1.一个带有两个参数的构造方法,用于将width和height属性初化; 2.一个不带参数的构造方法,将矩形初始化为宽和高都为10。 两个方法: 求矩形面积的方法area() 求矩形周长的方法perimeter() (2)通过继承Rect类编写一个具有
package zhongqiuzuoye; //自己写的方法 public class Rect { public double width; public double height; Rect( ...
- C++ 求阶乘 四种方法
来总结下求阶乘的各种方法哈. 写在最前:①各个代码仅仅是提供了求阶乘的思路,以便在实际须要时再来编码,代码并不健壮!②各个程序都在1到10内測试正确. 代码一: #include<iostrea ...
- 表达式求值(二叉树方法/C++语言描述)(二)
表达式二叉树节点的数据可能是运算数或运算符,可以使用一个联合体进行存储:同时还需要一个变量来指示存储的是运算数还是运算符,可以采用和栈方法求值中一样的枚举类型TokenType: typedef en ...
- POJ 3450 Corporate Identity (KMP,求公共子串,方法很妙)
http://blog.sina.com.cn/s/blog_74e20d8901010pwp.html我采用的是方法三. 注意:当长度相同时,取字典序最小的. #include <iostre ...
- 以Python列表特性为切入点的求质数列表的方法
一般,构造一个含有2-x之间所有质数的列表,我们采用最简单的遍历判断质数的方法: # 方法一 1 prime = [] def is_prime(n): if n <= 1: return Fa ...
- 表达式求值(二叉树方法/C++语言描述)(三)
二叉树方法求值对运算数处理的方法与栈方法求值不太相同,除了将字符串中的运算数转换为浮点类型外,还需要生成新的节点: void Calculator::dealWithNumber(char *& ...
- 表达式求值(二叉树方法/C++语言描述)(一)
使用二叉树对算数表达式(以下简称为表达式)进行求值,实质上是将表达式转换为二叉树,对其进行后序遍历,得到后缀表达式的同时可以求得表达式的值.转换和求值的过程也需要借助数据结构栈的帮助. 二叉树数据结构 ...
- java求最大值以及定义方法调用
class ArrayDome { public static void main(String[] args) { int[] arr = {-12,-51,-12,-11}; int max = ...
- Haybale Stacking(差分数组 + 求中位数的一些方法 + nth_element)
题意: 给定N个初始值为0的数, 然后给定K个区间修改(区间[l,r] 每个元素加一), 求修改后序列的中位数. 分析: K个离线的区间修改可以使用差分数组(http://www.cnblogs.co ...
随机推荐
- [CISCN2019 华北赛区 Day1 Web1]Dropbox-phar文件能够上传到服务器端实现任意文件读取
0x00知识点 phar是什么: 我们先来了解一下流包装 大多数PHP文件操作允许使用各种URL协议去访问文件路径:如data://,zlib://或php://.例如常见的 include('php ...
- D11 列表 list 元祖 字典dict
取值 name = "alexdfg" print(name[3:5]) 取出 ex name = "alexdfg" print(name[3]) 取出e 列 ...
- 当初对"软件工程"这个专业的期待和想象是什么?
很多期待,很多幻想 印象很深刻的初中语文老师让我们背诵的一首诗<错误>: <错误> 作 者:郑愁予 我打江南走过 那等在季节里的容颜如莲花的开落 东风不来,三月的柳絮不飞 你底 ...
- JDK的安装与环境变量配置
1.下载JDK后安装,此处安装的是JDK8 2.安装后的路径如下图所示,JDK与JRE在同一个文件夹中 3.安装完JDK后配置环境变量 计算机→属性→高级系统设置→高级→环境变量 4.系统变量→新建 ...
- 深入分析Java反射(六)-反射调用异常处理
前提 Java反射的API在JavaSE1.7的时候已经基本完善,但是本文编写的时候使用的是Oracle JDK11,因为JDK11对于sun包下的源码也上传了,可以直接通过IDE查看对应的源码和进行 ...
- 基于SpringBoot框架企业级应用系统开发全面实战
Eclipse 安装spring-tool-suite教程,并创建一个新的springboot项目 使用SpringBoot构建项目,加载SSM整合的applicationContext.xml的注解 ...
- UML-类图-箭头
概览 1.泛化 一般理解为 继承.实线+空心箭头 2.依赖 成员变量.局部变量.参数.虚线+箭头 public class Sale { public void updatePriceFor(Prod ...
- 小白学习之pytorch框架(5)-多层感知机(MLP)-(tensor、variable、计算图、ReLU()、sigmoid()、tanh())
先记录一下一开始学习torch时未曾记录(也未好好弄懂哈)导致又忘记了的tensor.variable.计算图 计算图 计算图直白的来说,就是数学公式(也叫模型)用图表示,这个图即计算图.借用 htt ...
- Django内置标签
在Django中也提供了大量Django自带的内置标签来供我们使用.标签的写法与过滤器的写法不同,标签是具有开始和结束的,例如:{% if %}为开始标签,{% endif %}为结束标签. 可以查 ...
- python获取当前时间戳
import time # 获取当前时间戳print(int(time.time()))