📄 led_vhdl.vhd
字号:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
library UNISIM;
use UNISIM.VComponents.all;
entity lcd is
Port ( clk,reset : in std_logic; lcd_data : out std_logic_vector (7 downto 0); lcd_en,lcd_rs,lcd_reset,lcd_rw : out std_logic );
end lcd;
architecture lcd_arch of lcd is
signal lcd_we_n : std_logic;signal lcd_en_int : std_logic;signal w_comp_n : std_logic;signal seq_count : std_logic_vector ( 5 downto 0);signal lcd_rs_data : std_logic_vector ( 8 downto 0);signal delay_count : std_logic_vector (21 downto 0);signal lcd_addr : std_logic_vector ( 5 downto 0);type state_lcd_write_type is (lcd_write_idle, lcd_write_1, lcd_write_2, lcd_write_3, lcd_write_4);signal state_lcd_write : state_lcd_write_type;type state_type is (idle, wait_1, wait_2, state_1, state_2, state_3, done);signal state : state_type;begin
lcd_reset <= reset;sequencer_state_register: process (clk, reset) begin if (reset = '0') then state <= idle; elsif (clk'event and clk = '1') then case state is when idle=> if (delay_count(21) = '1') then state <= wait_1; else state <= idle; end if; when wait_1=> if (delay_count(21) = '1') then state <= state_1; else state <= wait_1; end if; when state_1=> state <= state_2; when state_2=> if((w_comp_n = '0')and(lcd_addr = "000110"))then state <= wait_2; elsif(w_comp_n = '0') then state <= wait_1; else state <= state_2; end if;-- The following sections performs the writing of the above message to the LCD -- panel. Similar to the initialization section, a fix delay is inserted between-- 2 LCD writes. The 22-bit counter used in the initialization section is also-- used here to generate the fix delay. when wait_2=> if (delay_count(21)= '1')then state <= state_3; else state <= wait_2; end if; when state_3=> if((w_comp_n = '0')and(lcd_addr = "100111"))then state <= done; elsif(w_comp_n = '0')then state <= wait_2; else state <= state_3; end if; when done=> state <= done; end case; end if;end process sequencer_state_register;-- The following section generates a write enable (lcd_we_n) signal based on the-- state of the above state machine that is used to generate the lcd_en signal.sequencer_state_logic: process (state) begin case state is when idle => lcd_we_n <= '1'; when wait_1 => lcd_we_n <= '1'; when wait_2 => lcd_we_n <= '1'; when state_1=> lcd_we_n <= '0'; when state_2=> lcd_we_n <= '0'; when state_3=> lcd_we_n <= '0'; when done => lcd_we_n <= '1'; end case;end process sequencer_state_logic;-- The following sections uses the lcd_we_n signal to generate the lcd_en signal and-- a write complete signal (w_comp_n). The w_comp_n signal is used to reset various-- counters that are used to generate LCD control signals.state_lcd_write_register: process (clk, reset) begin if (reset = '0') then state_lcd_write <= lcd_write_idle; elsif (clk'event and clk = '1') then case state_lcd_write is when lcd_write_idle=> if (lcd_we_n = '0') then state_lcd_write <= lcd_write_1; else state_lcd_write <= lcd_write_idle; end if; when lcd_write_1=> if (seq_count = "000101")then state_lcd_write <= lcd_write_2; else state_lcd_write <= lcd_write_1; end if; when lcd_write_2=> if (seq_count = "011110")then state_lcd_write <= lcd_write_3; else state_lcd_write <= lcd_write_2; end if; when lcd_write_3=> if (seq_count = "110010")then state_lcd_write <= lcd_write_4; else state_lcd_write <= lcd_write_3; end if; when lcd_write_4=> state_lcd_write <= lcd_write_idle; end case; end if;end process state_lcd_write_register;state_lcd_write_logic: process (state_lcd_write) begin case state_lcd_write is when lcd_write_idle=> lcd_en_int <= '0'; w_comp_n <= '1'; when lcd_write_1 => lcd_en_int <= '0'; w_comp_n <= '1'; when lcd_write_2 => lcd_en_int <= '1'; w_comp_n <= '1'; when lcd_write_3 => lcd_en_int <= '0'; w_comp_n <= '1'; when lcd_write_4 => lcd_en_int <= '0'; w_comp_n <= '0'; end case;end process state_lcd_write_logic;-- The following process provides the LCD initialization data and also the ASCII-- characters needed to write the "Digital Lab Xilinx Spartan3" to the LCD panel. Once,-- the "Digital Lab" is written to the first line of the LCD, hex 0xc0 is written to-- the LCD control register to start at line 2 and write the "Xilinx Spartan3" to the-- LCD panel. The lcd_rs_data consist of the lcd_rs signal (MSB) and 8 bits of data-- (lcd_data).process (lcd_addr) begin case lcd_addr is when "000000" => lcd_rs_data <= "000111000"; -- lcd initializations when "000001" => lcd_rs_data <= "000111000"; when "000010" => lcd_rs_data <= "000000110"; when "000011" => lcd_rs_data <= "000001110"; when "000100" => lcd_rs_data <= "000000001"; when "000101" => lcd_rs_data <= "010000000"; when "000110" => lcd_rs_data <= "000001100"; when "000111" => lcd_rs_data <= "100100000"; -- lcd first line, "DIGITAL LAB" when "001000" => lcd_rs_data <= "100100000"; when "001001" => lcd_rs_data <= "101000100"; --D when "001010" => lcd_rs_data <= "101001001"; --I when "001011" => lcd_rs_data <= "101000111"; --G when "001100" => lcd_rs_data <= "101001001"; --I when "001101" => lcd_rs_data <= "101010100"; --T when "001110" => lcd_rs_data <= "101000001"; --A when "001111" => lcd_rs_data <= "101001100"; --L when "010000" => lcd_rs_data <= "100100000"; when "010001" => lcd_rs_data <= "101001100"; --L when "010010" => lcd_rs_data <= "101000001"; --A when "010011" => lcd_rs_data <= "101000010"; --B when "010100" => lcd_rs_data <= "100100000"; when "010101" => lcd_rs_data <= "100100000"; when "010110" => lcd_rs_data <= "100100000"; when "010111" => lcd_rs_data <= "011000000"; -- start at lcd second line when "011000" => lcd_rs_data <= "101011000"; --X -- lcd second line, "Xilinx Spartan3" when "011001" => lcd_rs_data <= "101001001"; --I when "011010" => lcd_rs_data <= "101001100"; --L when "011011" => lcd_rs_data <= "101001001"; --I when "011100" => lcd_rs_data <= "101001110"; --N when "011101" => lcd_rs_data <= "101011000"; --X when "011110" => lcd_rs_data <= "100100000"; when "011111" => lcd_rs_data <= "101010011"; --S when "100000" => lcd_rs_data <= "101010000"; --P when "100001" => lcd_rs_data <= "101000001"; --A when "100010" => lcd_rs_data <= "101010010"; --R when "100011" => lcd_rs_data <= "101010100"; --T when "100100" => lcd_rs_data <= "101000001"; --A when "100101" => lcd_rs_data <= "101001110"; --N when "100110" => lcd_rs_data <= "100110011"; --3 when "100111" => lcd_rs_data <= "100100000"; when others => lcd_rs_data <= "111111111"; end case;end process;-- The following is a 22-bit free running counter that is cleared when the reset-- signal is asserted or the MSB of the counter goes to 1. This counter is used-- to generate delays between back-to-back writes to the LCD panel during the -- initialization and also normal write cycles. process (clk) begin if (clk'event and clk = '1') then if ((reset = '0') or (delay_count(21) = '1')) then delay_count <= (others => '0'); else delay_count <= delay_count + 1; end if; end if; end process;-- The following counter is used by the sequencer to generate the lcd_en signal.-- The counter is reset at the end of each write to the LCD when the w_comp_n-- signal goes active. process (clk) begin if (clk'event and clk = '1') then if((reset='0')or(w_comp_n='0'))then seq_count<=(others=>'0'); elsif (lcd_we_n = '0') then seq_count<=seq_count + 1; end if; end if; end process;-- The following block generates the address pointer to the LCD initialization and-- data values. The counter is incremented at the end of each write to the LCD panel-- when the w_comp_n signal goes active.process (clk) begin if (clk'event and clk = '1') then if (reset = '0') then lcd_addr<=(others => '0'); elsif(w_comp_n='0')then lcd_addr<=lcd_addr + 1; end if; end if;end process;-- The following sections define the LCD data and control signals. For this reference-- design, the lcd_rw signal is set to "0" forcing all LCD accesses to be write cycles. lcd_data <= lcd_rs_data(7 downto 0); lcd_en <= lcd_en_int; lcd_rs <= lcd_rs_data(8); lcd_rw <= '0';end lcd_arch;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -