This repository has been archived by the owner on Jul 12, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
matrix_ledcontrol.vhd
191 lines (170 loc) · 5.76 KB
/
matrix_ledcontrol.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
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.rgbmatrix.all; --config bestand: bevat standaardwaarden en definities voor kleuren voor de matrix.
entity matrix_ledcontrol is
port (
clk_in : in std_logic;
reset : in std_logic;
clk_out : out std_logic;
rgb1_out : out std_logic_vector(2 downto 0);
rgb2_out : out std_logic_vector(2 downto 0);
ledaddr_out : out std_logic_vector(3 downto 0);
lat_out : out std_logic;
oe_out : out std_logic;
addr : out std_logic_vector(ADDR_WIDTH-1 downto 0);
data : in std_logic_vector(DATA_WIDTH-1 downto 0);
readready : out std_logic
);
end matrix_ledcontrol;
architecture behaviour of matrix_ledcontrol is
component matrix_clkdivider is
generic (
in_freq : natural;
out_freq : natural
);
port (
clk_in : in std_logic;
reset : in std_logic;
clk_out : out std_logic
);
end component;
signal devidedclk : std_logic; --gesplitste klok
signal s_clk : std_logic; --klok signal voor matrix
signal rgb1, next_rgb1 : std_logic_vector(2 downto 0); --rgb1
signal rgb2, next_rgb2 : std_logic_vector(2 downto 0); --rgb2
signal ledaddr, next_ledaddr : std_logic_vector(3 downto 0);
signal ramaddr, next_ramaddr : std_logic_vector(ADDR_WIDTH-1 downto 0);
signal column, next_column : unsigned(IMG_WIDTH_LOG2 downto 0);
signal bpp, next_bpp : unsigned(PIXEL_DEPTH-1 downto 0);
signal lat : std_logic;
signal oe : std_logic;
type state_type is (INIT, READ_DATA, SRAMADDR, SLEDADDR, LATCH);
signal state, next_state : state_type;
begin
clock : matrix_clkdivider
generic map (
in_freq => 50000000, --50 MHz
out_freq => 25000000 --25 MHz
)
port map (
reset => reset,
clk_in => clk_in,
clk_out => devidedclk
);
--signals worden aan ports verbonden
clk_out <= s_clk;
rgb1_out <= rgb1;
rgb2_out <= rgb2;
ledaddr_out <= ledaddr;
addr <= ramaddr;
lat_out <= lat;
oe_out <= oe;
process(reset, devidedclk)
begin
if(reset = '1') then
state <= INIT;
column <= (others => '0');
bpp <= (others => '0');
ledaddr <= (others => '1'); --Ledaddr wordt pas gebruikt nadat de waarde is gelatcht. Zodra deze gebruikt wordt, is deze dus 0.
ramaddr <= (others => '0');
rgb1 <= (others => '0');
rgb2 <= (others => '0');
elsif(rising_edge(devidedclk)) then
state <= next_state;
column <= next_column;
bpp <= next_bpp;
ledaddr <= next_ledaddr;
ramaddr <= next_ramaddr;
rgb1 <= next_rgb1;
rgb2 <= next_rgb2;
end if;
end process;
process(state, column, bpp, ledaddr, ramaddr, rgb1, rgb2, data) is
variable upper, lower : unsigned(DATA_WIDTH/2-1 downto 0);
variable upper_r, upper_g, upper_b : unsigned(PIXEL_DEPTH-1 downto 0); --bovenste helft matrix
variable lower_r, lower_g, lower_b : unsigned(PIXEL_DEPTH-1 downto 0); --onderste helft matrix
variable r1, g1, b1, r2, g2, b2 : std_logic;
begin
r1 := '0'; g1 := '0'; b1 := '0'; --startwaarde 0
r2 := '0'; g2 := '0'; b2 := '0'; --startwaarde 0
next_column <= column;
next_bpp <= bpp;
next_ledaddr <= ledaddr;
next_ramaddr <= ramaddr;
next_rgb1 <= rgb1;
next_rgb2 <= rgb2;
s_clk <= '0';
lat <= '0';
oe <= '1'; --active low
readready <= '0';
case state is
when INIT =>
if(ledaddr = "1111") then
if(bpp = unsigned (to_unsigned(-2, PIXEL_DEPTH))) then
next_bpp <= (others => '0');
else
next_bpp <= bpp + 1;
end if;
end if;
next_state <= READ_DATA;
when READ_DATA =>
oe <= '0';
if(upper_r > bpp) then -- als de data een 1 bevat, wordt de desbetreffende bit voor de leds ook 1 gemaakt. Dit herhaalt zich voor alle 6 de bits
r1 := '1';
end if;
if(upper_g > bpp) then
g1 := '1';
end if;
if(upper_b > bpp) then
b1 := '1';
end if;
if(lower_r > bpp) then
r2 := '1';
end if;
if(lower_g > bpp) then
g2 := '1';
end if;
if(lower_b > bpp) then
b2 := '1';
end if;
next_column <= column + 1;
if(column < IMG_WIDTH) then
next_state <= SRAMADDR; --lees volgende adres, nog niet alle leds in de rij gehad
else
next_state <= SLEDADDR; --volgende lijn
end if;
when SRAMADDR =>
s_clk <= '1';
oe <= '0';
next_ramaddr <= std_logic_vector(unsigned(ramaddr)+1); --ga naar volgend adres
readready <= '1';
next_state <= READ_DATA;
when SLEDADDR =>
next_ledaddr <= std_logic_vector(unsigned(ledaddr)+1); --ga naar volgende lijn, latch de waarden
next_column <= (others => '0');
next_state <= LATCH;
when LATCH =>
lat <= '1';
next_state <= INIT;
when others => NULL;
end case;
-- Pixel data is given as 2 combined words, with the upper half containing
-- the upper pixel and the lower half containing the lower pixel. Inside
-- each half the pixel data is encoded in RGB order with multiple repeated
-- bits for each subpixel depending on the chosen color depth. For example,
-- a PIXEL_DEPTH of 3 results in a 18-bit word arranged RRRGGGBBBrrrgggbbb.
-- The following assignments break up this encoding into the human-readable
-- signals used above, or reconstruct it into LED data signals.
upper := unsigned(data(DATA_WIDTH-1 downto DATA_WIDTH/2));--bovenste helft data (47 downto 24)
lower := unsigned(data(DATA_WIDTH/2-1 downto 0)); --onderste helft data (23 downto 0)
upper_r := upper(3*PIXEL_DEPTH-1 downto 2*PIXEL_DEPTH); --47 downto 40
upper_g := upper(2*PIXEL_DEPTH-1 downto PIXEL_DEPTH); --39 downto 32
upper_b := upper( PIXEL_DEPTH-1 downto 0); --31 downto 24
lower_r := lower(3*PIXEL_DEPTH-1 downto 2*PIXEL_DEPTH); --23 downto 16
lower_g := lower(2*PIXEL_DEPTH-1 downto PIXEL_DEPTH); --15 downto 8
lower_b := lower( PIXEL_DEPTH-1 downto 0); -- 7 downto 0
next_rgb1 <= r1 & g1 & b1;
next_rgb2 <= r2 & g2 & b2;
end process;
end architecture;