在下面的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;
答案 0 :(得分:1)
随机错误是由于Holder(n)未初始化使用。我可以提出两个解决方案:
A)确保你的synth工具允许它(不会忽略声明中的init值),然后将其更新为:
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
这样,您可以确保所有信号在重置时都获得有效值。
答案 1 :(得分:1)
这样的问题似乎在stackoverflow上很常见。用户附带一段代码,并希望获得帮助,解释它无法正常工作的原因。我不会告诉你代码到底有什么问题,但我会评论开发工作,可读和可测试的VHDL代码的过程。
我首先要提出一个大胆的主张:RTL很简单。与验证相比,它是数字设计的重要部分。在没有任何验证的情况下编写工作RTL当然是可能的,但是设计复杂性随着代码行数的增加而变得一致,验证工作在表面上增长,难怪验证这些日子引起了很多关注。
这只是一个疯狂的猜测 - 我认为这是大学或学院实验室任务的一部分。如果是这样,我发现很奇怪您不需要为您的设计提供测试平台。你显然已经为你的设计付出了很多努力;你应该期望至少放入你的测试平台。一旦你超越了一个琐碎的设计,你最终会花费数小时浪费实验室测试,试图找出错误 - 在模拟器中很容易发现的错误。
有一些例外情况,但我会说你在使用功能测试平台之前不应该写一行RTL。您的测试平台和被测设备以及连接实体的行为模型可以充分利用您选择的设计和验证语言的全部功能,而不仅限于可综合子集。行为建模的副作用是它可以帮助您理解设计的规范。
总结一下:
那么,你的测试平台在哪里?