-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathCSA_carry.v
100 lines (88 loc) · 2.05 KB
/
CSA_carry.v
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
module CSA_carry(
input enable,
input clk,
input[79:0] frac_even,
input[79:0] frac_odd,
output[1:0] adr_even,
output[1:0] adr_odd,
output[2:0] blk,
output[127:0] frac_out,
output clr_odd,
output sign,
output finish
);
reg[15:0] carry;
reg sign_1;
reg[63:0] fraction;
reg[2:0] block,block_delay1;
reg stop_flag,stop_flag_delay1;
reg enable_delay1;
wire[79:0] frac;
wire[79:0] add_result;
assign frac=block[0]?frac_odd:frac_even;
assign add_result=frac+{{64{carry[15]}},carry};
always@(posedge clk)begin
if(enable)begin
block<=3'b000;
carry<=16'b0;
fraction<=64'b0;
stop_flag<=1'b0;
end
else begin
if(block==3'b111)begin
stop_flag<=1'b1;
end else begin
block<=block+3'b1;
end
carry<=add_result[79:64];
fraction<=add_result[63:0];
end
if(block==3'b111)begin
sign_1<=carry[15];
end
block_delay1<=block;
stop_flag_delay1<=stop_flag;
enable_delay1<=enable;
end
reg[127:0] fraction_pos_2,fraction_neg_2;
reg[2:0] block_pos_2,block_neg_2;
reg sign_2;
reg finish_2,finish_2_delay,finish_2_delay2;
always@(posedge clk)begin
if(enable_delay1)begin
fraction_pos_2<=128'b0;
fraction_neg_2<=128'b0;
block_neg_2<=3'b0;
block_pos_2<=3'b0;
end else begin
if(~stop_flag_delay1) begin
if(fraction!=64'b0)begin
fraction_pos_2[127:64]<=fraction;
fraction_pos_2[63:0]<=(block_delay1==(block_pos_2+3'b1))?fraction_pos_2[127:64]:64'b0;
block_pos_2<=block_delay1;
end
if(fraction!=64'hffff_ffff_ffff_ffff)begin
fraction_neg_2[127:64]<=fraction;
fraction_neg_2[63:0]<=(block_delay1==(block_neg_2+3'b1))?fraction_neg_2[127:64]:64'b0;
block_neg_2<=block_delay1;
end
end
end
if(block_delay1==3'b110)begin
finish_2<=1'b1;
end
else begin
finish_2<=1'b0;
end
sign_2<=sign_1;
finish_2_delay<=finish_2;
finish_2_delay2<=finish_2_delay;
end
assign adr_even=block[2:1];
assign adr_odd=block[2:1];
assign frac_out=sign_2?fraction_neg_2:fraction_pos_2;
assign blk=sign_2?block_neg_2:block_pos_2;
assign clr_odd=block[0];
assign sign=sign_2;
assign finish=finish_2_delay2;//&~finish_2_delay2;
endmodule