首页 文章

VHDL组件端口映射问题

提问于
浏览
0

我是处理在VHDL中使用COMPONENTS的新手,我理解如何移植映射简单的东西,如减慢时钟,但是我已经构建了一个似乎运行良好的序列dtetctor,但我希望它的'输出触发输入我的LCD写程序并显示在我的液晶屏上 . 我怎样才能只映射一个信号,或者是否有更好的方法来考虑使用我没想到的COMPONENT?

我如何进行直接实体实例化?我可以在这里使用吗?我一直在尝试不同的方法使我的输出Z成为enable_0上LCD的输入,但是无法弄清楚如何不弄乱该实体上的所有其他端口 .

谢谢大家

马特

--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;

2 回答

  • 0
    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
                 );
    

    您可以像这样在顶层模块中实例化这些模块 . 只需从块到块映射相应的输入和输出端口 .

  • 0

    我尝试将信号嵌入到LCD程序中,并且能够解决这个问题 . 我想学习如何在将来实例化实体,所以谢谢大家的回复 .

    马特

    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
    

相关问题