Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
17043 Discussions

For loop, array and a step motor, VHDL

Altera_Forum
Honored Contributor II
4,739 Views

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.
0 Kudos
5 Replies
Altera_Forum
Honored Contributor II
3,185 Views

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.
0 Kudos
Altera_Forum
Honored Contributor II
3,185 Views

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!! :)
0 Kudos
Altera_Forum
Honored Contributor II
3,185 Views

 

--- 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).
0 Kudos
Altera_Forum
Honored Contributor II
3,185 Views

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;
0 Kudos
Altera_Forum
Honored Contributor II
3,185 Views

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 ---  

0 Kudos
Reply