-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMouseCursor.vhd
257 lines (233 loc) · 11.1 KB
/
MouseCursor.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
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
------------------------------------------------------------------------
-- mouse_displayer.vhd
------------------------------------------------------------------------
-- Author : Ulrich Zoltán
-- Copyright 2006 Digilent, Inc.
------------------------------------------------------------------------
-- Software version : Xilinx ISE 7.1.04i
-- WebPack
-- Device : 3s200ft256-4
------------------------------------------------------------------------
-- This file contains the implementation of a mouse cursor.
------------------------------------------------------------------------
-- Behavioral description
------------------------------------------------------------------------
-- Mouse position is received from the mouse_controller, horizontal and
-- vertical counters are received from vga_module and if the counters
-- are inside the mouse cursor bounds, then the mouse is sent to the
-- screen instead of the received pixels. The mouse cursor is 16x16
-- pixels and used 2 colors: white and black. For the color encoding
-- 2 bits are used to be able to use transparency. The cursor is stored
-- in a distributed ram memory 256x2bits in dimension. If the current
-- pixel of the mouse is "00" then output color is black, if "01" then
-- white and if "10" or "11" then the pixel is perfectly transparent
-- and the input colors are output. This way, the mouse will not be a
-- 16x16 square and will have an arrow shape.
-- Memory address is composed from the difference of the vga counters
-- and mouse position. xdiff is the difference on 4 bits (because cursor
-- is 16 pixels width) between the horizontal vga counter and the xpos
-- of the mouse. ydiff is the difference on 4 bits (because cursor
-- has 16 pixels in height) between the vertical vga counter and the
-- ypos of the mouse. By concatenating ydiff and xidff (in this order)
-- the memory address of the current pixel is obtained.
-- Distributed memory is forced by the attributes, because the block
-- rams are entirely used for storing images.
-- If blank input from the vga_module is active, this means that current
-- pixel is not inside visible screen and color outputs are set to black
------------------------------------------------------------------------
-- Port definitions
------------------------------------------------------------------------
-- clk - global clock signal (100MHz)
-- pixel_clk - input pin, from pixel_clock_switcher, the clock used
-- - by the vga_controller for the currently used
-- - resolution, generated by a dcm. 25MHz for 640x480
-- - and 40MHz for 800x600. This clock is used to read
-- - pixels from memory and output data on color outputs.
-- xpos - input pin, 10 bits, from mouse_controller
-- - the x position of the mouse relative to the upper
-- - left corner
-- ypos - input pin, 10 bits, from mouse_controller
-- - the y position of the mouse relative to the upper
-- - left corner
-- hcount - input pin, 11 bits, from vga_module
-- - the horizontal counter from the vga_controller
-- - tells the horizontal position of the current pixel
-- - on the screen from left to right.
-- vcount - input pin, 11 bits, from vga_module
-- - the vertical counter from the vga_controller
-- - tells the vertical position of the currentl pixel
-- - on the screen from top to bottom.
-- blank - input pin, from vga_module
-- - if active, current pixel is not in visible area,
-- - and color outputs should be set on 0.
-- red_in - input pin, 4 bits, from effects_layer
-- - red channel input of the image to be displayed
-- green_in - input pin, 4 bits, from effects_layer
-- - green channel input of the image to be displayed
-- blue_in - input pin, 4 bits, from effects_layer
-- - blue channel input of the image to be displayed
-- red_out - output pin, 4 bits, to vga hardware module.
-- - red output channel
-- green_out - output pin, 4 bits, to vga hardware module.
-- - green output channel
-- blue_out - output pin, 4 bits, to vga hardware module.
-- - blue output channel
------------------------------------------------------------------------
-- Revision History:
-- 09/18/2006(UlrichZ): created
-- 10/29/2006(MirceaD): modified for Basys:
-- color busses reduced to 3-3-2 bits
------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- simulation library
library UNISIM;
use UNISIM.VComponents.all;
-- the mouse_displayer entity declaration
-- read above for behavioral description and port definitions.
entity mouse_displayer is
port (
clk : in std_logic;
pixel_clk: in std_logic;
xpos : in std_logic_vector(9 downto 0);
ypos : in std_logic_vector(9 downto 0);
hcount : in std_logic_vector(10 downto 0);
vcount : in std_logic_vector(10 downto 0);
blank : in std_logic;
red_in : in std_logic_vector(3 downto 0);
green_in : in std_logic_vector(3 downto 0);
blue_in : in std_logic_vector(3 downto 0);
red_out : out std_logic_vector(3 downto 0);
green_out: out std_logic_vector(3 downto 0);
blue_out : out std_logic_vector(3 downto 0)
);
-- force synthesizer to extract distributed ram for the
-- displayrom signal, and not a block ram, because the block ram
-- is entirely used to store the image.
attribute rom_extract : string;
attribute rom_extract of mouse_displayer: entity is "yes";
attribute rom_style : string;
attribute rom_style of mouse_displayer: entity is "distributed";
end mouse_displayer;
architecture Behavioral of mouse_displayer is
------------------------------------------------------------------------
-- CONSTANTS
------------------------------------------------------------------------
type displayrom is array(0 to 255) of std_logic_vector(1 downto 0);
-- the memory that holds the cursor.
-- 00 - black
-- 01 - white
-- 1x - transparent
constant mouserom: displayrom := (
"00","00","11","11","11","11","11","11","11","11","11","11","11","11","11","11",
"00","01","00","11","11","11","11","11","11","11","11","11","11","11","11","11",
"00","01","01","00","11","11","11","11","11","11","11","11","11","11","11","11",
"00","01","01","01","00","11","11","11","11","11","11","11","11","11","11","11",
"00","01","01","01","01","00","11","11","11","11","11","11","11","11","11","11",
"00","01","01","01","01","01","00","11","11","11","11","11","11","11","11","11",
"00","01","01","01","01","01","01","00","11","11","11","11","11","11","11","11",
"00","01","01","01","01","01","01","01","00","11","11","11","11","11","11","11",
"00","01","01","01","01","01","00","00","00","00","11","11","11","11","11","11",
"00","01","01","01","01","01","00","11","11","11","11","11","11","11","11","11",
"00","01","00","00","01","01","00","11","11","11","11","11","11","11","11","11",
"00","00","11","11","00","01","01","00","11","11","11","11","11","11","11","11",
"00","11","11","11","00","01","01","00","11","11","11","11","11","11","11","11",
"11","11","11","11","11","00","01","01","00","11","11","11","11","11","11","11",
"11","11","11","11","11","00","01","01","00","11","11","11","11","11","11","11",
"11","11","11","11","11","11","00","00","11","11","11","11","11","11","11","11"
);
-- width and height of cursor.
constant OFFSET: std_logic_vector(4 downto 0) := "10000"; -- 16
------------------------------------------------------------------------
-- SIGNALS
------------------------------------------------------------------------
--signal rompos: std_logic_vector(7 downto 0) := (others => '0');
-- pixel from the display memory, representing currently displayed
-- pixel of the cursor, if the cursor is being display at this point
signal mousepixel: std_logic_vector(1 downto 0) := (others => '0');
-- when high, enables displaying of the cursor, and reading the
-- cursor memory.
signal enable_mouse_display: std_logic := '0';
-- difference in range 0-15 between the vga counters and mouse position
signal xdiff: std_logic_vector(3 downto 0) := (others => '0');
signal ydiff: std_logic_vector(3 downto 0) := (others => '0');
begin
-- compute xdiff
x_diff: process(clk)
variable temp_diff: std_logic_vector(10 downto 0) := (others => '0');
begin
if(rising_edge(clk)) then
temp_diff := hcount - ('0' & xpos);
xdiff <= temp_diff(3 downto 0);
end if;
end process x_diff;
-- compute ydiff
y_diff: process(clk)
variable temp_diff: std_logic_vector(10 downto 0) := (others => '0');
begin
if(rising_edge(clk)) then
temp_diff := vcount - ('0' & ypos);
ydiff <= temp_diff(3 downto 0);
end if;
end process y_diff;
-- read pixel from memory at address obtained by concatenation of
-- ydiff and xdiff
mousepixel <= mouserom(conv_integer(ydiff & xdiff))
when rising_edge(pixel_clk);
-- set enable_mouse_display high if vga counters inside cursor block
enable_mouse: process(pixel_clk)
begin
if(rising_edge(pixel_clk)) then
if(hcount >= xpos and hcount < (xpos + OFFSET) and
vcount >= ypos and vcount < (ypos + OFFSET))
then
enable_mouse_display <= '1';
else
enable_mouse_display <= '0';
end if;
end if;
end process enable_mouse;
-- if cursor display is enabled, then, according to pixel
-- value, set the output color channels.
process(pixel_clk)
begin
if(rising_edge(pixel_clk)) then
-- if in visible screen
if(blank = '0') then
-- in display is enabled
if(enable_mouse_display = '1') then
-- white pixel of cursor
if(mousepixel = "01") then
red_out <= (others => '1');
green_out <= (others => '1');
blue_out <= (others => '1');
-- black pixel of cursor
elsif(mousepixel = "00") then
red_out <= (others => '0');
green_out <= (others => '0');
blue_out <= (others => '0');
-- transparent pixel of cursor
-- let input pass to output
else
red_out <= red_in;
green_out <= green_in;
blue_out <= blue_in;
end if;
-- cursor display is not enabled
-- let input pass to output.
else
red_out <= red_in;
green_out <= green_in;
blue_out <= blue_in;
end if;
-- not in visible screen, black outputs.
else
red_out <= (others => '0');
green_out <= (others => '0');
blue_out <= (others => '0');
end if;
end if;
end process;
end Behavioral;