2013-07-02 5 views
0

В следующем коде VHDL, когда я использую логический или код перестает работать, HD44780LCD падает, но когда я удаляю логический или удаляет один из держателей, код начинает работать снова. Я использую стартовый совет Xilinx Spartan 3E. Другими словами, когда я заменитьWeird VHDL Behavior

SendCommand <= Holder(0); 

с

SendCommand <= Holder(0) or Holder(1); 

Программа действует странно и аварий.

Вот код:

library IEEE; 
use IEEE.STD_LOGIC_1164.all; 
use IEEE.STD_LOGIC_ARITH.all; 
use IEEE.STD_LOGIC_UNSIGNED.all; 

entity Main is 
    port(
    CLK : in std_logic; 
    RIGHT : in std_logic; 
    left : in std_logic; 
    UP  : in std_logic; 
    DOWN : in std_logic; 
    SF_DSW : in std_logic_vector(3 downto 0); 
    LED : out std_logic_vector(7 downto 0); 
    LCD_E : out std_logic; 
    LCD_RS : out std_logic; 
    LCD_RW : out std_logic; 
    SF_D : out std_logic_vector(11 downto 8) 
    ); 
end Main; 

architecture Behavioral of Main is 
    component LCDS 
    port(
     CLK  : in std_logic; 
     Enable : in std_logic; 
     EnableCMD : in std_logic; 
     CMD  : in std_logic_vector(7 downto 0); 
     ASCII  : in std_logic_vector (7 downto 0); 
     LCD_E  : out std_logic; 
     LCD_RS : out std_logic; 
     LCD_RW : out std_logic; 
     SF_D  : out std_logic_vector(11 downto 8) 
    ); 
    end component; 
    signal Char  : std_logic_vector(7 downto 0); 
    signal SendChar : std_logic; 
    signal Command  : std_logic_vector(7 downto 0) := X"80"; 
    signal SendCommand : std_logic; 
    signal SDisable : std_logic_vector(2 downto 0); 
    signal Holder  : std_logic_vector(2 downto 0); 
    constant MS3  : std_logic_vector(17 downto 0) := "100100100111110000"; 
begin 
    DisplayDriver : LCDS 
    port map(CLK, SendChar, SendCommand, Command, Char, LCD_E, LCD_RS, LCD_RW, SF_D); 
    SendKey : process (CLK) 
    begin 
    if rising_edge(CLK) then 
     if SDisable(0) = '0' then 
     if left = '1' then Holder(0) <= '1'; SDisable(0) <= '1'; end if; 
     elsif left = '1' and SDisable(0) = '1' then Holder(0) <= '0'; 
     else 
     if left = '0' and SDisable(0) = '1' then SDisable(0) <= '0'; end if; 
     end if; 
     if SDisable(1) = '0' then 
     if right = '1' then Holder(1) <= '1'; SDisable(1) <= '1'; end if; 
     elsif right = '1' and SDisable(1) = '1' then Holder(1) <= '0'; 
     else 
     if right = '0' and SDisable(1) = '1' then SDisable(1) <= '0'; end if; 
     end if; 
     if SDisable(2) = '0' then 
     if UP = '1' then Holder(2) <= '1'; SDisable(2) <= '1'; end if; 
     elsif UP = '1' and SDisable(2) = '1' then Holder(2) <= '0'; 
     else 
     if UP = '0' and SDisable(2) = '1' then SDisable(2) <= '0'; end if; 
     end if; 
     if left = '1' then 
     if ((Command > X"7F") and (Holder(0) = '1')) then 
      Command <= Command -1; 
     end if; 
     elsif right = '1' then 
     if ((Command < X"D1") and (Holder(1) = '1')) then 
      Command <= Command +1; 
     end if; 
     end if; 
     if UP = '1' then 
     if Holder(2) = '1' then 
      Char <= Char +1; 
     end if; 
     end if; 
     if SF_DSW = X"0" then 
     LED    <= X"00"; 
     LED(3 downto 0) <= left&right&DOWN&UP; 
     LED(4)   <= ((left or right) or UP); 
     elsif SF_DSW = X"1" then 
     LED <= Char; 
     elsif SF_DSW = X"2" then 
     LED <= Command; 
     end if; 
     SendCommand <= (Holder(0)); 
     --Not working when 
     --SendCommand <= (Holder(0) or Holder(1)); 
     SendChar <= Holder(2); 
    end if; 
    end process; 
