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 ...
随机推荐
- Vue.js——3.增删改查
vue 写假后台 bootstrap 做的样式 代码 <!DOCTYPE html> <html lang="en"> <head> < ...
- 拷贝构造函数[c++]
拷贝构造函数何时会被调用? 1. 对象以值传递的方式传入函数参数 2.对象以值传递的方式从函数返回 3.对象需要通过另外一个对象进行初始化 下面我们来看代码: //#include <iostr ...
- android implementation 依赖第三方库
依赖第三方库
- Java多线程求和
package test; import java.util.concurrent.*; import java.util.concurrent.locks.Lock; import java.uti ...
- 第二季第八天 part2
for (let i = 0; i < 3; i++) { log(i) } log(i) // 结果是 undefined let和const的作用域只在花括号内 let和const不能重复声 ...
- JavaSE--【转】网络安全之证书、密钥、密钥库等名词解释
转载 http://www.cnblogs.com/alanfang/p/5600449.html 那些证书相关的名词解释(SSL,X.509,PEM,DER,CRT,CER,KEY,CSR,P12等 ...
- mac词典安装
网上下载词典文件,比如https://www.xiaomac.com/2013121204.html,将朗道词典解压放入这里. $ ls /Library/Dictionaries/ langdao- ...
- day49-线程-事件
#1.Event里面有一个标志flag,当e = Event()刚创建的时候,flag=False,阻塞,这个时候,e.is_set()也是等于False,阻塞. #e.set()让flag变成非阻塞 ...
- 实现hashmap
/**数组下面挂着链表*/ #include<stdio.h> #include<unistd.h> #include<stdlib.h> #include< ...
- mock简单的json返回
针对非常简单的json返回串,我们也不一定非得通过freemarker模板的方式来构造返回数据,这里看实际的需求,如果返回的内容是固定的,而且json又非常简单,我们也可以直接写在程序里面,下面的接口 ...