乘法器的verilog实现(并行、移位相加、查找表)

更新时间:2023-05-25 07:11:12 阅读: 评论:0

乘法器的verilog实现(并⾏、移位相加、查找表)并⾏乘法器,也就是⽤乘法运算符实现,下⾯的代码实现8bit⽆符号数的乘法。
代码:
1module mult_parrell(rst_n,
太空舞步教程
2                            clk,
3                            a,
4                            b,
5                            p
6                                  );
7parameter DATA_SIZE = 8;
8
9input rst_n;
星期日的英文
10input clk;
11input [DATA_SIZE - 1 : 0] a;
12input [DATA_SIZE - 1 : 0] b;
13
14output [2*DATA_SIZE - 1 : 0] p;
15
16reg [DATA_SIZE - 1 : 0] a_r;
17reg [DATA_SIZE - 1 : 0] b_r;
18
19wire [2*DATA_SIZE - 1 : 0] p_tmp;
20reg [2*DATA_SIZE - 1 : 0] p;
21
22//输⼊数据打⼀拍
23always@(podge clk)
24if(!rst_n)
25begin
26            a_r <= 8'd0;
27            b_r <= 8'd0;
28end
29el
30begin
31            a_r <= a;
32            b_r <= b;
33end
34
35assign p_tmp = a*b;  //只能做⽆符号数的相乘,若要做有符号数乘法,需将数据声明为signed类型
36
37//输出数据打⼀拍
38always@(podge clk)
39if(!rst_n)
40begin
41            p <= 16'd0;
42end
43el
44begin
45            p <= p_tmp;
46end
47
48endmodule
移位相加乘法器,下⾯的代码可实现8bit有符号数的相乘,注意符号扩展以及MSB位的处理:
//输⼊数据取反
assign a_r_inv = ~a_r + 1;
assign a_shift0 = b_r[0] ? {{8{a_r[7]}},a_r} : 0;
assign a_shift1 = b_r[1] ? {{7{a_r[7]}},a_r,1'b0} : 0;
assign a_shift2 = b_r[2] ? {{6{a_r[7]}},a_r,2'b0} : 0;
assign a_shift3 = b_r[3] ? {{5{a_r[7]}},a_r,3'b0} : 0;
assign a_shift4 = b_r[4] ? {{4{a_r[7]}},a_r,4'b0} : 0;
assign a_shift5 = b_r[5] ? {{3{a_r[7]}},a_r,5'b0} : 0;
assign a_shift6 = b_r[6] ? {{2{a_r[7]}},a_r,6'b0} : 0;
assign a_shift7 = b_r[7] ? {{1{a_r_inv[7]}},a_r_inv,7'b0} : 0;  //被乘数为⽆符号数时,特别处理
代码:
1module mult_shift_add(rst_n,
2                                clk,
3                                a,
4                                b,
5                                p
6                                      );
7parameter DATA_SIZE = 8;
8
9input rst_n;
10input clk;
11input [DATA_SIZE - 1 : 0] a;
12input [DATA_SIZE - 1 : 0] b;
13
14output [2*DATA_SIZE - 2 : 0] p;
15
16//输⼊数据打⼀个时钟节拍
17reg [DATA_SIZE - 1 : 0] a_r;
18reg [DATA_SIZE - 1 : 0] b_r;
19
20//输⼊数据取反
21wire [DATA_SIZE - 1 : 0] a_r_inv;
22
23//输⼊数据移位
24wire [2*DATA_SIZE - 1 : 0] a_shift0;
25wire [2*DATA_SIZE - 1 : 0] a_shift1;
26wire [2*DATA_SIZE - 1 : 0] a_shift2;
27wire [2*DATA_SIZE - 1 : 0] a_shift3;
28wire [2*DATA_SIZE - 1 : 0] a_shift4;
29wire [2*DATA_SIZE - 1 : 0] a_shift5;
30wire [2*DATA_SIZE - 1 : 0] a_shift6;
31wire [2*DATA_SIZE - 1 : 0] a_shift7;
32
33//输出数据打⼀个时钟节拍
34wire [2*DATA_SIZE - 1 : 0] p_tmp;
35reg [2*DATA_SIZE - 1 : 0] p;
36
37//输⼊数据打⼀个时钟节拍
38always@(podge clk)
39if(!rst_n)
40begin
41            a_r <= 8'd0;
42            b_r <= 8'd0;
43end
44el
45begin
46            a_r <= a;
47            b_r <= b;
48end
inform
49//输⼊数据取反
50assign a_r_inv = ~a_r + 1;
51
52//输⼊数据移位,注意符号扩展,不仅仅是最⾼位扩展
53//对每⼀个bit都需扩展
54assign a_shift0 = b_r[0] ? {{8{a_r[7]}},a_r} : 0;
55assign a_shift1 = b_r[1] ? {{7{a_r[7]}},a_r,1'b0} : 0;sheep是什么意思
56assign a_shift2 = b_r[2] ? {{6{a_r[7]}},a_r,2'b0} : 0;
57assign a_shift3 = b_r[3] ? {{5{a_r[7]}},a_r,3'b0} : 0;
58assign a_shift4 = b_r[4] ? {{4{a_r[7]}},a_r,4'b0} : 0;
59assign a_shift5 = b_r[5] ? {{3{a_r[7]}},a_r,5'b0} : 0;
60assign a_shift6 = b_r[6] ? {{2{a_r[7]}},a_r,6'b0} : 0;
61assign a_shift7 = b_r[7] ? {{1{a_r_inv[7]}},a_r_inv,7'b0} : 0;  //被乘数为⽆符号数时,特别处理62
bathroom怎么读63assign p_tmp = a_shift0 + a_shift1 + a_shift2 + a_shift3 + a_shift4
64                    + a_shift5 + a_shift6 + a_shift7;
65
66always@(podge clk)
67if(!rst_n)
68begin
69//p <= 16'd0;
70            p <= 15'd0;
71end
72el
73begin
74//p <= p_tmp[15:0];
75            p <= p_tmp[14:0];
76end
77
78endmodule
testbench:
1module mult_shift_add_tb;
2
3// Inputs
4reg rst_n;
5reg clk;
6reg [7:0] a;
7reg [7:0] b;
8
9// Outputs
10wire [14:0] p;
11
12// Instantiate the Unit Under Test (UUT)
13    mult_shift_add uut (
14        .rst_n(rst_n),
15        .clk(clk),
16        .a(a),
17        .b(b),
18        .p(p)
19    );
20
21parameter CLK_PERIOD = 10;
22
23initial begin
24        rst_n = 0;
25        clk = 0;
26
27        #100;
28        rst_n = 1;
29end
一整天英语
30
31always #(CLK_PERIOD/2) clk = ~clk;
32
33always@(podge clk)
34if(!rst_n)
35begin
36            a = 8'd0;
37            b = 8'd0;
38end
39el
40begin
41            a = a + 1;
42            b = b - 1;
43end
44
45endmodule
ISIM仿真结果:
移位相加乘法器树:
assign p_tmp = a_shift0 + a_shift1 + a_shift2 + a_shift3 + a_shift4 + a_shift5 + a_shift6 + a_shift7;换为:
assign sum_01 = a_shift0 + a_shift1;
assign sum_23 = a_shift2 + a_shift3;
assign sum_45 = a_shift4 + a_shift5;
assign sum_67 = a_shift6 + a_shift7;
assign sum_0123 = sum_01 + sum_23;
assign sum_4567 = sum_45 + sum_67;iaea
assign p_tmp = sum_0123 + sum_4567;
就成为乘法器树。
原理是通过切断关键路径,提⾼电路的运⾏频率。
LUT乘法,下⾯的代码利⽤2bit的LUT实现4bit⽆符号数的乘法。
代码:
1module mult_lut(rst_n,
2                        clk,
3                        a,
4                        b,
5                        p
6                              );
7
8parameter DATA_SIZE = 4;
9
10input rst_n;
11input clk;
12input [DATA_SIZE - 1 : 0] a;
13input [DATA_SIZE - 1 : 0] b;
14
15output [2*DATA_SIZE - 1 : 0] p;
16
17//输⼊数据打⼀个时钟节拍
18reg [DATA_SIZE - 1 : 0] a_r;
19reg [DATA_SIZE - 1 : 0] b_r;
20
21//输⼊数据拆半的乘积
22
23wire [DATA_SIZE - 1 : 0] p_tmp00;
24wire [DATA_SIZE - 1 : 0] p_tmp01;
25
26wire [DATA_SIZE - 1 : 0] p_tmp10;
27wire [DATA_SIZE - 1 : 0] p_tmp11;
28
29//reg [2*DATA_SIZE - 1 : 0] sum01;
30//reg [2*DATA_SIZE - 1 : 0] sum23;
31
32wire [2*DATA_SIZE - 1 : 0] p_tmp;
33reg [2*DATA_SIZE - 1 : 0] p;
34
35//输⼊数据打⼀个时钟节拍
36always@(podge clk)
37if(!rst_n)
38begin
39            a_r <= 4'd0;
40            b_r <= 4'd0;
41end
42el
43begin
44            a_r <= a;
45            b_r <= b;
46end
47
48 mult_lut_2bit u0_mult_lut_2bit (
49    .rst_n(rst_n),
50    .clk(clk),
51    .a(a_r[1:0]),
52    .b(b_r[1:0]),
53    .p(p_tmp00)
54    );
55
56 mult_lut_2bit u1_mult_lut_2bit (
57    .rst_n(rst_n),
58    .clk(clk),
59    .a(a_r[1:0]),
60    .b(b_r[3:2]),
61    .p(p_tmp01)
62    );
63
64 mult_lut_2bit u2_mult_lut_2bit (
65    .rst_n(rst_n),
66    .clk(clk),
67    .a(a_r[3:2]),
68    .b(b_r[1:0]),
69    .p(p_tmp10)
70    );
71
72 mult_lut_2bit u3_mult_lut_2bit (
73    .rst_n(rst_n),
74    .clk(clk),
75    .a(a_r[3:2]),
76    .b(b_r[3:2]),
77    .p(p_tmp11)
78    );
79
80//assign p_tmp = p_tmp00 + p_tmp01<<2 + p_tmp10<<2 + p_tmp11<<4; //不能直接⽤移位操作符实现移位81assign p_tmp = p_tmp00 + {p_tmp01,2'b00} + {p_tmp10,2'b00} + {p_tmp11,4'b00};
82//assign sum01 = p_tmp00 + p_tmp01<<2;
83//assign sum23 = p_tmp10<<2 + p_tmp11<<4;
84
85//assign p_tmp = sum01 + sum23;
86
87always@(podge clk)
88if(!rst_n)
89begin
90            p <= 8'd0;
91end
92el
93begin
94            p <= p_tmp;
95end
96
97endmodule
2bitLUT乘法器:
1module mult_lut_2bit(rst_n,
2                            clk,
3                            a,
4                            b,
5                            p
6                                  );
7
8parameter DATA_SIZE = 2;
effective9
10input rst_n;
11input clk;
12input [DATA_SIZE - 1 : 0] a;
13input [DATA_SIZE - 1 : 0] b;
14
15output [2*DATA_SIZE - 1 : 0] p; 16
17//输⼊数据打⼀个时钟节拍
18reg [DATA_SIZE - 1 : 0] a_r;
19reg [DATA_SIZE - 1 : 0] b_r;
20
21//输出数据打⼀个时钟节拍深大师院国际高中
22reg [2*DATA_SIZE - 1 : 0] p_tmp; 23reg [2*DATA_SIZE - 1 : 0] p;
24
25//输⼊数据打⼀个时钟节拍
26always@(podge clk)
27if(!rst_n)
28begin
29            a_r <= 8'd0;
30            b_r <= 8'd0;
31end
32el
33begin
34            a_r <= a;
35            b_r <= b;
36end
37
38always@(*)
39begin
40ca({a_r,b_r})
414'b0000 : p_tmp = 4'b0000; 424'b0001 : p_tmp = 4'b0000; 434'b0010 : p_tmp = 4'b0000; 444'b0011 : p_tmp = 4'b0000; 454'b0100 : p_tmp = 4'b0000; 464'b0101 : p_tmp = 4'b0001; 474'b0110 : p_tmp = 4'b0010; 484'b0111 : p_tmp = 4'b0011; 49
504'b1000 : p_tmp = 4'b0000; 514'b1001 : p_tmp = 4'b0010; 524'b1010 : p_tmp = 4'b0100; 534'b1011 : p_tmp = 4'b0110; 544'b1100 : p_tmp = 4'b0000; 554'b1101 : p_tmp = 4'b0011; 564'b1110 : p_tmp = 4'b0110; 574'b1111 : p_tmp = 4'b1001; 58endca
59end
60
61always@(podge clk)
62if(!rst_n)
63begin
64            p <= 4'd0;
65end
66el
67begin
68            p <= p_tmp[3:0];
69end日本大学
70
71endmodule

本文发布于:2023-05-25 07:11:12,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/78/768188.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

上一篇:hypermesh教程4
下一篇:FPGA代码
标签:数据   符号   移位   时钟
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图