end Behavioral; 

Здесь DisplayDriver компоненты кода Если его полезные

library IEEE; 
use IEEE.STD_LOGIC_1164.all; 
use IEEE.STD_LOGIC_ARITH.all; 
use IEEE.STD_LOGIC_UNSIGNED.all; 

entity LCDS is 
    port(
    CLK  : in std_logic; 
    Enable : in std_logic; 
    EnableCMD : in std_logic; 
    CMD  : in std_logic_vector(7 downto 0); 
    ASCII  : in std_logic_vector (7 downto 0); 
    LCD_E  : out std_logic; 
    LCD_RS : out std_logic; 
    LCD_RW : out std_logic; 
    SF_D  : out std_logic_vector(11 downto 8) 
    ); 
end LCDS; 

architecture Behavioral of LCDS is 
    type Conf is (S1, S2, S3, S4, Done); 
    type Initx is (FuncSet, DisplaySet, DisplayOn, MWait, Custom, Done); 
    type DelaySet is (MS5000, MS1000, MS2, US300, NS500, US160, none); 
    type Chars is (A, none); 
    signal Conf_s  : Conf  := S1; 
    signal Init_s  : Initx; 
    signal Chars_s  : Chars  := none; 
    signal SDisable : std_logic := '0'; 
    signal SDisableCMD : std_logic := '0'; 
    signal DelaySet_s : DelaySet; 
    signal Counter  : std_logic_vector(29 downto 0); 
    signal XLatch  : std_logic := '0'; 
