0

Spartan 3AN の LCD の初期化を実装しようとしています。私はこれに非常に慣れていないので、すべてのアドバイスは大歓迎です。

私のコードは次のとおりです。

----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    17:31:49 11/04/2011 
-- Design Name: 
-- Module Name:    LCD - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--use IEEE.STD_LOGIC_ARITH.ALL;
--use IEEE.STD_LOGIC_UNSIGNED.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity LCD is
    Port ( clk : in  STD_LOGIC;
           LCD_DB : out  STD_LOGIC_VECTOR (7 downto 0);
           LCD_E : out  STD_LOGIC;
           LCD_RS : out  STD_LOGIC;
           LCD_RW : out  STD_LOGIC);
end LCD;

architecture Behavioral of LCD is

--      CAUTION!!!  When using 4-bit mode, FPGA must drive the LCD_DB<3:0> signals HIGH ( = '1' )   
--      MAQUINA DE ESTADOS INICIALIZACION
    type initialization_state is (A, B, C, D, E, F, G, H, I, done);
    signal iCurrentState: initialization_state := A;
    signal iNextState: initialization_state := A;
    signal cycleCounter: integer := 0;

--      MAQUINA DE ESTADOS

begin

    initializationLCD:
    process (clk) begin
        if (clk'event and clk = '1') then
            case iCurrentState is
                when A =>
                    if (cycleCounter = 750000) then
                        iCurrentState <= B;
                        cycleCounter <= 0;
                    else
                        cycleCounter <= cycleCounter + 1;
                    end if;
                when B =>
                    LCD_RS <= '1';
                    LCD_RW <= '0';
                    LCD_DB <= "00000001";
                    if (cycleCounter = 50000) then
                        iCurrentState <= C;
                        cycleCounter <= 0;
                    else
                        cycleCounter <= cycleCounter + 1;
                    end if;
                when C =>
                    if (cycleCounter = 50000) then
                        iCurrentState <= D;
                        cycleCounter <= 0;
                    else
                        cycleCounter <= cycleCounter + 1;
                    end if;
                when D =>
                    LCD_RS <= '1';
                    LCD_RW <= '0';
                    LCD_DB <= "00000010";
                    if (cycleCounter = 50000) then
                        iCurrentState <= E;
                        cycleCounter <= 0;
                    else
                        cycleCounter <= cycleCounter + 1;
                    end if;
                when E =>
                    if (cycleCounter = 50000) then
                        iCurrentState <= F;
                        cycleCounter <= 0;
                    else
                        cycleCounter <= cycleCounter + 1;
                    end if;
                when F =>
                    LCD_RS <= '1';
                    LCD_RW <= '0';
                    LCD_DB <= "00000100";
                    if (cycleCounter = 12) then
                        iCurrentState <= G;
                        cycleCounter <= 0;
                    else
                        cycleCounter <= cycleCounter + 1;
                    end if;
                when G =>
                    if (cycleCounter = 50000) then
                        iCurrentState <= H;
                        cycleCounter <= 0;
                    else
                        cycleCounter <= cycleCounter + 1;
                    end if;
                when H =>
                    LCD_RS <= '1';
                    LCD_RW <= '0';
                    LCD_DB <= "00001000";
                    if (cycleCounter = 12) then
                        iCurrentState <= I;
                        cycleCounter <= 0;
                    else
                        cycleCounter <= cycleCounter + 1;
                    end if;
                when I =>
                    if (cycleCounter = 50000) then
                        iCurrentState <= done;
                        cycleCounter <= 0;
                    else
                        cycleCounter <= cycleCounter + 1;
                    end if;
                when others =>
                    iCurrentState <= done;
            end case;
        end if;
    end process;

end Behavioral;

したがって、2 つの質問があります。

  1. このコードは大丈夫ですか?やるべきコードがもっとたくさんあることはわかっていますが、うまくいっているかどうかを確認したいだけです。何が質問 2 につながるのでしょうか。

  2. ISim を使用してシミュレーションを実行しました (ザイリンクス 12.3 を使用しています)。状態は常に A で変化しません。コードに何か不足がありますか? または、これを間違った方法でシミュレートしている可能性があります。シミュレートする方法を教えてもらえますか?

本当にありがとう !

4

1 に答える 1

2

私が見るいくつかのこと、いくつかはスタイルで、いくつかはそうではありません:

  1. およびライブラリは使用しないでください。これらは IEEE 標準ではなく、VHDL が提供する強力な型の多くを奪ってしまうため、初心者にとっては非常に不利になる可能性があります。代わりに使用してください。インターネット検索で詳細がわかります。std_logic_arithstd_logic_unsignednumeric_std
  2. 「最新の」マクロrising_edge()は、L->H 状態も処理するため、クロック チェックに適しています (FPGA/ASIC では決して発生しませんが...)。
  3. iNextState未使用と思われるものがあります。
  4. LCD起動時に出力が設定されない境界条件があります。FSM にリセットを追加するか、出力の設定方法を再考する必要があります (参照: Mealy と Moore スタイルの FSM)。
  5. の列挙がある場合は、initialization_stateより意味のある名前を付けたり、各状態で何をすべきかについてコメントしたりすることができます。

それ以外の場合は、クイック ルックで問題ないようです。他の人が指摘したように、750K クロックは長いシミュレーションであり、クロックを駆動するテストベンチ コードを見なければ、それが機能するかどうかわかりません。750K とその他すべてを、テスト目的で非常に小さな値に変更できる定数に切り替えることをお勧めします。

于 2011-11-05T13:26:59.980 に答える