标签:
杂谈 |
这段时间设计环路滤波器,用到小数乘法,我在博客园上找了篇文章,学校的网最近不稳定,并不总是能上上去,所以记下了,防止忘记~~~
原文出处:http://www.cnblogs.com/maqingbiao/archive/2010/07/25/1784634.html
例程实现的是,从外部输入两个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
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
2
3
4
5
6
8
13 /////////////////////////////////////////////////////
14 reg [31:0]
20
21 always @ ( posedge clk )
22 begin
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
49
50 endmodule
仿真结果如下: