-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathMandelbrot.vhd
122 lines (100 loc) · 4.34 KB
/
Mandelbrot.vhd
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
------------------------------------------------------------------
-- This is my simple "direct-to-VHDL" translation
-- of a Mandelbrot fractal computing engine.
------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
library ieee_proposed;
use ieee_proposed.fixed_pkg.all;
use work.custom_fixed_point_types.all;
entity Mandelbrot is
port (
CLK : in std_logic;
RST : in std_logic;
-- These are the input coordinates on the complex plane
-- for which the computation will take place.
input_x, input_y : in std_logic_vector(31 downto 0);
-- When this is pulsed once (0->1->0) the engine "wakes up" and
-- starts computing the output color.
startWorking : in std_logic;
-- When it concludes computing, it stores the result here...
OutputNumber : out std_logic_vector(7 downto 0);
-- ...and raises this ; to signal completion.
finishedWorking : out std_logic
);
end Mandelbrot;
architecture arch of Mandelbrot is
-- The simple state machine:
type state_type is (
receiving_input, -- waiting for input_x and input_y to arrive
comp_stage1, -- calculating x^2, y^2 and x*y
comp_stage2, -- calculating 2*x*y and x^2+y^2
comp_stage3, -- checking if magnitute > 4.0
comp_stage4, -- newx = x^2 - y^2 + input_x, newy = 2*x*y + input_y
computed
);
signal state : state_type;
-- the local variables needed for the algorithm
signal input_x_sfixed, input_y_sfixed : custom_fixed_point_type;
signal x_mandel, y_mandel : custom_fixed_point_type;
signal x_mandel_sq, y_mandel_sq : custom_fixed_point_type;
signal x_mandel_times_y_mandel, magnitude : custom_fixed_point_type;
signal pixel_color : unsigned(7 downto 0);
begin
process (RST, CLK)
begin
if (RST='1') then
OutputNumber <= X"00";
finishedWorking <= '0';
state <= receiving_input;
elsif rising_edge(CLK) then
case state is
when receiving_input =>
finishedWorking <= '0';
if startWorking = '1' then
input_x_sfixed <= to_sfixed_custom(input_x);
input_y_sfixed <= to_sfixed_custom(input_y);
x_mandel <= to_sfixed_custom(0.0);
y_mandel <= to_sfixed_custom(0.0);
pixel_color <= X"00";
state <= comp_stage1;
else
state <= receiving_input;
end if;
when comp_stage1 =>
if pixel_color(7) /= '0' then
state <= computed;
else
x_mandel_times_y_mandel <= resize(
x_mandel*y_mandel, x_mandel_times_y_mandel);
x_mandel_sq <= resize(x_mandel*x_mandel, x_mandel_sq);
y_mandel_sq <= resize(y_mandel*y_mandel, y_mandel_sq);
state <= comp_stage2;
end if;
when comp_stage2 =>
magnitude <= resize(x_mandel_sq + y_mandel_sq, magnitude);
x_mandel_times_y_mandel <= x_mandel_times_y_mandel sll 1;
state <= comp_stage3;
when comp_stage3 =>
if to_slv(magnitude)(31 downto 29) /= "000" then
state <= computed;
else
state <= comp_stage4;
end if;
when comp_stage4 =>
pixel_color <= pixel_color + 1;
x_mandel <= resize(
x_mandel_sq - y_mandel_sq + input_x_sfixed, x_mandel);
y_mandel <= resize(
x_mandel_times_y_mandel + input_y_sfixed, y_mandel);
state <= comp_stage1;
when computed =>
OutputNumber <= std_logic_vector(pixel_color);
finishedWorking <= '1';
state <= receiving_input;
end case; -- case state is ...
end if; -- if rising_edge(CLK) ...
end process;
end arch;