-
Notifications
You must be signed in to change notification settings - Fork 0
/
FPGA_Dithering.vhd
184 lines (167 loc) · 5.58 KB
/
FPGA_Dithering.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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.VgaUtils.all;
use work.Pixel.all;
entity FPGA_Dithering is
port (
clk : in STD_LOGIC; -- Pin 23, 50MHz from the onboard oscillator.
rgb : out STD_LOGIC_VECTOR (2 downto 0); -- Pins 106, 105 and 104
hsync : out STD_LOGIC; -- Pin 101
vsync : out STD_LOGIC -- Pin 103
);
end entity FPGA_Dithering;
architecture rtl of FPGA_Dithering is
-- VGA Clock - 25 MHz clock derived from the 50MHz built-in clock
signal vga_clk : STD_LOGIC;
signal vga_hsync, vga_vsync : STD_LOGIC;
signal display_enable : STD_LOGIC;
signal dithered_red_pixel, dithered_green_pixel, dithered_blue_pixel : STD_LOGIC;
signal rgb_output : STD_LOGIC_VECTOR (2 downto 0);
signal column, row : INTEGER;
signal pixel : pixel_type;
component ImageLoader is
generic (
init_file : in STRING;
image_width : in INTEGER;
image_height : in INTEGER;
memory_size : INTEGER;
address_width : INTEGER
);
port (
clk : in STD_LOGIC;
column : in INTEGER;
row : in INTEGER;
pixel : out pixel_type
);
end component;
component RgbImageLoader is
generic (
init_file : in STRING;
image_width : in INTEGER;
image_height : in INTEGER;
memory_size : INTEGER;
address_width : INTEGER
);
port (
clk : in STD_LOGIC;
column : in INTEGER;
row : in INTEGER;
pixel : out pixel_type
);
end component;
component VgaController is
generic (
h_pulse : INTEGER := 208; --horizontal sync pulse width in pixels
h_bp : INTEGER := 336; --horizontal back porch width in pixels
h_pixels : INTEGER := 1920; --horizontal display width in pixels
h_fp : INTEGER := 128; --horizontal front porch width in pixels
h_pol : STD_LOGIC := '0'; --horizontal sync pulse polarity (1 = positive, 0 = negative)
v_pulse : INTEGER := 3; --vertical sync pulse width in rows
v_bp : INTEGER := 38; --vertical back porch width in rows
v_pixels : INTEGER := 1200; --vertical display width in rows
v_fp : INTEGER := 1; --vertical front porch width in rows
v_pol : STD_LOGIC := '1'); --vertical sync pulse polarity (1 = positive, 0 = negative)
port (
pixel_clk : in STD_LOGIC; --pixel clock at frequency of VGA mode being used
reset_n : in STD_LOGIC; --active low asynchronous reset
h_sync : out STD_LOGIC; --horizontal sync pulse
v_sync : out STD_LOGIC; --vertical sync pulse
disp_ena : out STD_LOGIC; --display enable ('1' = display time, '0' = blanking time)
column : out INTEGER; --horizontal pixel coordinate
row : out INTEGER; --vertical pixel coordinate
n_blank : out STD_LOGIC; --direct blacking output to DAC
n_sync : out STD_LOGIC); --sync-on-green output to DAC
end component;
component OrderedDitherer is
port (
pixel : in STD_LOGIC_VECTOR(7 downto 0);
row : in INTEGER;
column : in INTEGER;
dithered_pixel : out STD_LOGIC
);
end component;
begin
-- img_gray : ImageLoader
-- generic map(
-- init_file => "./images/jardim_botanico_gray.mif",
-- image_height => 136,
-- image_width => 202,
-- memory_size => 27472,
-- address_width => 15
-- )
-- port map(
-- clk => clk,
-- column => column,
-- row => row,
-- pixel => pixel
-- );
img_color : RgbImageLoader
generic map(
init_file => "./images/jardim_botanico.mif",
image_height => 78,
image_width => 116,
memory_size => 9048,
address_width => 14
)
port map(
clk => clk,
column => column,
row => row,
pixel => pixel
);
vga_controller : VgaController generic map(
h_pulse => H_SYNC_PULSE,
h_bp => H_BACK_PORCH,
h_pixels => H_PIXELS,
h_fp => H_FRONT_PORCH,
h_pol => H_SYNC_POLARITY,
v_pulse => V_SYNC_PULSE,
v_bp => V_BACK_PORCH,
v_pixels => V_PIXELS,
v_fp => V_FRONT_PORCH,
v_pol => V_SYNC_POLARITY
)
port map(
pixel_clk => vga_clk,
reset_n => '1',
h_sync => vga_hsync,
v_sync => vga_vsync,
disp_ena => display_enable,
column => column,
row => row
);
red_ditherer : OrderedDitherer port map(
pixel => pixel.red,
row => row,
column => column,
dithered_pixel => dithered_red_pixel
);
green_ditherer : OrderedDitherer port map(
pixel => pixel.green,
row => row,
column => column,
dithered_pixel => dithered_green_pixel
);
blue_ditherer : OrderedDitherer port map(
pixel => pixel.blue,
row => row,
column => column,
dithered_pixel => dithered_blue_pixel
);
rgb_output(0) <= dithered_red_pixel;
rgb_output(1) <= dithered_green_pixel;
rgb_output(2) <= dithered_blue_pixel;
rgb <=
rgb_output when display_enable = '1' else
"000";
hsync <= vga_hsync;
vsync <= vga_vsync;
-- We need 25MHz for the VGA so we divide the input clock by 2
process (clk)
begin
if (rising_edge(clk)) then
vga_clk <= not vga_clk;
end if;
end process;
end architecture;