muh
[calu.git] / cpu / src / extension_lcd_b_8.vhd
1 library IEEE;
2 use IEEE.std_logic_1164.all;
3 use IEEE.numeric_std.all;
4 use IEEE.STD_LOGIC_ARITH.ALL;
5 use IEEE.STD_LOGIC_UNSIGNED.ALL;
6
7 use work.common_pkg.all;
8 use work.core_pkg.all;
9
10
11 use work.mem_pkg.all;
12 use work.extension_pkg.all;
13 use work.extension_lcd_pkg_8.all;
14
15 architecture behav of extension_lcd_8 is
16
17 constant CLK_Divide : integer := 16;
18
19 signal w1_st_co, w1_st_co_nxt, w2_im_val, w2_im_val_nxt : gp_register_t;
20 signal w3_im_notused, w3_im_notused_nxt, w4_im_notused, w4_im_notused_nxt : gp_register_t;
21
22 signal lcd_count, lcd_count_nxt : integer := 0;
23 signal lcd_st, lcd_st_nxt : std_logic_vector(1 downto 0);
24 signal lcd_preStart, lcd_preStart_nxt, lcd_mStart, lcd_mStart_nxt, lcd_done, lcd_done_nxt : std_logic;
25 signal lcd_en_int, lcd_en_nxt, lcd_start, lcd_start_nxt : std_logic;
26
27
28 signal lcd_rom_addr, lcd_rom_addr_nxt : std_logic_vector(2 downto 0);
29 signal lcd_rom_data : std_logic_vector(11 downto 0); -- eigentlich 8 downto 0, aber vhdl < 2008 kann 
30 --keine laenge von bits bei hex angeben und binaer suckt
31
32 type LCD_SETUP_STATE_TYPE is (SEND_DATA, WAIT_DONE, DO_WAIT, FETCH_NEW);
33 signal lcd_set_st, lcd_set_st_nxt : LCD_SETUP_STATE_TYPE;
34 signal lcd_set_delay, lcd_set_delay_nxt : std_logic_vector(17 downto 0);
35
36 begin
37
38
39 LCD_ON <= '1';
40 LCD_BLON <= '1';
41 LCD_RW <= '0';
42
43 LCD_EN <= lcd_en_int;
44
45 LCD_DATA <= lcd_rom_data(7 downto 0);
46 LCD_RS <= lcd_rom_data(8);
47
48 syn : process (clk, reset)
49 begin
50    if (reset = RESET_VALUE) then
51                 w1_st_co <= (others => '0');
52                 w2_im_val <= (others => '0');
53                 w3_im_notused <= (others => '0');
54                 w4_im_notused <= (others => '0');
55                 
56                 --lcd ctrl
57                 lcd_en_int <= '0';
58                 lcd_st <= "00";
59                 lcd_done <= '0';
60                 lcd_preStart <= '0';
61                 lcd_start <= '0';
62                 lcd_mStart <= '0';
63                 lcd_count <= 0;
64                 
65                 --lcd_setup
66                 lcd_rom_addr <= (others => '0');
67                 lcd_set_st <= SEND_DATA;
68                 lcd_set_delay <= (others => '0');
69                 
70         elsif rising_edge(clk) then
71                 w1_st_co <= w1_st_co_nxt;
72                 w2_im_val <= w2_im_val_nxt;
73                 w3_im_notused <= w3_im_notused_nxt;
74                 w4_im_notused <= w4_im_notused_nxt;
75                 
76                 --lcd ctrl
77                 lcd_en_int <= lcd_en_nxt;
78                 lcd_st <= lcd_st_nxt;
79                 lcd_done <= lcd_done_nxt;
80                 lcd_preStart <= lcd_preStart_nxt;
81                 lcd_start <= lcd_start_nxt;
82                 lcd_mStart <= lcd_mStart_nxt;
83                 lcd_count <= lcd_count_nxt;
84
85                 --lcd setup
86                 lcd_rom_addr <= lcd_rom_addr_nxt;
87                 lcd_set_st <= lcd_set_st_nxt;
88                 lcd_set_delay <= lcd_set_delay_nxt;
89                 
90         
91    end if;
92 end process syn;
93
94 -------------------------- LESEN UND SCHREIBEN ANFANG ------------------------------------------------------------
95
96 gwriten : process (ext_reg, w1_st_co, w2_im_val, w3_im_notused, w4_im_notused)
97 variable tmp_data : gp_register_t;
98 begin
99         w1_st_co_nxt <= w1_st_co;
100         w2_im_val_nxt <= w2_im_val;
101         w3_im_notused_nxt <= w3_im_notused;
102         w4_im_notused_nxt <= w4_im_notused;
103
104         -- timer logic
105         if (w1_st_co(0) = '1') then -- timer enabled?
106                 w2_im_val_nxt <= std_logic_vector(IEEE.numeric_std.unsigned(w2_im_val) + 1);
107                 -- n00b overflow (logic elements sparen...)
108                 if(w2_im_val(31) = '1') then 
109                         w1_st_co_nxt(16) <= '1';
110                 end if;
111         end if;
112
113         if ext_reg.sel = '1' and ext_reg.wr_en = '1' then
114                 tmp_data := (others =>'0');                     
115                 for i in 0 to 3 loop
116                         if ext_reg.byte_en(i) = '1' then
117                                 tmp_data(((i+1)*byte_t'length-1) downto i*byte_t'length) := ext_reg.data(((i+1)*byte_t'length-1) downto i*byte_t'length);
118                         end if;
119                 end loop;
120
121                 case ext_reg.addr(1 downto 0) is
122                 when "00" => -- status/config
123                         w1_st_co_nxt <= tmp_data;
124                 when "01" => -- timer value
125                         w2_im_val_nxt <= tmp_data;
126                 when "10" => null;
127                 when "11" => null;
128                 when others => null;
129                 end case;
130         end if;
131 end process gwriten;
132
133 gread : process (clk, ext_reg, w1_st_co, w2_im_val, w3_im_notused, w4_im_notused)
134 variable tmp_data : gp_register_t;
135 begin
136         tmp_data := (others => '0');
137         if ext_reg.sel = '1' and ext_reg.wr_en = '0' then
138                 case ext_reg.addr(1 downto 0) is
139                 when "00" => put_word_be(tmp_data, w1_st_co, ext_reg.byte_en);
140                 when "01" => put_word_be(tmp_data, w2_im_val, ext_reg.byte_en);
141                 when "10" => put_word_be(tmp_data, w3_im_notused, ext_reg.byte_en);
142                 when "11" => put_word_be(tmp_data, w4_im_notused, ext_reg.byte_en);
143                 when others => null;
144                 end case;
145         end if;
146         data_out <= tmp_data;
147 end process gread;
148
149
150
151 lcd_setup : process(clk, lcd_set_st, lcd_start, lcd_set_delay, lcd_rom_addr, lcd_done)
152 begin
153         lcd_set_st_nxt <= lcd_set_st;
154         lcd_start_nxt <= lcd_start;
155         lcd_set_delay_nxt <= lcd_set_delay;
156         lcd_rom_addr_nxt <= lcd_rom_addr;
157         
158         if lcd_rom_addr < "101000" then
159                 case lcd_set_st is
160                         when SEND_DATA =>
161                                 lcd_start_nxt <= '1';
162                                 lcd_set_st_nxt <= WAIT_DONE;
163
164                         when WAIT_DONE =>
165                                 if lcd_done = '1' then
166                                         lcd_set_st_nxt <= DO_WAIT;
167                                         lcd_start_nxt <= '0';
168                                 end if;
169
170                         when DO_WAIT =>
171                                 if lcd_set_delay < x"3fffe" then
172                                         lcd_set_delay_nxt <= lcd_set_delay + 1;
173                                 else
174                                         lcd_set_delay_nxt <= (others => '0');
175                                         lcd_set_st_nxt <= FETCH_NEW;
176                                 end if;
177
178                         when FETCH_NEW =>
179                                 lcd_rom_addr_nxt <= lcd_rom_addr + 1;
180                                 lcd_set_st_nxt <= SEND_DATA;
181                 end case;
182         end if;
183                 
184 end process lcd_setup;
185
186 lcd_ctrl : process(clk, lcd_en_int, lcd_count, lcd_mStart, lcd_start, lcd_done, lcd_preStart, lcd_st)
187 begin
188         lcd_en_nxt <= lcd_en_int;
189         lcd_count_nxt <= lcd_count;
190         lcd_mStart_nxt <= lcd_mStart;
191         
192         lcd_preStart_nxt <= lcd_start;
193         lcd_done_nxt <= lcd_done;
194         
195         --start detection
196         if lcd_preStart = '0' and lcd_start = '1' then
197                 lcd_mStart_nxt <= '1';
198                 lcd_done_nxt <= '0';
199         end if;
200         lcd_st_nxt <= lcd_st;
201         case lcd_st is
202                 when "00" =>
203                         if  lcd_mStart = '1' then
204                                 lcd_st_nxt <= "01"; -- wait setup
205                         else
206                                 lcd_st_nxt <= "00";
207                         end if;
208                 when "01" =>
209                         lcd_en_nxt <= '1';
210                         lcd_st_nxt <= "10";
211                 when "10" =>
212                         if(lcd_count < CLK_Divide) then
213                                 lcd_count_nxt <= lcd_count+1;
214                         else
215                                 lcd_st_nxt <= "11";
216                         end if;
217                 when "11" =>
218                         lcd_en_nxt <= '0';
219                         lcd_mStart_nxt <= '0';
220                         lcd_done_nxt  <= '1';
221                         lcd_count_nxt <= 0;
222                         lcd_st_nxt <= "00";
223         end case;
224
225
226 end process lcd_ctrl;
227
228 lcd_data_rom : process(lcd_rom_addr)
229 begin
230         case lcd_rom_addr is
231                 --init of display
232                 when "000" => lcd_rom_data <= x"038";
233                 when "001" => lcd_rom_data <= x"00c";
234                 when "010" => lcd_rom_data <= x"038";
235                 when "011" => lcd_rom_data <= x"00c";
236                 when "100" => lcd_rom_data <= x"001";
237                 when "101" => lcd_rom_data <= x"006";
238                 when "110" => lcd_rom_data <= x"080";
239                 when others => lcd_rom_data <= x"0b0"; --goto 0,0
240                 --      Line 1
241                 --when "000111" => lcd_rom_data <= x"120";      --      Welcome to the
242                 --when "001000" => lcd_rom_data <= x"13C";
243                 --when "001001" => lcd_rom_data <= x"133";
244                 
245                 --when "010110" => lcd_rom_data <= x"120";
246                 --      Change Line
247                 --when "010111" => lcd_rom_data <= x"0c0";
248                 --      Line 2
249                 --when "011000" => lcd_rom_data <= x"120";      --      Altera DE2-70
250                 --when "011001" => lcd_rom_data <= x"141";      
251                 --when "011010" => lcd_rom_data <= x"085"; --back to upper line + forward
252                 --when "011011" => lcd_rom_data <= x"174";
253 --              when "011100" => lcd_rom_data <= x"165";
254 --              when "011101" => lcd_rom_data <= x"172";
255 --              when "011110" => lcd_rom_data <= x"161";
256 --              when "011111" => lcd_rom_data <= x"120";
257 --              when "100000" => lcd_rom_data <= x"144";
258 --              when "100010" => lcd_rom_data <= x"145";
259 --              when "100011" => lcd_rom_data <= x"132";
260 --              when "100100" => lcd_rom_data <= x"1b0";
261 --              when "100101" => lcd_rom_data <= x"131";
262 --              when "100110" => lcd_rom_data <= x"131";
263 --              when "100111" => lcd_rom_data <= x"135";
264 --              when "101000" => lcd_rom_data <= x"120";
265 --              when others => lcd_rom_data <= x"120";
266         end case;
267 end process lcd_data_rom;
268
269
270 -------------------------- LESEN UND SCHREIBEN ENDE ---------------------------------------------------------------
271 -------------------------- INTERNE VERARBEITUNG ANFANG ------------------------------------------------------------
272 -------------------------- INTERNE VERARBEITUNG ENDE --------------------------------------------------------------
273 end behav;