-
Notifications
You must be signed in to change notification settings - Fork 1
/
addsub.v
128 lines (107 loc) · 2.93 KB
/
addsub.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
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
// 0 for add, 1 for sub (matches designware why not)
`define ADD 1'b0
`define SUB 1'b1
// +/- sign bit
`define POS 1'b0
`define NEG 1'b1
module addsub(
input wire op, // 0 for add, 1 for sub (matches designware why not)
input wire [31:0] a,
input wire [31:0] b,
output wire [31:0] z
);
// SP floating point fields
`define sign 31
`define exponent 30:23
`define mantissa 22:0
// Add and subtract
wire [31:0] abs_a; assign abs_a = {`POS,a[30:0]};
wire [31:0] abs_b; assign abs_b = {`POS,b[30:0]};
wire [31:0] zadd;
sradd ADD (
.a(abs_a),
.b(abs_b),
.z(zadd)
);
wire [31:0] zsub;
srsub SUB (
.a(abs_a),
.b(abs_b),
.z(zsub)
);
//////////////////////////////////////
// op sign(a) sign(b) result //
// -------------------------------- //
// add + + (a+b) //
// add + - (a-b) //
// add - + -(a-b) //
// add - - -(a+b) //
// -------------------------------- //
// sub + + (a-b) //
// sub + - (a+b) //
// sub - + -(a+b) //
// sub - - -(a-b) //
//////////////////////////////////////
// Sign bit shortcuts
wire apos; assign apos = (a[`sign] == `POS);
wire bpos; assign bpos = (b[`sign] == `POS);
wire [31:0] zraw;
assign zraw =
((op == `ADD) && apos && bpos) ? zadd :
((op == `ADD) && apos && ~bpos) ? zsub :
((op == `ADD) && ~apos && bpos) ? zsub^32'h80000000 :
((op == `ADD) && ~apos && ~bpos) ? zadd^32'h80000000 :
((op == `SUB) && apos && bpos) ? zsub :
((op == `SUB) && apos && ~bpos) ? zadd :
((op == `SUB) && ~apos && bpos) ? zadd^32'h80000000 :
((op == `SUB) && ~apos && ~bpos) ? zsub^32'h80000000 :
32'hFFFFFFFF;
// oh how i hate to do this
// turn -0 (0x80000000) into true zero (0x00000000)
// wire [31:0] z;
assign z = (zraw == 32'h80000000) ? 32'h0 : zraw;
// FIXME Technically I think these are supposed to be OUTSIDE the module def
//`define DBG1
//`define DBG9
`ifdef DBG1
always @ (*) begin
$display("%m fooo");
if (op == `ADD) begin
$display("%m..ADD a=bsr'%08X (%08X) b=bsr'%08X (%08X) z=bsr'%08X (%08X)",
a, a, b, b, z, z);
end else begin
$display("%m..SUB a=bsr'%08X (%08X) b=bsr'%08X (%08X) z=bsr'%08X (%08X)",
a, a, b, b, z, z);
end
`ifdef DBG9
$display("%m op=%1x apos=%1x bpos=%1x", op, apos, bpos);
$display("%m (op==SUB) = %x", (op==`SUB));
$display("%m (op==SUB) && apos && bpos) = %x", ((op == `SUB) && apos && bpos));
`endif
$display("%m");
end
`endif
endmodule;
/*
wire [31:0] a_plus_b;
sradd ADD (
//`define SRADD_TEST1
`ifdef SRADD_TEST1
// FIXME TEST CODE
// 1 + .707 = 1.707?
.a(32'h3f800000),
.b(32'h3f3504f3),
`else
`ifdef SRADD_TEST2
// FIXME TEST CODE
// 1 + 1 = 2?
.a(32'h3f800000),
.b(32'h3f800000),
`else
.a({a[`sign], a[`exponent], a[`mantissa]}),
.b({a[`sign], b[`exponent], b[`mantissa]}),
`endif
`endif
.z(a_plus_b)
);
*/