begin 
    Display : process(CLK, Enable, EnableCMD) 
    begin 
    if rising_edge(CLK) then 
     LCD_RW <= '0'; 
     if SDisable = '0' then 
     if Enable = '1' then Chars_s <= A; SDisable <= '1'; end if; 
     elsif Enable = '1' and SDisable = '1' then Chars_s <= none; 
     else 
     if Enable = '0' and SDisable = '1' then SDisable <= '0'; end if; 
     end if; 
     if SDisableCMD = '0' then 
     if EnableCMD = '1' then Init_s <= Custom; SDisable <= '1'; end if; 
     elsif EnableCMD = '1' and SDisableCMD = '1' then Init_s <= Done; 
     else 
     if EnableCMD = '0' and SDisableCMD = '1' then SDisableCMD <= '0'; end if; 
     end if; 
     if DelaySet_s = none then 
     if not (Conf_s = Done) then 
      case Conf_s is 
      when S1 => 
       LCD_RS  <= '0'; 
       SF_D  <= X"3"; 
       DelaySet_s <= MS2; 
       Conf_s  <= S2; 
       LCD_E  <= '1'; 
      when S2 => 
       LCD_RS  <= '0'; 
       SF_D  <= X"3"; 
       DelaySet_s <= US160; 
       Conf_s  <= S3; 
       LCD_E  <= '1'; 
      when S3 => 
       LCD_RS  <= '0'; 
       SF_D  <= X"3"; 
       DelaySet_s <= US160; 
       Conf_s  <= S4; 
       LCD_E  <= '1'; 
      when S4 => 
       LCD_RS  <= '0'; 
       SF_D  <= X"2"; 
       DelaySet_s <= US160; 
       Conf_s  <= Done; 
       LCD_E  <= '1'; 
      when others => null; 
      end case; 
     elsif not(Init_s = Done) then 
      case Init_s is 
      when FuncSet => 
       if XLatch = '0' then 
       LCD_RS  <= '0'; 
       SF_D  <= X"2"; 
       XLatch  <= '1'; 
       DelaySet_s <= US300; 
       LCD_E  <= '1'; 
       else 
       LCD_RS  <= '0'; 
       SF_D  <= X"8"; 
       XLatch  <= '0'; 
       delaySet_s <= US300; 
       Init_s  <= DisplaySet; 
       LCD_E  <= '1'; 
       end if; 
      when DisplaySet => 
       if XLatch = '0' then 
       LCD_RS  <= '0'; 
       SF_D  <= X"0"; 
       XLatch  <= '1'; 
       delaySet_s <= US300; 
       LCD_E  <= '1'; 
       else 
       LCD_RS  <= '0'; 
       SF_D  <= X"8"; 
       XLatch  <= '0'; 
       delaySet_s <= US300; 
       Init_s  <= DisplayOn; 
       LCD_E  <= '1'; 
       end if; 
      when DisplayOn => 
       if XLatch = '0' then 
       LCD_RS  <= '0'; 
       SF_D  <= X"0"; 
       XLatch  <= '1'; 
       delaySet_s <= US300; 
       LCD_E  <= '1'; 
       else 
       LCD_RS  <= '0'; 
       SF_D  <= X"F"; 
       XLatch  <= '0'; 
       delaySet_s <= MS2; 
       Init_s  <= MWait; 
       LCD_E  <= '1'; 
       end if; 
      when MWait => 
       XLatch  <= '0'; 
       LCD_E  <= '0'; 
       DelaySet_s <= MS2; 
       Init_s  <= Done; 
      when Custom => 
       if XLatch = '0' then 
       LCD_RS  <= '0'; 
       SF_D  <= CMD(7 downto 4); 
       XLatch  <= '1'; 
       delaySet_s <= US300; 
       LCD_E  <= '1'; 
       else 
       LCD_RS  <= '0'; 
       SF_D  <= CMD(3 downto 0); 
       XLatch  <= '0'; 
       delaySet_s <= MS2; 
       Init_s  <= MWait; 
       LCD_E  <= '1'; 
       end if; 
      when others => null; 
      end case; 
     elsif Chars_s = A then 
      case Chars_s is 
      when A => 
       if XLatch = '0' then 
       LCD_RS  <= '1'; 
       SF_D  <= ASCII(7 downto 4); 
       XLatch  <= '1'; 
       DelaySet_s <= US300; 
       LCD_E  <= '1'; 
       else 
       LCD_RS  <= '1'; 
       SF_D  <= ASCII(3 downto 0); 
       XLatch  <= '0'; 
       DelaySet_s <= US160; 
       LCD_E  <= '1'; 
       Chars_s <= none; 
       end if; 
      when others => null; 
      end case; 
     end if; 
     else 
     case DelaySet_s is 
      when MS5000 => 

      if Counter < "1110111001101011001010000000" then 
       Counter <= Counter + 1; 
      else 
       LCD_E  <= '0'; 
       Counter <= (others => '0'); 
       DelaySet_s <= none; 
      end if; 
      when MS1000 => 
      if Counter < "10111110101111000010000000" then 
       Counter <= Counter + 1; 
      else 
       LCD_E  <= '0'; 
       Counter <= (others => '0'); 
       DelaySet_s <= none; 
      end if; 
      when MS2 => 
      if Counter < "11000011010100000" then 
       Counter <= Counter + 1; 
      else 
       LCD_E  <= '0'; 
       Counter <= (others => '0'); 
       DelaySet_s <= none; 
      end if; 
      when US300 => 
      if Counter < "11101010011000" then 
       Counter <= Counter + 1; 
      else 
       LCD_E <= '0'; 
       Counter <= (others => '0'); 
       DelaySet_s <= none; 
      end if; 
      when US160 => 
      if Counter < "1111101000000" then 
       Counter <= Counter + 1; 
      else 
       LCD_E  <= '0'; 
       Counter <= (others => '0'); 
       DelaySet_s <= none; 
      end if; 
      when NS500 => 
      if Counter < "11001" then 
       Counter <= Counter + 1; 
      else 
       LCD_E  <= '0'; 
       Counter <= (others => '0'); 
       DelaySet_s <= none; 
      end if; 
      when others => null; 
     end case; 
     end if; 
    end if; 
    end process; 
end Behavioral; 
+0

Ваш отправленный исходный код спагетти. Я рекомендую вам выровнять его и использовать pastebin, если наш код слишком длинный, чтобы получить лучший ответ. С другой стороны, какая авария? Вы когда-нибудь имитировали/синтезировали его? – Khanh

