-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmul.v
More file actions
134 lines (124 loc) · 3.71 KB
/
mul.v
File metadata and controls
134 lines (124 loc) · 3.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
`timescale 10ns / 1ns
module mul
(
input mul_clk,
input resetn,
input mul_signed,
input [31:0] x,
input [31:0] y,
output [63:0] result
);
parameter TOTAL_BITS=64;//部分积的长度
parameter IN_BITS=34;//输入的乘数的位宽
parameter EXTEND_BITS1=32;
parameter EXTEND_BITS2=2;
parameter NUM_RESULTS=17;//部分积的个数
wire [TOTAL_BITS-1:0] longx;
wire [IN_BITS-1:0] longy;
assign longx={{EXTEND_BITS1{mul_signed&x[31]}},x};
assign longy={{EXTEND_BITS2{mul_signed&y[31]}},y};
//输入扩展后的longx(TOTAL_BITS=64),与longy(IN_BITS=34),得到P和C
wire [TOTAL_BITS-1:0] P [NUM_RESULTS-1:0];
wire [NUM_RESULTS-1:0] neg_flag;
wire [TOTAL_BITS-1:0] two_X;
wire [TOTAL_BITS-1:0] neg_X;
wire [TOTAL_BITS-1:0] two_neg_X;
assign two_X={longx[TOTAL_BITS-2:0],1'b0};
assign neg_X=~longx;
assign two_neg_X=~two_X;
genvar result_num;
generate
for(result_num=0;result_num<NUM_RESULTS;result_num=result_num+1)
begin:booth_num
wire y2,y1,y0;
wire [TOTAL_BITS-1:0] single_p;
wire [TOTAL_BITS-1:0] temp_p;
wire single_neg_flag;//取反的标志位
if(result_num==0)
begin
assign y0=1'b0;
assign {y2,y1}=longy[1:0];
end
else
begin
assign {y2,y1,y0}=longy[2*result_num+1:2*result_num-1];
end
wire [2:0] sel;
assign sel={y2,y1,y0};
assign temp_p=({TOTAL_BITS{sel==3'b000}} & {TOTAL_BITS{1'b0}})
|({TOTAL_BITS{sel==3'b001}} & longx)
|({TOTAL_BITS{sel==3'b010}} & longx)
|({TOTAL_BITS{sel==3'b011}} & two_X)
|({TOTAL_BITS{sel==3'b100}} & two_neg_X)
|({TOTAL_BITS{sel==3'b101}} & neg_X)
|({TOTAL_BITS{sel==3'b110}} & neg_X)
|({TOTAL_BITS{sel==3'b111}} & {TOTAL_BITS{1'b0}});
if(result_num==0)
begin
assign single_p=temp_p;
end
else
begin
assign single_p={temp_p[TOTAL_BITS-1-2*result_num:0],{2*result_num{single_neg_flag}}};//允许0个拼接在一起吗
end
assign P[result_num]=single_p;
assign single_neg_flag=(sel==3'b100)|(sel==3'b101)|(sel==3'b110);
assign neg_flag[result_num]=single_neg_flag;
end
endgenerate
//受流水线影响,neg_flag的5-15位都要保存下来
reg [NUM_RESULTS-1:0] neg_flag_reg;
always @(posedge mul_clk)
begin
if(resetn==0)
begin
neg_flag_reg<={NUM_RESULTS{1'b0}};
end
else
begin
neg_flag_reg<=neg_flag;
end
end
wire [16:0] in [TOTAL_BITS-1:0];
wire [13:0] cin;
wire [TOTAL_BITS-1:0] tempA;//C,没有进行错位处理,应该左移一位才是要用的
wire [TOTAL_BITS-1:0] B;//S
genvar gvr1;
genvar gvr2;
generate
for(gvr1=0;gvr1<TOTAL_BITS;gvr1=gvr1+1)
begin:loop1
for(gvr2=0;gvr2<NUM_RESULTS;gvr2=gvr2+1)
begin:loop2
assign in[gvr1][gvr2]=P[gvr2][gvr1];
end
end
endgenerate
assign cin[13:0]=/*neg_flag[13:0]*/{neg_flag_reg[13:5],neg_flag[4:0]};
//17个加数,每个加数TOTAL_BITS=64位的华莱士树
genvar bit_num;
generate
for(bit_num=0;bit_num<TOTAL_BITS;bit_num = bit_num+1)
begin:tree_num
wire [16:0] single_in;
wire [13:0] single_cin;
wire [13:0] single_cout;
wire single_A,single_B;
one_bit_Wallace u_one_bit_Wallace(.clk(mul_clk),.resetn(resetn),.in(single_in),.cin(single_cin),.cout(single_cout),.A(single_A),.B(single_B));
assign single_in=in[bit_num];
assign tempA[bit_num]=single_A;
assign B[bit_num]=single_B;
if(bit_num==0)
begin
assign single_cin=cin;
end
else
begin
assign single_cin=tree_num[bit_num-1].single_cout;
end
end
endgenerate
wire [TOTAL_BITS-1:0] A;
assign A={tempA[TOTAL_BITS-2:0],neg_flag_reg[14]};
assign result=A+B+neg_flag_reg[15];
endmodule