新手求助 关于verilog中数值计算的设计方法。
所以我从来没碰过floating number和fixed point number这些运算。(又考虑小数,又考虑正负号。小弟我一头雾水。)
现在我只会用:
always @(posedge clk) sum=A+B;
做个整数的加减法(负整数verilog一律默认用补码表示对吧?目前实验都是成功的。)
但是如果在simulus模块中input小数,verilog根本不认。比如a=8'd3.14就是错误的,会报警。
关于小数运算,DSP芯片无疑是最典型的例子吧?而且各种application的各种算法都有实现到AISC上来加速。
所以我想verilog中的小数运算,应该是个成熟的技术吧?
请问各位大侠前辈,你们一般是如何实现fixed point或者是floating point的加减乘除的呢?
谢谢了。
不能识别小数的,都是当成整数来处理然后再来截位的,
比如A+B A=1.8, B=2.5
那先你自己规定下想用几位来代表小数精度,比如1.8=1+0.5+0.25+(后面还有0.05)
你要是想精度更深的话,把这0.05再这样展开,如果只想用两位小数,那1.8就按1.75来看待,{3'bA, 2'bB},也就是5'b00111 B=5'b01010 两个相加,5'b10001,也就是4.25, 拿着这个数你就知道前三位整数,后两位小数了。
要是不要想小数了,再右移两位,四舍五入,就得4了。
多谢大侠回复。我是不是可以这样理解:
小数的加减乘除,和整数的加减乘除一模一样,只是我得用人脑记住小数点位置(就像您刚才举的定点数例子)。
假设我只是人脑记好 “嗯,前3位是整数部分,后2位是小数部分”,然后事先把$readmemb所读取分件中的数都这么表示,然后全当整数在verilog里面算,最后输出的结果也用 “嗯,前3位是整数部分,后2位是小数部分” 来解释就行了吧?
对于乘除运算是不是会麻烦一些?而且 一般大侠们做真实项目的时候,是不是这样:
A(5位)X B(5位)= C(10位),一般想让C仍然是5位,然后结掉后5位。?。(我这里有点乱了)?
是的,对于加减是这样,不管整数小数都这样处理,心里知道后面几位代表小数就行。注意加减时,因为要考虑进位的位置,SUM会扩展到高一位的,如果你对和的值心里有数,不会发生溢出,或者溢出后可以直接截取高位,比如3位相加,010+010也就是2+2等于4嘛,那应该变成4位,0100, 如果你还写成三位的,100,那就变成-4了,
对于乘法更复杂些,A*B,都是前三位整数,后2位小数的,那乘出来10位数,应该是前6位是整数,后四位是小数了,不是5位……
对于除法,这个比较难,你直接用CORE使用就行,如果真要用,可以使用叠迭法,就是如果A/B,如果一个值D*B还小于A,但(D+1)*B就大于A了,那A/B就是D这个值了。
硬件小数运算可以用浮点运算单精度和双精度的都可以。
IEEE754标准,
opencores上有FPU的core可以下来看看。
谢谢回复。关于截断,那就意味着小数点的位置一定就变化了吧?
我知道您那个例子里两个数相乘后四位是小数,但是为了整齐,我下意识地希望所有寄存器都是5位的,所以就要把A*B也截成5位的(不知道大侠平时做大项目的时候也是这样做的吗?)所以我不可能只把4位小数丢掉,还剩下6位整数。 如果我把后5位都丢掉,那么我得到的数就是错的,但是位数对。如果我丢掉3位小数,和高位的2位整数,看起来错误就小多了(符号位另算,当然高位的2位应该是0)请问我这么想对吗?
看来数字只要相乘,位数就会变长,小数点位置就会变化,截断的话注意的问题也很多。不知道大侠们用的比较专业的设计方法是怎么的呢?
拿笔算,用精度的最后一位的数值衡量误差。
把误差表示出来,带入到系统中,累加起来看总误差是否满足需求。
每一次定点运算也好,截位也好,误差都不超过一个ulp (unit of least precision)
0.00001111截位到0.00001,总误差小于0.00001,也就是2^-5。
对于乘法,建议直接使用CORE,对于位数的处理,通常就是砍掉前面和砍后面的,两者同时进行来保证value正确,同时对于符号位这个要留神,
如果你是两个变量相乘的话,按上面的方法,如果仅是一个定量乘以变量,就不需要花费乘法器了,
比如A*1.8, 那就是A*(1+1/2+1/4+...),也就是等于A + A>>1 + A>>2
每次都要手工地去截位太复杂,可以的话,你可以自己去写一个模块,可以参数化地配置截位的,最好分为signed, unsigned,前面截多少位,后面多少位,你输入的数据多少位等, 配置下即可,
建议仔细阅读 《verilog 最后的私私细雨》中第一章“不同的自然”,对浮点数加减乘除有详细的讲解。
多谢各位大侠的指教,真是受益匪浅。
导师和我谈的时候,我感觉貌似倾向于用"定点数":
因为他先让我做一个matlab或者C的仿真(浮点数),然后verilog仿真,说会有区别,看看区别有多大。他虽然没有明确指示我用“定点数”,但是我和另外一个同学的第一印象都是要我们用“定点数”。
请问大侠们在research的时候,是如何决定用“定点数”或者“浮点数”的呢?
“定点数”乘法的Core在哪里能找到呢?谢谢
定点还是浮点主要看操作数以及中间结果的取值范围以及精度要求。
主要看你系统的要求,而且这两个都可以用数学表达进行定量分析。
既然你是做研究的,95%的事都要自己去搞定,网上的人只能给你提供个大概思路。
定点数加乘法太简单,除非对性能有特殊要求,否则一般没第三方提供的软核,都自己做。
FPGA,library,EDA厂家倒是一般会提供。
网上有可能能搜到booth结构的,一般质量难以保证。
可以去opencore看看。
另外关于定点还是浮点,我觉得你至少应该先去看看定点和浮点都什么特点。
多谢Patrick007指点。
以上的问题已经解决了,现在小弟还想请大侠们给个思路;
目前,我已经完成了一些小计算模块的设计(加减,乘法,LUT)仿真总算是通过了,现在就是把这些模块拼在一起,完成a+b*(1-exp(c)) 这样的matlab式的计算。但是硬件设计和matlab感觉大不一样了。于是我就有点蒙了。
请问: 如何进行时序上的控制,用CLK吗(每个module内部always @(posedge clk))?还是可以直接连接起来(每个module内部是always @(a,b,c))?
还有verilog里是如何实现循环嵌套的呢?(也可能我想错了,硬件实现是不是应该从另一个角度思考呢?)
。
我是半路出家的新手,很多这一行的专业课都是没上过。所以如果问了蠢问题,大侠们多多包涵啊:)
你这里面运算比较复杂,如果精度上有一定要求,exp不是一个周期能做好的。
应该先买本verilog的书看看。
规划一下硬件结构。
否则verilog写出来了,肯定也综合不了。
能综合,性能也上不去。
还是应该先看书,否则下面的话题,无从说起。
把书看好了,不急这一时。
与或非门是不认小数的
高手啊,受益匪浅啊
给您发送站内信了,恳请指导!
小编求指教的 我给你发了站内信息
高手高手又涨知识了
多谢 这篇文档将的很好
今天从这个帖子里学到很多东西,多谢小编,本人也想知道浮点数是怎么运算的,苦于一直没门路啊
学习了很多,最近也一直在做定点数的乘法非常纠结
现在正在看这一本,觉得很有用
