采用线性逼近法结合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实现方法的更多相关文章

  1. 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( ...

  2. C++ 求阶乘 四种方法

    来总结下求阶乘的各种方法哈. 写在最前:①各个代码仅仅是提供了求阶乘的思路,以便在实际须要时再来编码,代码并不健壮!②各个程序都在1到10内測试正确. 代码一: #include<iostrea ...

  3. 表达式求值(二叉树方法/C++语言描述)(二)

    表达式二叉树节点的数据可能是运算数或运算符,可以使用一个联合体进行存储:同时还需要一个变量来指示存储的是运算数还是运算符,可以采用和栈方法求值中一样的枚举类型TokenType: typedef en ...

  4. POJ 3450 Corporate Identity (KMP,求公共子串,方法很妙)

    http://blog.sina.com.cn/s/blog_74e20d8901010pwp.html我采用的是方法三. 注意:当长度相同时,取字典序最小的. #include <iostre ...

  5. 以Python列表特性为切入点的求质数列表的方法

    一般,构造一个含有2-x之间所有质数的列表,我们采用最简单的遍历判断质数的方法: # 方法一 1 prime = [] def is_prime(n): if n <= 1: return Fa ...

  6. 表达式求值(二叉树方法/C++语言描述)(三)

    二叉树方法求值对运算数处理的方法与栈方法求值不太相同,除了将字符串中的运算数转换为浮点类型外,还需要生成新的节点: void Calculator::dealWithNumber(char *& ...

  7. 表达式求值(二叉树方法/C++语言描述)(一)

    使用二叉树对算数表达式(以下简称为表达式)进行求值,实质上是将表达式转换为二叉树,对其进行后序遍历,得到后缀表达式的同时可以求得表达式的值.转换和求值的过程也需要借助数据结构栈的帮助. 二叉树数据结构 ...

  8. java求最大值以及定义方法调用

    class ArrayDome { public static void main(String[] args) { int[] arr = {-12,-51,-12,-11}; int max = ...

  9. Haybale Stacking(差分数组 + 求中位数的一些方法 + nth_element)

    题意: 给定N个初始值为0的数, 然后给定K个区间修改(区间[l,r] 每个元素加一), 求修改后序列的中位数. 分析: K个离线的区间修改可以使用差分数组(http://www.cnblogs.co ...

随机推荐

  1. Pmw大控件(二)

    Pmw大控件英文名Pmw Python megawidgets 官方参考文档:Pmw 1.3 Python megawidgets 一,如何使用Pmw大控件 下面以创建一个计数器(Counter)为例 ...

  2. proto3 不支持内建类型的非空判断即 hasXXX

    proto3 移除了内建类型的非空判断方法 即代码生成工具不会为 bool int 等类型生成has方法 有使用过proto2 或者其它rpc 框架的人都知道使用has 方法去判断消息里的值是否设置, ...

  3. Java中包的基本管理与编译

    在写程序的过程中,总会出现代码编译过关,但是项目偏偏报错的情况,遇到几种情况,都在此一一记录,希望以后少走弯路. 1.添加jsp文件的时候,会报错 Multiple annotations found ...

  4. Eclipse上传Git远程仓库,并且增加Maven Dependencies

    前言: 遇见问题了,公司一台电脑,家里一台电脑,当有项目在进行的时候,又不想把电脑背来背去的,就像一个人玩单机,这个时候GIT就可以帮你解决这个问题.当GIT准备就绪的时候,新的问题来了git下载下载 ...

  5. Ubuntu18.04 有线无法正常上网(请读完全文再进行操作)

    电脑Windows10+Ubuntu18.04双系统,一直都没问题,前段时间突然在Ubuntu系统下有线连接失败,但是在Windows下可以正常上网. 今天尝试进行了修复. 在终端通过ifconfig ...

  6. Django框架(八):视图(一) URLconf、视图

    1. 视图 视图的功能就是接收请求,进行处理,与M和T进行交互,返回应答. 返回html内容HttpResponse,也可能重定向redirect,还可以返回json数据. 1.1 URLconf 1 ...

  7. CocoaPods-Alcatraz插件

    Alcatraz:Xcode的插件管理工具,可通过它添加CocoaPods插件 下载地址:https://github.com/alcatraz/Alcatraz 建议: 不提倡通过终端命令下载Alc ...

  8. Postgresql的导表

    背景 前面已经介绍了常用的备份与恢复了,接下来介绍一下导表. 正文 很多情况,会有把数据导出的需求,轻重缓急总会有特别紧急的情况,但是又不是专业干db的人,还是记录下来,以防不时之需. 针对于导表,个 ...

  9. ZJNU 2206 - 染色

    开纵横两个结构体数组,记录连续涂了一整行或者一整列的情况 再开一个map,记录涂点 #include<iostream> #include<algorithm> #includ ...

  10. swift------导入OC三方类找不到头文件的解决方法

    1.首先新建个 swift工程 2.在swift 中新建 OC 类 比如新建 Request 类,会自动生成个.XXXX-Bridging-Header 类: 3.让后把 导入的第三方头文件导入进去. ...