+0

Драйвер должен помечать мигающий curosr, но когда я возвращаю компонент SendCommand, ничего не отображается, когда lcd настроен правильно, но когда я нажимаю любую из кнопок, ничего не появляется, и мигающий курсор тоже не срабатывает. И да, я пробовал его и пытался на реальном спартанском 3E Board – user150374

+0

Я не могу найти какое-либо объявление для 'right' в вашем коде. Можете ли вы проверить, совпадает ли опубликованный код с кодом, который вы используете для синтеза? Это также может помочь, если вы кратко объяснили, что представляет «Держатель» и что он должен делать. – damage

ответ

1

Случайные ошибки обусловлены Holder (п) используется неинициализированным. Я могу предложить два решения:

A) Убедитесь, что ваш инструмент синтезатор позволяет (не игнорировать инициализации значения в объявлениях), а затем обновить его как:

signal Holder  : std_logic_vector(2 downto 0) := (others => '0'); 

B) список чувствительности вашего процесса не хватает сигнал сброса, как в

process_name : process (rst, clk) 
begin 
    if (rst = '1') then -- or '0' if active-low async. reset 
     ... set initial value for all signals 
    elsif rising_edge(clk) then 

Таким образом, вы убедитесь, что все сигналы получают действительное значение после сброса.

+0

Отсутствие сигнала сброса может быть правильным при синхронном сбросе. Если только он/она хочет асинхронно. сброс, первый должен включить список чувствительности. – Khanh

+0

В моем проекте нет сигнала сброса, если я хочу сбросить что-то, я просто перезапустил его. Я попробовал metho A, но он не работал. Я собираюсь сгенерировать и загрузить схему – user150374

+0

Я думаю, что нет никакой возможности генерировать схему из vhdl в ISE – user150374

1

Вопросы, подобные этому, как правило, встречаются здесь в stackoverflow. Пользователь приходит с куском кода и хочет помочь объяснить, почему он не работает. Я не скажу вам, что именно не так с кодом, но я прокомментирую процесс разработки рабочего, читаемого и проверяемого кода VHDL.

Начну с смелого заявления: RTL прост. По сравнению с проверкой это тривиальная часть цифрового дизайна. Разумеется, можно писать рабочий RTL без какой-либо проверки, но в то время как сложность дизайна растет линейно с количеством строк кода, усилия по проверке растут экспоненциально, неудивительно, что проверка в последнее время становится предметом пристального внимания.

Это просто дикая догадка - я полагаю, что это часть лабораторного задания в университете или колледже. Если это так, мне кажется странным, что вы не обязаны предоставлять тестовый стенд для своего дизайна. Вы явно приложили много усилий в свой дизайн; вы должны ожидать, что поместите как минимум столько же в свой тестовый стенд. Как только вы выйдете за рамки тривиального дизайна, вы закончите тратить часы на потраченные впустую лабораторные тесты, пытаясь выяснить, что не так - ошибки, которые легко можно найти в симуляторе.

Есть исключения, но я бы сказал, что вы не должны писать одну строку RTL, прежде чем у вас будет функциональная тестовая площадка, чтобы ее реализовать. Ваши тестовые тесты и модели поведения устройств, находящихся под тестом и связанными с ними объектами, могут воспользоваться всеми возможностями вашего дизайна и языка проверки выбора и не ограничиваться синтезируемым подмножеством. Побочным эффектом моделирования поведения является то, что он помогает вам понять спецификацию вашего дизайна.

Итак, подведем итог:

  1. Learn behavoural моделирования и научиться хорошо. Написание эффективных и правильных моделей имеет важное значение для разработки хороших и эффективных тестовых стендов.
  2. Исследуйте разработку, основанную на испытаниях. Это хорошо относится и к разработке аппаратного обеспечения. Модульный testbench упрощает добавление новых тестовых примеров - случаев, которые выполняют определенные функции устройства.
  3. Использовать модели поведения как для вашего устройства, так и для внешних компонентов. Написание поведенческой реализации целевого проекта не является отходами. Это поможет вам разработать свой тестовый стенд до того, как будет написан любой RTL.

Итак, где ваш тестовый стенд?