-
Notifications
You must be signed in to change notification settings - Fork 0
/
fixed_point_arithmetic.v
113 lines (94 loc) · 3.01 KB
/
fixed_point_arithmetic.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
`timescale 1ns/1ns
module int_fixed_point_mult_int
(
input signed [20:0] int_in,
input signed [9:0] fixed_X,
input signed [17:0] fixed_Y,
output reg signed [20:0] int_out
);
// here fixed_Y must be the binary representation of the integer to the right of the decimal point
// accuracy of fixed point value is assumed to be 5 d.p. so divide by 10^5
always @(*)
begin
if (fixed_X == 256)
int_out <= int_in * 0 - ((int_in * fixed_Y)/ 100000);
else if (fixed_X <0)
int_out <= int_in * fixed_X - ((int_in * fixed_Y)/ 100000);
else
int_out <= int_in * fixed_X + ((int_in * fixed_Y) / 100000);
end
endmodule
module int_fixed_point_div_int
(
input signed [20:0] int_in,
input signed [9:0] fixed_X,
input signed [17:0] fixed_Y,
output reg signed [20:0] int_out
);
always @(*)
begin
if (fixed_X == 10'b0 && fixed_Y == 18'b0)
int_out <= 21'b011111111111111111111; // incredibly high positive value
else if (fixed_X <0 && int_in >=0)
int_out <= (int_in * 100000)/ (fixed_X * 100000 - fixed_Y);
else if (fixed_X == 256)
int_out <= ((int_in * 100000)/ (-fixed_Y));
else if (fixed_X <0 && int_in <0)
int_out <= (-int_in * 100000)/ (-fixed_X * 100000 + fixed_Y);
else
int_out <= (int_in * 100000)/ (fixed_X * 100000 + fixed_Y);
end
endmodule
// this module only to count through slices for a single frame
// int_in can be a max of 160 (8 bits), and both the int and fixed_point are positive, so no signed values required
// fixed point value is 0.375 at 160x120 resolution
// fixed_X_out can take a max value of 60 (field of view)
module int_fixed_point_mult_fixed_point
(
input [7:0] int_in,
input fixed_X,
input [9:0] fixed_Y,
output reg [5:0] fixed_X_out,
output reg [9:0] fixed_Y_out
);
// assuming here a 3 d.p. accuracy since all multiples of 0.375 can be represnted perfectly by 3 digit integers
// on the right
always @(*)
begin
fixed_X_out <= (int_in * fixed_X) + $floor((int_in * fixed_Y) / 1000);
fixed_Y_out <= ((int_in * fixed_Y) >= (1000*fixed_X_out)) ? ((int_in * fixed_Y) -(1000*fixed_X_out)) : (int_in*fixed_Y);
end
endmodule
module fixed_point_subtract_fixed_point
(
input [9:0] fixed_X_in_1,
input [9:0] fixed_Y_in_1,
input [9:0] fixed_X_in_2,
input [9:0] fixed_Y_in_2,
output reg signed [9:0] fixed_X_out,
output reg signed [9:0] fixed_Y_out
);
always @(*)
begin
if (((fixed_Y_in_2) > (fixed_Y_in_1)) ) begin
if ((fixed_X_in_1) < (fixed_X_in_2)) begin
fixed_X_out <= ((fixed_X_in_1) - fixed_X_in_2);
fixed_Y_out <= ((fixed_Y_in_2) - fixed_Y_in_1);
end
else begin
fixed_X_out <= ((fixed_X_in_1-1) - fixed_X_in_2);
fixed_Y_out <= (( 1000- fixed_Y_in_2) + fixed_Y_in_1);
end
end
else begin
if ((fixed_X_in_1) < (fixed_X_in_2)) begin
fixed_X_out <= ((fixed_X_in_1 +1) - fixed_X_in_2);
fixed_Y_out <= ( (1000- fixed_Y_in_1) + fixed_Y_in_2);
end
else begin
fixed_X_out <= fixed_X_in_1 - fixed_X_in_2;
fixed_Y_out <= fixed_Y_in_1 - fixed_Y_in_2;
end
end
end
endmodule