0

在以下 VHDL 代码中,当我使用逻辑或代码停止工作时,HD44780LCD 崩溃,但是当我删除逻辑或并删除其中一个支架时,代码再次开始工作。我正在使用 Xilinx Spartan 3E 入门板。换句话说,当我更换

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

2 回答 2

1

随机错误是由于未初始化使用 Holder(n)。我可以提出两个解决方案:

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

这样,您可以确保所有信号在复位时都获得有效值。

于 2013-07-03T01:02:26.443 回答
1

这样的问题在stackoverflow上似乎很常见。用户提供了一段代码,并希望得到帮助来解释它为什么不起作用。我不会确切地告诉你代码有什么问题,但我会评论开发工作、可读和可测试的 VHDL 代码的过程。

我将首先从一个大胆的声明开始:RTL 很容易。与验证相比,它是数字设计中微不足道的部分。当然可以在没有任何验证的情况下编写有效的 RTL,但是虽然设计复杂性随着代码行数的增加而线性增长,但验证工作量呈指数增长,难怪如今验证受到了很多关注。

这只是一个疯狂的猜测——我认为这是大学或学院实验室任务的一部分。如果是这样,我觉得奇怪的是您不需要为您的设计提供测试平台。您显然在设计中付出了很多努力;你应该期望至少在你的测试平台中投入同样多的东西。一旦您超越了琐碎的设计,您最终将花费数小时进行浪费的实验室测试,试图找出问题所在——在模拟器中很容易发现错误。

也有例外,但我想说的是,在你有一个功能测试台来练习它之前,你不应该写一行 RTL。您的测试平台和被测设备和连接实体的行为模型可以充分利用您选择的设计和验证语言的全部功能,而不仅限于可综合的子集。行为建模的一个副作用是它可以帮助您了解设计规范。

所以总结一下:

  1. 学习行为建模,然后学好。编写高效且正确的模型对于开发良好且高效的测试平台至关重要。
  2. 探索测试驱动的开发。它也适用于硬件开发。一个模块化的测试平台可以很容易地添加新的测试用例——练习某些设备特性的用例。
  3. 为您的被测设备和外部组件使用行为模型。编写目标设计的行为实现并不是一种浪费。它将帮助您在编写任何 RTL 之前开发您的测试平台。

那么,您的测试平台在哪里?

于 2013-08-21T21:18:09.997 回答