Christopher Impey
Christopher Impey

Reputation: 15

VHDL clocked LED Sequence

this is my first post on this site, im studying VHDL for my Electronics degree and have to write a program that changes an LED sequence at each clock pulse for one sequence. i think i have cracked it but this is my first time using the VHDL language so im not sure if iv used the most efficient method. my code is.

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;


entity REG_LED is
 PORT(CLK:      IN  std_logic;              -- CLK input
     LEDS:      Out std_logic_vector (4 downto 0):= "11111"); -- initialise      output
End REG_LED;

ARCHITECTURE behavioral OF REG_LED IS
 SIGNAL Temp:   std_logic_vector (3 downto 0):= "0000"; -- initailise comparison signal
  BEGIN
    CLK_0_Process:  PROCESS (CLK)   -- begin 
    BEGIN 
    if Temp <= "0000" Then          -- State 0          
        if rising_edge(CLK) Then
            Temp <= "0001" ;
            LEDS <= "00001";    
        END IF;
     ELSIF Temp <= "0001" Then  -- State 1
        if rising_edge(CLK) Then
            Temp <= "0010" ;
            LEDS <= "00001";
     END IF;
     ELSIF Temp <= "0010" Then  -- State 2
        if rising_edge(CLK) Then
            Temp <= "0011" ;
            LEDS <= "11111";
     END IF;
     ELSIF Temp <= "0011" Then  -- State 3  
        if rising_edge(CLK) Then
            Temp <= "0100" ;
            LEDS <= "00000";
     END IF;
     ELSIF Temp <= "0100" Then  -- State 4
        if rising_edge(CLK) Then
            Temp <= "0101" ;
            LEDS <= "11111";
     END IF;
     ELSIF Temp <= "0101" Then  -- State 5
        if rising_edge(CLK) Then
            Temp <= "0110" ;
            LEDS <= "00100";
     END IF;
     ELSIF Temp <= "0110" Then  -- State 6
        if rising_edge(CLK) Then
            Temp <= "0111" ;
            LEDS <= "01010";
     END IF;
     ELSIF Temp <= "0111" Then  -- State 7
        if rising_edge(CLK) Then
            Temp <= "1000" ;
            LEDS <= "10001";
     END IF;
     ELSIF Temp <= "1000" Then  -- State 8
        if rising_edge(CLK) Then
                LEDS <= "10001";
     END IF;
    END IF;
    END PROCESS ;
END behavioral;

can anyone let me know if there is an alternative route that iv missed?

Many thanks

Upvotes: 0

Views: 1405

Answers (1)

Matthew
Matthew

Reputation: 13967

Well, I'd say it's an inefficient method, but, just like with any language, the more you learn the more efficient the code you are able to write. More importantly, you code is not synthesisable: you would not be able to produce hardware directly from it.

If you want your code to be synthesisable, you should stick to a template. Here is one such template for sequential logic with no asynchronous reset, which all synthesis tools should understand:

process(CLK)  -- nothing else should go in the sensitivity list
begin
    -- never put anything here
    if rising_edge(CLK) then  -- or falling_edge(CLK)
        -- put the synchronous stuff here
        -- ie the stuff that happens on the rising or falling edge of the clock
    end if;
     -- never put anything here
end process;        

So, you need to refactor your code to fit this template, ie something along the lines of:

process(CLK)
begin
  if rising_edge(CLK) then
    if Temp <= "0000" Then          -- State 0          
      Temp <= "0001" ;
      LEDS <= "00001";    
    ELSIF Temp <= "0001" Then  -- State 1
      Temp <= "0010" ;
      LEDS <= "00001";
    ELSIF Temp <= "0010" Then  -- State 2

    -- etc etc

    end if;
  end if;
end process;

It seeing that Temp is just counting, it would be much more efficient (in terms of elegance of solution and fewer lines of code) to use the line Temp <= Temp + 1; in your code and to drive the LEDS signal using a case statement (in a separate process). But then you'd have to learn about type conversion and the numeric_std package and case statements, which presumably you haven't learnt about yet.

Upvotes: 1

Related Questions