Reputation: 37
I am new to dealing with using COMPONENTS in VHDL and I understand how to port map simple things like slowing down a clock, however I have built a sequence dtetctor that seems to work well, but I want to have its' output trigger an input in my LCD write program and display to my LCD screen. How can I port map only the one signal over, or is there a better way of thinking about using the COMPONENT that I'm not thinking of?
How do i do direct entity instantiation? Could I use that here? I have been trying different ways to make my output Z be the input for the LCD on enable_0 but cant figure out how to not mess with all the other ports on that entity.
Thanks all
Matt
--Sequence detector(Mealy Machine-resetting)
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY Sequence_Detector IS PORT(
X : IN STD_LOGIC_VECTOR(8 DOWNTO 0);
CLK, LOAD: IN STD_LOGIC;
LED : OUT STD_LOGIC_VECTOR(17 DOWNTO 0);
Z: INOUT STD_LOGIC_VECTOR(1 DOWNTO 0));
END ENTITY;
ARCHITECTURE BEH OF Sequence_Detector IS
TYPE state_type is (S0,S1,S2,S3,S4,S5,S6,S7,S8);
SIGNAL TMP : STD_LOGIC_VECTOR(8 DOWNTO 0);
SIGNAL clkout : STD_LOGIC;
SIGNAL state : state_type;
COMPONENT slowclk PORT(
clk : IN STD_LOGIC;
clkout : OUT STD_LOGIC);
END COMPONENT;
BEGIN
LED(17) <= LOAD;
LED(8 DOWNTO 0) <= X;
TMP <= X;
state0: slowclk PORT MAP (clk, clkout);
PROCESS (CLK)
BEGIN
IF (LOAD = '1') THEN
IF (clkout'EVENT AND clkout = '1') THEN
CASE state IS
WHEN S0 =>
IF X(8) = '0' THEN
state <= S0; --1--
Z <= "00";
ELSE
state <= S1;
Z <= "00";
END IF;
WHEN S1 =>
IF X(7) = '0' THEN
state <= S0; --1--
Z <= "00";
ELSE
state <= S2;
Z <= "00";
END IF;
WHEN S2 =>
IF X(6) = '0' THEN
state <= S3; --0--
Z <= "00";
ELSE
state <= S2;
Z <= "00";
END IF;
WHEN S3 =>
IF X(5) = '0' THEN
state <= S0; --1--
Z <= "00";
ELSE
state <= S4;
Z <= "00";
END IF;
WHEN S4 =>
IF X(4) = '0' THEN
state <= S5; --0--
Z <= "00";
ELSE
state <= S2;
Z <= "00";
END IF;
WHEN S5 =>
IF X(3) = '0' THEN
state <= S6; --0--
Z <= "00";
ELSE
state <= S0;
Z <= "00";
END IF;
WHEN S6 =>
IF X(2) = '0' THEN
state <= S0; --1--
Z <= "00";
ELSE
state <= S7;
Z <= "00";
END IF;
WHEN S7 =>
IF X(1) = '0' THEN
state <= S0; --1--
Z <= "00";
ELSE
state <= S8;
Z <= "00";
END IF;
WHEN S8 =>
IF X(0) = '0' THEN
state <= S0; --0--
Z <= "11";
ELSE
state <= S2;
Z <= "01";
END IF;
END CASE;
END IF;
END IF;
END PROCESS;
END BEH;
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
ENTITY slowclk IS PORT(
clk : IN STD_LOGIC;
clkout : OUT STD_LOGIC);
END slowclk;
ARCHITECTURE ckt OF slowclk IS
BEGIN
PROCESS(clk)
VARIABLE cnt : INTEGER RANGE 0 TO 50000000;
BEGIN
IF clk'EVENT AND clk='1' THEN
IF cnt=50000000 THEN
cnt:=0;
clkout<='1';
ELSE
cnt:=cnt+1;
clkout<='0';
END IF;
END IF;
END PROCESS;
END ckt;
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.all;
USE IEEE.STD_LOGIC_ARITH.all;
USE IEEE.STD_LOGIC_UNSIGNED.all;
ENTITY LCD IS
-------------------------------------------------------------------
-- ASCII HEX TABLE
-- Hex Low Hex Digit
-- Value 0 1 2 3 4 5 6 7 8 9 A B C D E F
------\----------------------------------------------------------------
--H 2 | SP ! " # $ % & ' ( ) * + , - . /
--i 3 | 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
--g 4 | @ A B C D E F G H I J K L M N O
--h 5 | P Q R S T U V W X Y Z [ \ ] ^ _
-- 6 | ` a b c d e f g h i j k l m n o
-- 7 | p q r s t u v w x y z { | } ~ DEL
-----------------------------------------------------------------------
PORT(
reset, CLOCK_50 : IN STD_LOGIC;
enable_0 : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
enable_1 : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
LCD_RS, LCD_E : OUT STD_LOGIC;
LCD_RW : OUT STD_LOGIC;
LCD_ON : OUT STD_LOGIC;
LCD_BLON : OUT STD_LOGIC;
DATA_BUS : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END ENTITY;
ARCHITECTURE Behavior OF LCD IS
TYPE character_string IS ARRAY ( 0 TO 31 ) OF STD_LOGIC_VECTOR( 7 DOWNTO 0 );
TYPE STATE_TYPE IS (HOLD, FUNC_SET, DISPLAY_ON, MODE_SET, Print_String,
LINE2, RETURN_HOME, DROP_LCD_E, RESET1, RESET2,
RESET3, DISPLAY_OFF, DISPLAY_CLEAR);
SIGNAL state, next_command : STATE_TYPE;
SIGNAL LCD_display_string : character_string;
SIGNAL DATA_BUS_VALUE, Next_Char : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL CLK_COUNT_400HZ : STD_LOGIC_VECTOR(19 DOWNTO 0);
SIGNAL CHAR_COUNT : STD_LOGIC_VECTOR(4 DOWNTO 0);
SIGNAL CLK_400HZ_Enable,LCD_RW_INT : STD_LOGIC;
SIGNAL Line1_chars, Line2_chars : STD_LOGIC_VECTOR(127 DOWNTO 0);
BEGIN
LCD_ON <= '1';
LCD_BLON <= '1';
PROCESS (clock_50)
BEGIN
CASE(enable_0) IS
--passed--
WHEN "11" => LCD_display_string <= (
X"53",X"65",X"71",X"75",X"65",X"6E",X"63",X"65",X"20",X"50",X"61",X"73",X"73",X"65",X"64",X"20",
X"4D",X"61",X"74",X"74",X"68",X"65",X"77",X"20",X"41",X"6E",X"64",X"65",X"72",X"73",X"6F",X"6E");
WHEN "10" => LCD_display_string <= (
X"20",X"20",X"20",X"20",X"45",X"45",X"43",X"45",X"20",X"33",X"34",X"33",X"20",X"20",X"20",X"20",
X"4D",X"61",X"74",X"74",X"68",X"65",X"77",X"20",X"41",X"6E",X"64",X"65",X"72",X"73",X"6F",X"6E");
--failed--
WHEN "01" => LCD_display_string <= (
X"53",X"65",X"71",X"75",X"65",X"6E",X"63",X"65",X"20",X"46",X"61",X"69",X"6C",X"65",X"64",X"20",
X"4D",X"61",X"74",X"74",X"68",X"65",X"77",X"20",X"41",X"6E",X"64",X"65",X"72",X"73",X"6F",X"6E");
WHEN "00" => LCD_display_string <= (
X"20",X"20",X"20",X"20",X"45",X"45",X"43",X"45",X"20",X"33",X"34",X"33",X"20",X"20",X"20",X"20",
X"4D",X"61",X"74",X"74",X"68",X"65",X"77",X"20",X"41",X"6E",X"64",X"65",X"72",X"73",X"6F",X"6E");
END CASE;
END PROCESS;
-- BIDIRECTIONAL TRI STATE LCD DATA BUS
DATA_BUS <= DATA_BUS_VALUE WHEN LCD_RW_INT = '0' ELSE "ZZZZZZZZ";
-- get next character in display string
Next_Char <= LCD_display_string(CONV_INTEGER(CHAR_COUNT));
LCD_RW <= LCD_RW_INT;
PROCESS
BEGIN
WAIT UNTIL CLOCK_50'EVENT AND CLOCK_50 = '1';
IF RESET = '0' THEN
CLK_COUNT_400HZ <= X"00000";
CLK_400HZ_Enable <= '0';
ELSE
IF CLK_COUNT_400HZ < X"0F424" THEN
CLK_COUNT_400HZ <= CLK_COUNT_400HZ + 1;
CLK_400HZ_Enable <= '0';
ELSE
CLK_COUNT_400HZ <= X"00000";
CLK_400HZ_Enable <= '1';
END IF;
END IF;
END PROCESS;
PROCESS (CLOCK_50, reset)
BEGIN
IF reset = '0' THEN
state <= RESET1;
DATA_BUS_VALUE <= X"38";
next_command <= RESET2;
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW_INT <= '0';
ELSIF CLOCK_50'EVENT AND CLOCK_50 = '1' THEN
-- State Machine to send commands and data to LCD DISPLAY
IF CLK_400HZ_Enable = '1' THEN
CASE state IS
-- Set Function to 8-bit transfer and 2 line display with 5x8 Font size
-- see Hitachi HD44780 family data sheet for LCD command and timing details
WHEN RESET1 =>
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW_INT <= '0';
DATA_BUS_VALUE <= X"38";
state <= DROP_LCD_E;
next_command <= RESET2;
CHAR_COUNT <= "00000";
WHEN RESET2 =>
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW_INT <= '0';
DATA_BUS_VALUE <= X"38";
state <= DROP_LCD_E;
next_command <= RESET3;
WHEN RESET3 =>
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW_INT <= '0';
DATA_BUS_VALUE <= X"38";
state <= DROP_LCD_E;
next_command <= FUNC_SET;
-- EXTRA STATES ABOVE ARE NEEDED FOR RELIABLE PUSHBUTTON RESET OF LCD
WHEN FUNC_SET =>
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW_INT <= '0';
DATA_BUS_VALUE <= X"38";
state <= DROP_LCD_E;
next_command <= DISPLAY_OFF;
-- Turn off Display and Turn off cursor
WHEN DISPLAY_OFF =>
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW_INT <= '0';
DATA_BUS_VALUE <= X"08";
state <= DROP_LCD_E;
next_command <= DISPLAY_CLEAR;
-- Clear Display and Turn off cursor
WHEN DISPLAY_CLEAR =>
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW_INT <= '0';
DATA_BUS_VALUE <= X"01";
state <= DROP_LCD_E;
next_command <= DISPLAY_ON;
-- Turn on Display and Turn off cursor
WHEN DISPLAY_ON =>
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW_INT <= '0';
DATA_BUS_VALUE <= X"0C";
state <= DROP_LCD_E;
next_command <= MODE_SET;
-- Set write mode to auto increment address and move cursor to the right
WHEN MODE_SET =>
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW_INT <= '0';
DATA_BUS_VALUE <= X"06";
state <= DROP_LCD_E;
next_command <= Print_String;
-- Write ASCII hex character in first LCD character location
WHEN Print_String =>
state <= DROP_LCD_E;
LCD_E <= '1';
LCD_RS <= '1';
LCD_RW_INT <= '0';
-- ASCII character to output
IF Next_Char(7 DOWNTO 4) /= X"0" THEN
DATA_BUS_VALUE <= Next_Char;
ELSE
-- Convert 4-bit value to an ASCII hex digit
IF Next_Char(3 DOWNTO 0) >9 THEN
-- ASCII A...F
DATA_BUS_VALUE <= X"4" & (Next_Char(3 DOWNTO 0)-9);
ELSE
-- ASCII 0...9
DATA_BUS_VALUE <= X"3" & Next_Char(3 DOWNTO 0);
END IF;
END IF;
state <= DROP_LCD_E;
-- Loop to send out 32 characters to LCD Display (16 by 2 lines)
IF (CHAR_COUNT < 31) AND (Next_Char /= X"FE") THEN
CHAR_COUNT <= CHAR_COUNT +1;
ELSE
CHAR_COUNT <= "00000";
END IF;
-- Jump to second line?
IF CHAR_COUNT = 15 THEN
next_command <= line2;
-- Return to first line?
ELSIF (CHAR_COUNT = 31) OR (Next_Char = X"FE") THEN
next_command <= return_home;
ELSE
next_command <= Print_String;
END IF;
-- Set write address to line 2 character 1
WHEN LINE2 =>
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW_INT <= '0';
DATA_BUS_VALUE <= X"C0";
state <= DROP_LCD_E;
next_command <= Print_String;
-- Return write address to first character postion on line 1
WHEN RETURN_HOME =>
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW_INT <= '0';
DATA_BUS_VALUE <= X"80";
state <= DROP_LCD_E;
next_command <= Print_String;
-- The next three states occur at the end of each command or data transfer to the LCD
-- Drop LCD E line - falling edge loads inst/data to LCD controller
WHEN DROP_LCD_E =>
LCD_E <= '0';
state <= HOLD;
-- Hold LCD inst/data valid after falling edge of E line
WHEN HOLD =>
state <= next_command;
END CASE;
END IF;
END IF;
END PROCESS;
END Behavior;
Upvotes: 0
Views: 2292
Reputation: 140
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY top_module IS PORT(
X : IN STD_LOGIC_VECTOR(8 DOWNTO 0);
CLK, LOAD: IN STD_LOGIC;
LCD_RS, LCD_E : OUT STD_LOGIC;
LCD_RW : OUT STD_LOGIC;
LCD_ON : OUT STD_LOGIC;
LCD_BLON : OUT STD_LOGIC;
);
END ENTITY;
ARCHITECTURE Behavior OF top_module IS
component Sequence_Detector IS PORT(
X : IN STD_LOGIC_VECTOR(8 DOWNTO 0);
CLK, LOAD: IN STD_LOGIC;
LED : OUT STD_LOGIC_VECTOR(17 DOWNTO 0);
Z: INOUT STD_LOGIC_VECTOR(1 DOWNTO 0));
END component;
component slowclk IS PORT(
clk : IN STD_LOGIC;
clkout : OUT STD_LOGIC);
END component;
component LCD is PORT(
reset, CLOCK_50 : IN STD_LOGIC;
enable_0 : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
enable_1 : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
LCD_RS, LCD_E : OUT STD_LOGIC;
LCD_RW : OUT STD_LOGIC;
LCD_ON : OUT STD_LOGIC;
LCD_BLON : OUT STD_LOGIC;
DATA_BUS : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END component;
begin
Instance_sequence_detector:
port map ( X => X,
CLK => clkout,
LOAD => LOAD,
LED => LED,
Z => Z );
Instance_slowclk:
port map ( clk => clk,
clkout => clkout
);
Instance_LCD:
port map(reset => reset,
CLOCK_50 => clkout,
enable_0 => enable_0,
enable_1 => enable_1,
LCD_RS => LCD_RS,
LCD_E => LCD_E,
LCD_RW => LCD_RW,
LCD_ON => LCD_ON,
LCD_BLON => LCD_BLON,
DATA_BUS => DATA_BUS
);
You can instantiate those modules in your top module like this. Just map the corresponding in and out ports from block to block.
Upvotes: 0
Reputation: 37
I tries embedding the signals into the LCD program and was able to figure it out. I would like to learn how to take care of instantiating the Entities in the future so thank you all for the responses.
Matt
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.all;
USE IEEE.STD_LOGIC_ARITH.all;
USE IEEE.STD_LOGIC_UNSIGNED.all;
ENTITY State_Machine IS
-------------------------------------------------------------------
-- ASCII HEX TABLE
-- Hex Low Hex Digit
-- Value 0 1 2 3 4 5 6 7 8 9 A B C D E F
------\----------------------------------------------------------------
--H 2 | SP ! " # $ % & ' ( ) * + , - . /
--i 3 | 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
--g 4 | @ A B C D E F G H I J K L M N O
--h 5 | P Q R S T U V W X Y Z [ \ ] ^ _
-- 6 | ` a b c d e f g h i j k l m n o
-- 7 | p q r s t u v w x y z { | } ~ DEL
-----------------------------------------------------------------------
PORT(reset, CLOCK_50 : IN STD_LOGIC;
-- enable : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
X : IN STD_LOGIC_VECTOR(8 DOWNTO 0);
LOAD : IN STD_LOGIC;
LCD_RS, LCD_E : OUT STD_LOGIC;
LCD_RW : OUT STD_LOGIC;
LCD_ON : OUT STD_LOGIC;
LCD_BLON : OUT STD_LOGIC;
LED : OUT STD_LOGIC_VECTOR(17 DOWNTO 0);
DATA_BUS : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0));
-- W : INOUT STD_LOGIC_VECTOR(1 DOWNTO 0));
END ENTITY;
ARCHITECTURE BEH OF State_Machine IS
TYPE character_string IS ARRAY ( 0 TO 31 ) OF STD_LOGIC_VECTOR( 7 DOWNTO 0 );
TYPE state_type_1 is (S0,S1,S2,S3,S4,S5,S6,S7,S8);
TYPE STATE_TYPE IS (HOLD, FUNC_SET, DISPLAY_ON, MODE_SET, Print_String,
LINE2, RETURN_HOME, DROP_LCD_E, RESET1, RESET2,
RESET3, DISPLAY_OFF, DISPLAY_CLEAR);
SIGNAL TMP : STD_LOGIC_VECTOR(8 DOWNTO 0);
SIGNAL clkout : STD_LOGIC;
SIGNAL Z : STD_LOGIC_VECTOR(1 DOWNTO 0);
SIGNAL state_1 : state_type_1;
SIGNAL state, next_command : STATE_TYPE;
SIGNAL LCD_display_string : character_string;
SIGNAL DATA_BUS_VALUE, Next_Char : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL CLK_COUNT_400HZ : STD_LOGIC_VECTOR(19 DOWNTO 0);
SIGNAL CHAR_COUNT : STD_LOGIC_VECTOR(4 DOWNTO 0);
SIGNAL CLK_400HZ_Enable,LCD_RW_INT : STD_LOGIC;
SIGNAL Line1_chars, Line2_chars : STD_LOGIC_VECTOR(127 DOWNTO 0);
COMPONENT slowclk
PORT(clock_50 : IN STD_LOGIC;
clkout : OUT STD_LOGIC);
END COMPONENT;
BEGIN
LCD_ON <= '1';
LCD_BLON <= '1';
LED(17) <= LOAD;
LED(8 DOWNTO 0) <= X;
TMP <= X;
state0: slowclk PORT MAP (clock_50, clkout);
PROCESS (CLock_50)
BEGIN
IF (LOAD = '1') THEN
IF (clkout'EVENT AND clkout = '1') THEN
CASE state_1 IS
WHEN S0 =>
IF X(8) = '0' THEN
state_1 <= S0; --1--
Z <= "00";
ELSE
state_1 <= S1;
Z <= "00";
END IF;
WHEN S1 =>
IF X(7) = '0' THEN
state_1 <= S0; --1--
Z <= "00";
ELSE
state_1 <= S2;
Z <= "00";
END IF;
WHEN S2 =>
IF X(6) = '0' THEN
state_1 <= S3; --0--
Z <= "00";
ELSE
state_1 <= S2;
Z <= "00";
END IF;
WHEN S3 =>
IF X(5) = '0' THEN
state_1 <= S0; --1--
Z <= "00";
ELSE
state_1 <= S4;
Z <= "00";
END IF;
WHEN S4 =>
IF X(4) = '0' THEN
state_1 <= S5; --0--
Z <= "00";
ELSE
state_1 <= S2;
Z <= "00";
END IF;
WHEN S5 =>
IF X(3) = '0' THEN
state_1 <= S6; --0--
Z <= "00";
ELSE
state_1 <= S0;
Z <= "00";
END IF;
WHEN S6 =>
IF X(2) = '0' THEN
state_1 <= S0; --1--
Z <= "00";
ELSE
state_1 <= S7;
Z <= "00";
END IF;
WHEN S7 =>
IF X(1) = '0' THEN
state_1 <= S0; --1--
Z <= "00";
ELSE
state_1 <= S8;
Z <= "00";
END IF;
WHEN S8 =>
IF X(0) = '0' THEN
state_1 <= S0; --0--
Z <= "11";
ELSE
state_1 <= S2;
Z <= "01";
END IF;
END CASE;
END IF;
END IF;
END PROCESS;
PROCESS (clock_50)
BEGIN
CASE(z) IS
WHEN "11" => LCD_display_string <= (X"53",X"65",X"71",X"75",X"65",X"6E",X"63",X"65",X"20",X"50",X"61",X"73",X"73",X"65",X"64",X"20",
X"4D",X"61",X"74",X"74",X"68",X"65",X"77",X"20",X"41",X"6E",X"64",X"65",X"72",X"73",X"6F",X"6E");
WHEN "10" => LCD_display_string <= (X"20",X"20",X"20",X"20",X"45",X"45",X"43",X"45",X"20",X"33",X"34",X"33",X"20",X"20",X"20",X"20",
X"4D",X"61",X"74",X"74",X"68",X"65",X"77",X"20",X"41",X"6E",X"64",X"65",X"72",X"73",X"6F",X"6E");
WHEN "01" => LCD_display_string <= (X"53",X"65",X"71",X"75",X"65",X"6E",X"63",X"65",X"20",X"46",X"61",X"69",X"6C",X"65",X"64",X"20",
X"4D",X"61",X"74",X"74",X"68",X"65",X"77",X"20",X"41",X"6E",X"64",X"65",X"72",X"73",X"6F",X"6E");
WHEN "00" => LCD_display_string <= (X"20",X"20",X"20",X"20",X"45",X"45",X"43",X"45",X"20",X"33",X"34",X"33",X"20",X"20",X"20",X"20",
X"4D",X"61",X"74",X"74",X"68",X"65",X"77",X"20",X"41",X"6E",X"64",X"65",X"72",X"73",X"6F",X"6E");
END CASE;
END PROCESS;
-- ASCII hex values for LCD Display
-- Enter Live Hex Data Values from hardware here
-- LCD DISPLAYS THE FOLLOWING:
------------------------------
--| Count=XX |
--| DE2 |
------------------------------
-- Line 1
-- Line 2
-- BIDIRECTIONAL TRI STATE LCD DATA BUS
DATA_BUS <= DATA_BUS_VALUE WHEN LCD_RW_INT = '0' ELSE "ZZZZZZZZ";
-- get next character in display string
Next_Char <= LCD_display_string(CONV_INTEGER(CHAR_COUNT));
LCD_RW <= LCD_RW_INT;
PROCESS
BEGIN
WAIT UNTIL CLOCK_50'EVENT AND CLOCK_50 = '1';
IF RESET = '0' THEN
CLK_COUNT_400HZ <= X"00000";
CLK_400HZ_Enable <= '0';
ELSE
IF CLK_COUNT_400HZ < X"0F424" THEN
CLK_COUNT_400HZ <= CLK_COUNT_400HZ + 1;
CLK_400HZ_Enable <= '0';
ELSE
CLK_COUNT_400HZ <= X"00000";
CLK_400HZ_Enable <= '1';
END IF;
END IF;
END PROCESS;
PROCESS (CLOCK_50, reset)
BEGIN
IF reset = '0' THEN
state <= RESET1;
DATA_BUS_VALUE <= X"38";
next_command <= RESET2;
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW_INT <= '0';
ELSIF CLOCK_50'EVENT AND CLOCK_50 = '1' THEN
-- State Machine to send commands and data to LCD DISPLAY
IF CLK_400HZ_Enable = '1' THEN
CASE state IS
-- Set Function to 8-bit transfer and 2 line display with 5x8 Font size
-- see Hitachi HD44780 family data sheet for LCD command and timing details
WHEN RESET1 =>
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW_INT <= '0';
DATA_BUS_VALUE <= X"38";
state <= DROP_LCD_E;
next_command <= RESET2;
CHAR_COUNT <= "00000";
WHEN RESET2 =>
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW_INT <= '0';
DATA_BUS_VALUE <= X"38";
state <= DROP_LCD_E;
next_command <= RESET3;
WHEN RESET3 =>
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW_INT <= '0';
DATA_BUS_VALUE <= X"38";
state <= DROP_LCD_E;
next_command <= FUNC_SET;
-- EXTRA STATES ABOVE ARE NEEDED FOR RELIABLE PUSHBUTTON RESET OF LCD
WHEN FUNC_SET =>
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW_INT <= '0';
DATA_BUS_VALUE <= X"38";
state <= DROP_LCD_E;
next_command <= DISPLAY_OFF;
-- Turn off Display and Turn off cursor
WHEN DISPLAY_OFF =>
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW_INT <= '0';
DATA_BUS_VALUE <= X"08";
state <= DROP_LCD_E;
next_command <= DISPLAY_CLEAR;
-- Clear Display and Turn off cursor
WHEN DISPLAY_CLEAR =>
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW_INT <= '0';
DATA_BUS_VALUE <= X"01";
state <= DROP_LCD_E;
next_command <= DISPLAY_ON;
-- Turn on Display and Turn off cursor
WHEN DISPLAY_ON =>
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW_INT <= '0';
DATA_BUS_VALUE <= X"0C";
state <= DROP_LCD_E;
next_command <= MODE_SET;
-- Set write mode to auto increment address and move cursor to the right
WHEN MODE_SET =>
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW_INT <= '0';
DATA_BUS_VALUE <= X"06";
state <= DROP_LCD_E;
next_command <= Print_String;
-- Write ASCII hex character in first LCD character location
WHEN Print_String =>
state <= DROP_LCD_E;
LCD_E <= '1';
LCD_RS <= '1';
LCD_RW_INT <= '0';
-- ASCII character to output
IF Next_Char(7 DOWNTO 4) /= X"0" THEN
DATA_BUS_VALUE <= Next_Char;
ELSE
-- Convert 4-bit value to an ASCII hex digit
IF Next_Char(3 DOWNTO 0) >9 THEN
-- ASCII A...F
DATA_BUS_VALUE <= X"4" & (Next_Char(3 DOWNTO 0)-9);
ELSE
-- ASCII 0...9
DATA_BUS_VALUE <= X"3" & Next_Char(3 DOWNTO 0);
END IF;
END IF;
state <= DROP_LCD_E;
-- Loop to send out 32 characters to LCD Display (16 by 2 lines)
IF (CHAR_COUNT < 31) AND (Next_Char /= X"FE") THEN
CHAR_COUNT <= CHAR_COUNT +1;
ELSE
CHAR_COUNT <= "00000";
END IF;
-- Jump to second line?
IF CHAR_COUNT = 15 THEN next_command <= line2;
-- Return to first line?
ELSIF (CHAR_COUNT = 31) OR (Next_Char = X"FE") THEN
next_command <= return_home;
ELSE next_command <= Print_String; END IF;
-- Set write address to line 2 character 1
WHEN LINE2 =>
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW_INT <= '0';
DATA_BUS_VALUE <= X"C0";
state <= DROP_LCD_E;
next_command <= Print_String;
-- Return write address to first character postion on line 1
WHEN RETURN_HOME =>
LCD_E <= '1';
LCD_RS <= '0';
LCD_RW_INT <= '0';
DATA_BUS_VALUE <= X"80";
state <= DROP_LCD_E;
next_command <= Print_String;
-- The next three states occur at the end of each command or data transfer to the LCD
-- Drop LCD E line - falling edge loads inst/data to LCD controller
WHEN DROP_LCD_E =>
LCD_E <= '0';
state <= HOLD;
-- Hold LCD inst/data valid after falling edge of E line
WHEN HOLD =>
state <= next_command;
END CASE;
END IF;
END IF;
END PROCESS;
END BEH;
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
ENTITY slowclk IS
PORT(clock_50 : IN STD_LOGIC;
clkout : OUT STD_LOGIC);
END slowclk;
ARCHITECTURE ckt OF slowclk IS
BEGIN
PROCESS(clock_50)
VARIABLE cnt : INTEGER RANGE 0 TO 50000000;
BEGIN
IF clock_50'EVENT AND clock_50='1' THEN
IF cnt=50000000 THEN
cnt:=0;
clkout<='1';
ELSE
cnt:=cnt+1;
clkout<='0';
END IF;
END IF;
END PROCESS;
END ckt;
enter code here
Upvotes: 0