Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
12 years ago

For loop, array and a step motor, VHDL

I'm trying to implement a sequence in order to use a step motor using VHDL. Since I'm really new to VHDL I can't see what's missing in my code. I want to loop through an array to give the different steps to my variable named motor.

I'd appreciate any help.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity main is
    Port ( motor : out  STD_LOGIC_VECTOR (3 downto 0));
end main;
architecture Behavioral of main is
    type my_array is array (0 to 6) of std_logic_vector(2 downto 0); 
    signal secuencia : my_array;
    secuencia := ("0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111");
    
begin
    variable i : std_logic:= '1';
    for i in secuencia' range loop
      motor <= secuencia(i);
   end loop;
end Behavioral;

These are the errors:

ERROR:HDLCompiler:806 - "C:/Users/main.vhd" Line 12: Syntax error near "secuencia".
ERROR:HDLCompiler:806 - "C:/Users/main.vhd" Line 15: Syntax error near ":=".
ERROR:HDLCompiler:806 - "C:/Users/main.vhd" Line 16: Syntax error near "loop".
ERROR:HDLCompiler:806 - "C:/Users/main.vhd" Line 18: Syntax error near "loop".
ERROR:ProjectMgmt:496 - 4 error(s) found while parsing design hierarchy.

5 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Looking the code it seems you are a C programmer. The for loop statement in vhdl it's different from the for sentence of C. For loop is not a sequential statement. It is used when you need to copy paste many times a circuit cell ( iterative circuit ).

    Probably you're tried to explore the 8 output value you write in secuencia. A counter may solve it:

    architecture Behavioral of main is

    signal sec_reg, sec_next : unsigned(2 downto 0);

    secuencia := ("0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111");

    begin

    process( clr_n, clk )

    begin

    if( clr_n = '0' ) then

    sec_reg <= ( others => '0' );

    sal_reg <= "0000";

    elsif( clk'event and clk = '1 ) then

    sec_reg <= sec_next;

    sal_next <= sal_next;

    end if;

    end process;

    sec_next <= sec_reg + 1;

    motor <= sal_reg;

    process(sec_reg)

    begin

    case sec_reg is

    when "0000" =>

    sal_next <= "0000";

    when "0001" =>

    sal_next <= "0001";

    -- complete the rest

    end case;

    end process;

    end Behavioral;

    There something missing in this code. To drive a stepper motor you need to slow down the clock.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hey! Thank you so much for your answer. Actually I'm more into C so finally I decided to use a PIC. Anyways, I am going to try it again using VHDL.

    Here is what I was trying to do:

    char values = {0B01000, 0B01100, 0B00100, 0B00110, 0B00010, 0B00011, 0B00001, 0B01001};
      void motor(){
        short i;
        for (i = 0; i<7; i++){
          PORTC= values;
          Delay_ms(1);
        }
      }
    

    Thanks again for your time!! :)
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    The for loop statement in vhdl it's different from the for sentence of C. For loop is not a sequential statement. It is used when you need to copy paste many times a circuit cell ( iterative circuit ).

    --- Quote End ---

    Sorry to be a pedant, but a for loop IS a sequential statement. It will work exactly like it's C counterpart in the right situations - but only in simulation. The Synthesisor will unroll the loop and create parrallel logic as you describe, but the behaviour of a for loop can be important in testbenches. If you want "sequential" code inside a for loop, you can use a variable instead of a signal updating between iterations (but then you'll get a long chain of logic).
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    look I developed this code for a stepper motor with a sequence and I hope you serve :)

    library ieee;

    use ieee.std_logic_1164.all;

    use ieee.std_logic_arith.all;

    entity mtrpas is

    port(

    clock,reset:in std_logic;

    clkout:inout std_logic;

    push_l ,push_r: in std_logic;

    pasos2: out std_logic_vector(3 downto 0);

    pasos: out std_logic_vector(3 downto 0));

    end mtrpas;

    architecture archi_mtrpas of mtrpas is

    CONSTANT max: INTEGER := 50000000;

    CONSTANT half: INTEGER := max/10;

    SIGNAL count: INTEGER RANGE 0 TO half;

    begin

    PROCESS

    BEGIN

    WAIT UNTIL clock'EVENT and clock= '1';

    IF (count < max) THEN

    count <= count + 1;

    ELSE

    count <= 0;

    END IF;

    IF (count < half)THEN

    clkout <= '0';

    ELSE

    clkout <= '1';

    END IF;

    END PROCESS;

    --------------------------------------------

    process(push_l ,push_r,reset,clkout)

    variable cuenta: integer range 0 to 5:=0;

    begin

    if clkout'event and clkout='1' then

    if(reset='0') then

    cuenta:=0;

    else

    if(push_l='1') then

    cuenta:=cuenta+1;

    if(cuenta=5) then

    cuenta:=0;

    end if;

    end if;

    if(push_r='1') then

    cuenta:=cuenta-1;

    if(cuenta=0) then

    cuenta:=4;

    end if;

    end if;

    end if;

    end if;

    case cuenta is

    when 0=> pasos<="0000";pasos2<="0000";

    when 1=> pasos<="1000";pasos2<="1000";

    when 2=> pasos<="0100";pasos2<="0100";

    when 3=> pasos<="0010";pasos2<="0010";

    when 4=> pasos<="0001";pasos2<="0001";

    when others => null;

    end case;

    end process;

    end archi_mtrpas;
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Can you give an example?:

    --- Quote Start ---

    If you want "sequential" code inside a for loop, you can use a variable instead of a signal updating between iterations (but then you'll get a long chain of logic).

    --- Quote End ---