加减乘,在fpga设计中,使用verilog hdl语言来描述,简单的很,直接就是+、-、*,没有任何疑问,但是计算过程中的信号的位宽,却值得认真揣摩。
数学运算,必然涉及到有符号数与无符号数的区别,因此在写hdl代码时,必须明确参与运算的信号是否是有符号数。建议:参与运算的符号要么都是有符号数,要么都是无符号数,不建议使用有符号数与无符号数进行数学运算,如果在参与运算的两个信号一个是有符号数,而另外一个是无符号数的话,建议把无符号数扩展一位,将其转换成有符号数来进行处理。
无符号数扩展成有符号数的方法(以verilog为例):
input [7:0] data;
wire [8:0] data_r;
assign data_r = {data[7],data};
加法运算中的位宽处理:
input [7:0] data_a;
input [7:0] data_b;
output [8:0] data_x;
wire [8:0] data_x;
assign data_x = data_a + data_b;
如上面的代码,在做加法运算的时候,建议:
1、加法运算符两边的信号,位宽一致;
2、加法运算符两边的信号,要么都是有符号数,要么都是无符号数;
2、考虑到加法可能产生进位,输出信号比输入信号多1bit即可。
乘法运算中的位宽处理:
1. 两个无符号数相乘
input [7:0] data_a;
input [4:0] data_b;
output [12:0] data_x;
wire [12:0] data_x;
assign data_x = data_a * data_b;
两个无符号数相乘,输出信号位宽直接定义成两个输入信号位宽之和即可。
2. 两个有符号数相乘
reg signed [7:0] data_a;
reg signed [4:0] data_b;
output [12:0] data_x;
wire signed [11:0] data_x;
assign data_x = data_a * data_b;
两个有符号数相乘,考虑到符号位可以合并成一位,输出信号位宽定义成两个输入信号位宽之和-1即可。
3. 平方运算
如果输入信号是无符号数,则输出信号位宽等于输入信号位宽2倍;
如果输入信号是有符号数,则输出信号位宽等于输入信号位宽2倍-2
上述这些都是些基本概念,自己总结一下,备忘。。。
不错!设计中的基本常识,收下!
一个为理想不懈前进的人,一个永不言败人!
http://shop57496282.taobao.com/
欢迎光临网上店铺!
总结不错!如果能把两个有符号数相乘,不使用signed来表示,把代码写出来,会有更深的认识的。
一个为理想不懈前进的人,一个永不言败人!
http://shop57496282.taobao.com/
欢迎光临网上店铺!
一个为理想不懈前进的人,一个永不言败人!
http://shop57496282.taobao.com/
欢迎光临网上店铺!
还要注意有符号数与无符号数移位, << 和 >> 是逻辑的,<<< 和 >>>是算术的
移位前后位宽应该没有改变,
如定义reg signed [7:0] x;
x >>> 1相当于 { x[7], x[6:1] };
而x >> 1相当于 { 1'b0, x[6:1] };
如定义reg [7:0] x;
x >>> 1相当于 {1‘b0 x[6:1] };
而x >> 1也相当于 { 1'b0, x[6:1] };
C语言中移位是根据是否是有符号数来决定的,有符号数都为算术移位,无符号术都为逻辑移位,verilog和C语言这里不同,应该注意一下
如果能实现有符号补码乘法器,对这个乘法器的原理有很深刻的认识。
一个为理想不懈前进的人,一个永不言败人!
http://shop57496282.taobao.com/
欢迎光临网上店铺!
有符号的数的乘法,能否深入一下!
一个为理想不懈前进的人,一个永不言败人!
http://shop57496282.taobao.com/
欢迎光临网上店铺!
回复 10楼 chat1 的帖子
请教一下,为什么您这儿向右移位之后寄存器由八位变成七位了,然后>>>是什么符号能解释一下吗?我是新手,请赐教,谢谢