(原创)如何进行有符号小数乘法运算?(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

 

仿真结果如下:

 

 

 

posted on 2010-07-25 13:03  小麻同学  阅读(17180)  评论(6编辑  收藏  举报

导航