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 ...
随机推荐
- 201771010123汪慧和《面向对象程序设计Java》第十一周实验总结
一.理论部分 1.栈 (1)栈是一种特殊的线性表,是一种后进先出的结构.(2)栈是限定仅在表尾进行插入和删除运算的线性表,表尾称为栈顶,表头称为栈底.(3)栈的物理存储可以用顺序存储结构,也可以用链式 ...
- Block实现代理/通知效果
例子1:A控制器->跳转—>B控制器 , 假设想从B控制器回传数组给A控制器 实现:B控制器.h文件定义一个block参数,.m文件执行block,A控制器设置block内容 B.h文件/ ...
- 题解【[HAOI2006]受欢迎的牛】
切水题,写题解~ tarjan缩一波点,然后 只有一个出度为0的点:他的size就是答案 有多个初度为0的点:无解,0个 因为是强联通分量,所以肯定有出度为0的点,否则--就是你tarjan写挂了~ ...
- mysql的show status和show global status区别在哪
show status 本次会话的参数状态show global status 本次MYSQL服务开启(或重置)到现在总请求数
- zip4j 2.0压缩 加密压缩
https://github.com/srikanth-lingala/zip4j ZipParameters zipParameters = new ZipParameters(); zipPara ...
- POJ 1201 Intervals【差分约束】
传送门:http://poj.org/problem?id=1201 题意: 有n个如下形式的条件:,表示在区间[, ]内至少要选择个整数点.问你满足以上所有条件,最少需要选多少个点? 思路:第一道差 ...
- RedHat6.5升级内核
redhat6.5 升级内核 1.导入key rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org 2.安装elrepo的yum源 rp ...
- 【MySQL参数】-innodb_additional_mem_pool_size
原博客:https://yq.aliyun.com/articles/32384
- QeePHP
百度百科: https://baike.baidu.com/item/qeephp/8328612?fr=aladdin 官方地址: http://www.qeephp.cn/app/index.ph ...
- 四、Shell脚本高级编程实战第四部
一.比较两个数的大小 #!/bin/shread -p "Pls input two num:" a b[ -z "$a" ] || [ -z "$b ...