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

How can I detect vector changes in other processes?

Altera_Forum
Honored Contributor II
2,331 Views

Hi All, 

 

I’d like to experiment with various frequency & duty cycles to control a little motor with PWM. I’m using a DE0 devboard and the frequency & duty cycles are user programmable with the switches. My problem is that I don’t know how to reset my signals to 0 when either SW_FREQUENCY_SELECT_VECTOR or SW_DUTY_CYCLE_VECTOR is changed ( devkit switches are toggled) .  

How can I detect vector changes in other processes?  

 

 

 

My code: 

 

 

LIBRARY IEEE; 

use IEEE.STD_LOGIC_1164.ALL; 

use IEEE.STD_LOGIC_UNSIGNED.ALL; 

use IEEE.STD_LOGIC_ARITH.ALL; 

 

--FREQUENCY CALCULATION 

--50 000 000 50MHz 

-- 1 000 000 1MHz 

-- 20 000 20kHz 

-- 

-- 

--50 000 000 / 20 000 = 2500 "0000100111000100"; - 20kHz 

-- 

--250000ns 

--250us 

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

-- 

-- 0 000 100Hz 500000 "1111010000100100000" 

-- 1 001 1000Hz 50000 "0001100001101010000" 

-- 2 010 2200Hz 22727 "0000101100011000111" 

-- 3 011 5000Hz 10000 "0000010011100010000" 

-- 4 100 10000Hz 5000 "0000001001110001000" 

-- 5 101 15000Hz 3333 "0000000110100000101" 

-- 6 110 22000Hz 2272 "0000000100011100000" 

-- 7 111 32000Hz 1562 "0000000011000011010" 

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

--DUTY CYCLE CALCULATION 

-- duty_cycle_stop = ( SW_FREQUENCY_VECTOR / 100 ) * SW_DUTY_CYCLE_VECTOR  

-- example  

-- 1250 = ( 2500 / 100 ) * 50  

-- 

 

ENTITY PWM5 IS 

PORT( 

CLK : IN STD_LOGIC ; 

LED0,LED1,LED2 : OUT STD_LOGIC ; 

SW_VECTOR : IN std_logic_vector(9 downto 0); 

 

BUTTON0,BUTTON1,BUTTON2 : IN STD_LOGIC ; 

GPIO0_PIN2,GPIO0_PIN4 : OUT STD_LOGIC  

); 

END PWM5; 

 

 

architecture PWMARCH of PWM5 is 

 

 

alias RESET : STD_LOGIC is BUTTON0; 

alias PWM_PIN : STD_LOGIC is GPIO0_PIN2; 

alias SW_FREQUENCY_SELECT_VECTOR : std_logic_vector(2 downto 0) is SW_VECTOR(9 downto 7); 

alias SW_DUTY_CYCLE_VECTOR : std_logic_vector(6 downto 0) is SW_VECTOR(6 downto 0); 

 

signal count,duty_count : integer:=0; 

signal duty_cycle_stop : integer:=0; 

signal duty_cycle : STD_LOGIC; 

signal SW_FREQUENCY_VECTOR : std_logic_vector(18 downto 0) :="0001100001101010000"; -- 1 50000 1000Hz  

 

begin 

 

--process(SW_FREQUENCY_SELECT_VECTOR,SW_VECTOR ) 

process(SW_FREQUENCY_SELECT_VECTOR) 

begin 

 

case SW_FREQUENCY_SELECT_VECTOR is 

 

when "000" => 

SW_FREQUENCY_VECTOR <= "1111010000100100000"; -- 0 500000 100Hz  

when "001" => 

SW_FREQUENCY_VECTOR <= "0001100001101010000"; -- 1 50000 1000Hz  

when "010" => 

SW_FREQUENCY_VECTOR <= "0000101100011000111"; -- 2 22727 2200Hz  

when "011" => 

SW_FREQUENCY_VECTOR <= "0000010011100010000"; -- 3 10000 5000Hz  

when "100" => 

SW_FREQUENCY_VECTOR <= "0000001001110001000"; -- 4 5000 10000Hz  

when "101" => 

SW_FREQUENCY_VECTOR <= "0000000110100000101"; -- 5 3333 15000Hz  

when "110" => 

SW_FREQUENCY_VECTOR <= "0000000100011100000"; -- 6 2272 22000Hz  

when "111" => 

SW_FREQUENCY_VECTOR <= "0000000011000011010"; -- 7 1562 32000Hz  

-- will never reach this 

when others => 

SW_FREQUENCY_VECTOR <= "0000010011100010000"; 

end case; 

 

end process; 

 

 

-- Update duty cycle  

--process(SW_DUTY_CYCLE_VECTOR,SW_FREQUENCY_VECTOR,SW_FREQUENCY_SELECT_VECTOR,SW_VECTOR) 

process(SW_DUTY_CYCLE_VECTOR,SW_FREQUENCY_VECTOR) 

begin 

-- duty_cycle_stop <= ( SW_FREQUENCY_VECTOR / 100 ) * SW_DUTY_CYCLE_VECTOR;  

duty_cycle_stop <= ( conv_integer(SW_FREQUENCY_VECTOR) / 100 ) * conv_integer(SW_DUTY_CYCLE_VECTOR);  

end process; 

 

 

-- main process  

process(CLK) 

begin  

 

if(RESET = '0') then 

count <= 0; 

duty_count <= 0; 

duty_cycle <='0'; 

 

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

 

count <= count +1; --increment counter. 

 

--see whether counter value is reached,if yes turn on the duty cycle 

if(count >= conv_integer(SW_FREQUENCY_VECTOR)) then 

count <= 0; 

duty_count <= 0; 

LED2 <='1'; 

PWM_PIN <='1'; 

duty_cycle <='1'; 

end if; 

 

-- Duty cycle  

if ( duty_cycle = '1' ) then 

duty_count <= duty_count +1;  

-- keep duty cycle high until duty_cycle_stop is reached 

if(duty_count = duty_cycle_stop ) then 

LED2 <= '0'; 

PWM_PIN <='0'; 

duty_cycle <='0'; 

end if; 

end if; 

end if; 

end process;  

 

 

 

end PWMARCH; 

 

 

 

 

Thanks, 

James
0 Kudos
4 Replies
Altera_Forum
Honored Contributor II
999 Views

register them, and then look for a rising or falling edge on inside the clocked process: 

 

if rising_edge(clk) then if input = '1' and input_reg = '0' then --rising edge --reset end if; input_reg <= input; end if;
0 Kudos
Altera_Forum
Honored Contributor II
999 Views

Hi Tricky, 

 

Your solution would work if I was looking for a change in a STD_LOGIC but I need to detect changes on STD_LOGIC_VECTOR. Shall I check rising or falling edges on every bit in a vector?
0 Kudos
Altera_Forum
Honored Contributor II
999 Views

If you don't care about whether its a rising or falling edge can't you just use the /= operator (reg /= input)? Not sure how fast you are clocking the register but if it is a slow clock I think this would be fine.

0 Kudos
Altera_Forum
Honored Contributor II
999 Views

The solution is exactly the same: register it and use the inequality: 

 

if input /= input_reg then
0 Kudos
Reply