(原创)如何进行有符号小数乘法运算?(Verilog)

本例程实现的是,从外部输入两个32位有符号小数,进行乘运算,输出的乘积为32位有符号小数。

 

 
  
1 module fix_mult ( clk,rst_n,in_a,in_b,x1,x2,x3,x4,x5,x6,x7,y_out );
2
3   input clk,rst_n; // 时钟和复位信号
4   input [ 31 : 0 ] in_a,in_b; // 输入的被乘数和乘数
5   output [ 31 : 0 ] y_out; // 输出的乘积
6 /* 寄存器类型变量 为了能更清楚的了解全处理过程,
7 特地设计为输出的,不然仿真可能会被综合掉 */
8   output [ 15 : 0 ] x1,x2,x3,x4;
9   output [ 0 : 0 ] x5;
10   output [ 29 : 0 ] x6;
11 output [ 31 : 0 ] x7;
12
13 /// //
14 reg [ 31 : 0 ] y_out;
15 reg [ 15 : 0 ] x1,x2,x3,x4;
16 reg [ 0 : 0 ] x5;
17 reg [ 29 : 0 ] x6;
18 reg [ 31 : 0 ] x7;
19
20
21 always @ ( posedge clk )
22 begin
23 if ( ! rst_n ) // 复位时,全部寄存器变量清零
24 begin
25 x1 <= 16 ' b0;
26 x2 <= 16 ' b0;
27 x3 <= 16 ' b0;
28 x4 <= 16 ' b0;
29 x5 <= 1 ' b0;
30 x6 <= 30 ' b0;
31 x7 <= 32 ' b0;
32 y_out <= 32 ' b0;
33 end
34 else // 全过程可以看成:把32位的小数截取高16位—》左移16位,变为16位整数—》
35 // 相乘得到32位整数乘积后,右移32位—》调整无关位的位置—》得到32位小数
36 begin
37 x1 <= in_a[ 31 : 16 ]; // 截取16位被乘数,
38 x2 <= in_b[ 31 : 16 ]; // 截取16位乘数
39 x3 <= (x1[ 15 ] == 0 ) ? x1:{x1[ 15 ], ~ x1[ 14 : 0 ] + 1 ' b1}; //据最高位判断是否为负数,
40 // 若负数则把补码转成原码
41 x4 <= (x2[ 15 ] == 0 ) ? x2:{x2[ 15 ], ~ x2[ 14 : 0 ] + 1 ' b1};
42 x5 <= x3[ 15 ] ^ x4[ 15 ]; // 两数符号位相异或,得到乘积的符号位
43 x6 <= x3[ 14 : 0 ] * x4[ 14 : 0 ]; // 两数的数据位相乘
44 x7 <= {x5,x6, 1 ' b0}; //乘积由1位符号位和30位数据位及1位无关组成;
45 // 因为是小数,往低位生长,所以无关位放置最低位
46 y_out <= (x7[ 31 ] == 0 ) ? x7:{x7[ 31 ], ~ x7[ 30 : 0 ] + 1 ' b1};
47 end
48 end
49
50 endmodule

 

仿真结果如下:

 

2010072513414732.png

 

 

转载于:https://www.cnblogs.com/maqingbiao/archive/2010/07/25/1784634.html

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值