在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 2444|回复: 6

[求助] 求教一个关于小数乘法的问题

[复制链接]
发表于 2016-3-11 10:57:25 | 显示全部楼层 |阅读模式
200资产
module multiply(
   input clk,

input      signed [3:0] din_a, // bit3=符号位, bit2~bit0=整数位

input      signed [7:0] din_b, // bit7=符号位, bit6~bit4=整数位, bit3~bit0=小数位

output reg signed [7:0] dout
    );


reg signed [11:0] dout_r = 0;

always @ (posedge clk) begin
   dout <= (din_a*din_b)>>4;

// dout_r <= din_a*din_b;
//
dout   <= dout_r >> 4;
end

endmodule

代码很简单,就是两个有符号数的乘法,其中一个为整数,一个为小数,相乘后只取整数部分。

但是,我仿真发现,如果用always块中第一行语句的话,结果不正确;用always块中注释掉的部分结果就正确。

求大神指点。

1.png
 楼主| 发表于 2016-3-11 13:38:45 | 显示全部楼层
经总结发现:
1,使用always块第一句的话,会先计算din_a*din_b的值(用补码表示),然后截断为8bit,在然后右移4bit,>>运算符在执行右移操作时会将左边空出来的bit位补0,所以运算结果会都是正的。
2,解决办法:(1)按照always块中注释部分执行;(2)将>>改为>>>移位运算符即可,>>>运算符在移位时会根据被移位的数是有符号还是无符号,在空出的bit位相应的补'1'和‘0’。
发表于 2016-3-18 06:00:17 | 显示全部楼层

标题



这个写法<<<,可综合吗?
 楼主| 发表于 2016-3-18 08:26:02 | 显示全部楼层
回复 3# 董小三

可以
发表于 2016-3-18 11:14:33 | 显示全部楼层
分享是种美德
发表于 2016-3-18 16:42:46 | 显示全部楼层
dout <= (din_a*din_b)>>4;
是软件的思想,编译成汇编对应三个步骤,1、计算乘法的结果,2、把结果移位,3、再将结果赋值
Verilog是硬件,每步都要对应的硬件来实现的,顺序跟软件计算的是一样的,但这是硬件,不是软件,每个语句都对应一个确切的输入输出的硬件结构
你注释掉的才是确定的结构:第一句代表一个乘法器,第二句代表一组寄存器

进一步,你可以这样写:
module multiply(
    input clk,
   input      signed [3:0] din_a, // bit3=符号位, bit2~bit0=整数位
   input      signed [7:0] din_b, // bit7=符号位, bit6~bit4=整数位, bit3~bit0=小数位
   output   signed [7:0] dout
);

reg signed [11:0] dout_r = 0;
always @ (posedge clk) begin
  dout_r <= din_a*din_b;
end

assign dout = dout_r[11:4];
endmodule
这样dout可以提前一个周期输出结果。
发表于 2016-3-18 19:25:59 | 显示全部楼层
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /3 下一条

×

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-4-19 15:10 , Processed in 0.033605 second(s), 8 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表