Question

This is the subprogram for the LCD:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity VideoTest is
    port( LCD_E, LCD_RS, LCD_RW : OUT std_logic;
            LCD_DB : OUT std_logic_vector(7 downto 0);
            counter: IN integer;
            clk: IN std_logic);

end VideoTest;

architecture Behavioral of VideoTest is
    signal InitDone: std_logic :='0';
begin

InitAndSet: process (InitDone, counter, clk) is
    variable tencounter: integer :=0;
    variable tempcounter: integer :=0;
begin
    if (clk'event and clk='1') then
        if (InitDone = '0') then
        -- Enabling
            LCD_E <='1';

        -- Clear Screen
            LCD_RS<='0';
            LCD_RW<='0';
            LCD_DB(7 downto 1) <= "0000000";
            LCD_DB(0) <= '1';

        -- Return Cursor Home

            LCD_RS<='0';
            LCD_RW<='0';
            LCD_DB(7 downto 2) <= "000000";
            LCD_DB(1) <= '1';
            LCD_DB(0) <= '0';

        -- Setting incrementation and moving cursor;

            LCD_RS<='0';
            LCD_RW<='0';
            LCD_DB(7 downto 3) <= "00000";
            LCD_DB(2) <= '1';
            LCD_DB(1) <= '1';
            LCD_DB(0) <= '0';

        -- Display On, show cursor, blink cursor

            LCD_RS<='0';
            LCD_RW<='0';
            LCD_DB(7 downto 4) <= "0000";
            LCD_DB(3) <= '1';
            LCD_DB(2) <= '1';
            LCD_DB(1) <= '1';
            LCD_DB(0) <= '1';

        -- Function set

            LCD_RS<='0';
            LCD_RW<='0';
            LCD_DB(7 downto 6) <= "00";
            LCD_DB(5) <= '1';
            LCD_DB(4) <= '0';
            LCD_DB(3) <= '1';
            LCD_DB(2) <= '0';
            LCD_DB(1) <= '1';
            LCD_DB(0) <= '1';

        -- Set DD Adress to 0

            LCD_RS<='0';
            LCD_RW<='0';
            LCD_DB(7)<='1';
            LCD_DB(6 downto 0) <= "0000000";

            InitDone <= '0';
        end if;

        -- Setting the value (0 to 9 is equal to 00110000 to 00111001)
        if (InitDone = '1') then
            if (counter < 10) then
                LCD_RS<='1';
                LCD_RW<='0';
                case counter is
                    when 0 =>
                            LCD_DB <="00110000";
                    when 1 =>
                            LCD_DB <="00110001";
                    when 2 =>
                            LCD_DB <="00110010";
                    when 3 =>
                            LCD_DB <="00110011";
                    when 4 =>
                            LCD_DB <="00110100";
                    when 5 =>
                            LCD_DB <="00110101";
                    when 6 =>
                            LCD_DB <="00110110";
                    when 7 =>
                            LCD_DB <="00110111";
                    when 8 =>
                            LCD_DB <="00111000";
                    when 9 =>
                            LCD_DB <="00111001";
                    when others =>
                            LCD_DB <="00000000";
                end case;
            -- if counter is greater than 10, then put the number in two addresses.
            elsif (counter > 9) then

                LCD_DB <="00000000";
                tempcounter :=counter;
                for i in 0 to 8 loop
                    if tempcounter > 9 then
                        tempcounter := tempcounter - 10;
                    end if;
                end loop;
                tencounter := counter - tempcounter;

                case tencounter is
                    when 0 =>
                            LCD_DB <="00110000";
                    when 1 =>
                            LCD_DB <="00110001";
                    when 2 =>
                            LCD_DB <="00110010";
                    when 3 =>
                            LCD_DB <="00110011";
                    when 4 =>
                            LCD_DB <="00110100";
                    when 5 =>
                            LCD_DB <="00110101";
                    when 6 =>
                            LCD_DB <="00110110";
                    when 7 =>
                            LCD_DB <="00110111";
                    when 8 =>
                            LCD_DB <="00111000";
                    when 9 =>
                            LCD_DB <="00111001";
                    when others =>
                            LCD_DB <="00000000";
                end case;

                LCD_RS<='0';
                LCD_RW<='0';
                LCD_DB(7)<='1';
                LCD_DB(6 downto 1) <= "000000";
                LCD_DB(0) <='1';

                case tempcounter is
                    when 0 =>
                            LCD_DB <="00110000";
                    when 1 =>
                            LCD_DB <="00110001";
                    when 2 =>
                            LCD_DB <="00110010";
                    when 3 =>
                            LCD_DB <="00110011";
                    when 4 =>
                            LCD_DB <="00110100";
                    when 5 =>
                            LCD_DB <="00110101";
                    when 6 =>
                            LCD_DB <="00110110";
                    when 7 =>
                            LCD_DB <="00110111";
                    when 8 =>
                            LCD_DB <="00111000";
                    when 9 =>
                            LCD_DB <="00111001";
                    when others =>
                            LCD_DB <="00000000";
                end case;

            end if;
        end if;
    end if;

end process InitAndSet;


end Behavioral;

Here are the User Constraints:

-- Constraints
NET "LCD_E" LOC = "AB4" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "LCD_RS" LOC = "Y14" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "LCD_RW" LOC = "W13" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "LCD_DB<7>" LOC = "Y15" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "LCD_DB<6>" LOC = "AB16" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "LCD_DB<5>" LOC = "Y16" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "LCD_DB<4>" LOC = "AA12" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "LCD_DB<3>" LOC = "AB12" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "LCD_DB<2>" LOC = "AB17" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "LCD_DB<1>" LOC = "AB18" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;
NET "LCD_DB<0>" LOC = "Y13" | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = SLOW ;

As I've seen this program should activate the LCD Display since I've clear all of the old saved things in the memory, I've set the cursor to 0 location and then on specific number that increments (in the main project) it indicates the number on the screen. I've taken the constraints and the encoding directly from the User Manual for the Spartan 3AN - Beginner Kit.

Am I missing something? It acts as it is not powered or something.

Thanks in advance, Bojan Matovski

Was it helpful?

Solution

if (clk'event and clk='1') then
    if (InitDone = '0') then
    -- Enabling
        LCD_E <='1';

    -- Clear Screen
        LCD_RS<='0';
        LCD_RW<='0';
        LCD_DB(7 downto 1) <= "0000000";
        LCD_DB(0) <= '1';
        etc etc etc.....

One problem: You're missing a state machine in this first part. Check out Case statements and how they work with state machines. What will happen in the code you wrote is that LCD_RD, LCD_RW, etc will just be replaced with the LAST line of code that you have in that if statement. Everything prior to that will be unused.

Another problem: InitDone never gets set to '1'. Ever.

Yet another problem:

for i in 0 to 8 loop
    if tempcounter > 9 then
         tempcounter := tempcounter - 10;
    end if;
end loop;

This for loop doesn't behave the way you think it does. You need to read about for loops in synthesizable code. They do not behave like C for loops.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top