34169

Weird VHDL Behavior

Question:

In the following VHDL code when i use logical or the code stops working the HD44780LCD crashes but when i remove the logical or and remove one of the holders the code starts to work again. I'm using Xilinx Spartan 3E starter board. In other words when I replace the

SendCommand <= Holder(0);

with

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

The program acts weird and crashes.

Here is the code:

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;

Here is the DisplayDriver Components Code If its useful

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;

Answer1:

The random errors are due to Holder(n) being used uninitialized. I can propose two solutions:

A) make sure your synth tool allows it (does not ignore init values in declarations) and then update it as:

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

B) Your process' sensitivity list lacks a reset signal, like in

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

That way you make sure that all signals get a valid value upon reset.

Answer2:

Questions like this seems to be common here on stackoverflow. A user comes with a piece of code and want help explaining why it does not work. I won't tell you exactly what's wrong with the code, but I will comment on the process of developing working, readable and testable VHDL code.

I'll first start with a bold claim: RTL is easy. Compared to verification it is the trivial part of digital design. It is certainly possible to write working RTL without any verification, but whereas design complexity grows lineary with the number of lines of code, the verification effort grows expotensially it is no wonder that verification is getting a lot of attention these days.

This is just a wild guess - I assume this is part of a lab assignment at a university or college. If so is true, I find it strange that you are not required to provide a testbench for your design. You clearly have put a lot of effort into your design; you should expect to put at least as much into your testbench. Once you go beyond a trivial design you will end up spending hours in wasted lab tests trying to figure out what is wrong - errors which would easily be found in a simulator.

There are be exceptions, but I would go as far as to say that you shouldn't write a single line of RTL before you have a functional testbench to exercise it with. Your testbench and behavoural models of the device-under-test and connected entities can take advantage the full power of your design and verification language of choice, and is not limited to the synthesizable subset. A side-effect of behavoural modelling is that it helps you understand the specification of your design.

So to summarize:

<ol><li>Learn behavoural modelling, and learn it well. Writing efficient and correct models is essential to be able to develop good and efficient testbenches.</li> <li>Explore test-driven development. It applies well to hardware development too. A modular testbench make it easy to add new test cases - cases that exercises certain device features. </li> <li>Use behavoural models for both you device-under-test and for external components. Writing a behavoural implementation of the target design is not a waste. It will help you develop your testbench prior to any RTL being written.</li> </ol>

So, where is your testbench?

Recommend

  • conversion of list to bitarray in python
  • Android - Samsung Galaxy S4 Reboot issue
  • Phonegap app performance on Nexsus vs Samsung
  • Join then mutate using data.table without intermediate table
  • dplyr to calculate of prevalence of a variable in a condition
  • Where is my APK stored when i run program on a android device?
  • Splitting string variables in R
  • Minimum distance between two rotated rectangles with different angles
  • Implement reference sets in Redis
  • Mysqli How to get and fill data with 3 columns
  • Passing arguments by pass-by-reference to a swap function
  • How to configure mentioned use case using spring batch parallel step split flow?
  • Weird VHDL Behavior
  • What is the best way to replace a string with another string on entire table?
  • How to stop onItemSelected() from firing off multiple times after a selection of an item was made?
  • Different color of same date range in a column Excel
  • Led not working on Android using Unified Push Notification of worklight (6.0.0.2)
  • One constructor - multiple arguments
  • Snakemake: How to save and access sample details in config.yml file?
  • Pandas, groupby and count
  • drawable-sw720dp vs drawable-hdpi, drawable-xhdpi and others
  • C# ListView and RightToLeft
  • 'System.Net.Mail.SmtpException: Failure sending mail from remote mail server
  • Adding group mean lines to geom_bar plot and including in legend
  • Voice communication at 8KHz sampling rate for all android device using OpenSL
  • STR_Replace Issues With Soap Envelope
  • custom action bar relative layout children not placed correctly
  • How to remove the box frame in “plot.raster” in R package “raster”
  • Why does the memory alignment change within a structure?
  • subassignment of selected layers in raster brick
  • Sensor StepCounter sometime not work well on SamSung device
  • VBA Go to the next filtered cell
  • How to create a window in smalltalk
  • Using Response in the same PHP file
  • Is there a way to limit the number of records in certain collection
  • Giving security priviliege to a scheduler in Java EE 6
  • NHibernate Validation Localization with S#arp Architecture
  • Bug in WPF DataGrid
  • Redux, normalised entities and lodash merge
  • how does django model after text[] in postgresql [duplicate]