Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Servo component blocking my output pin.. how does it interfere with my other componen

Status
Not open for further replies.

kidi3

Full Member level 1
Joined
Mar 31, 2013
Messages
98
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Activity points
2,350
I at moment trying to combine a project consisting of 3 components. <ADC>, <LED>, Control (top-module), and <servo>.

the Idea is that the LED , start the ADC, and the ADC tells the Control unit when it can read from it , and based on the value the control unit reads, the servo moves.


Until now the connection between the ADC,LED and control seem to work. But when Instantiate the component Servo, and try to add it it simply breaks the looks...


I really don't have any idea on how this could occur, and would be very grateful if anyone could help me debugging this issue.


It interfers with my LED components output.
which I don't get. Servo should be running in the background, and not interfere with anything else..

Here is some code snippets of the process within each components.

counter.vhd

Code:
readBlock: process(clk,read_adc_sig, adc_value_sig,led_on_sig,redCount,greenCount,blueCount)
variable iterations: integer range 0 to 40 :=0 ;
begin
if rising_edge(clk) then 
    if iterations < 30 then 
        led_on_sig <= '1';
    elsif iterations >= 30 then 
        led_on_sig <= '0';        
        if redCount < greenCount then 
            if greenCount > blueCount then 
                MAX_LED_r <= '0';
                MAX_LED_g <= '0';
                MAX_LED_b <= '0';
                --GreenCount max
                --Måler forkert
                --direc_sig <= "10";
             end if;   
        elsif redCount < blueCount then 
            if  blueCount > greenCount then 
                MAX_LED_r <= '1';
                MAX_LED_g <= '0';
                MAX_LED_b <= '1';                
                -- BlueCount max
                --direc_sig <=  "00";
            end if;
        elsif greenCount < redCount then 
            if redCount > blueCount then 
                MAX_LED_r <= '0';
                MAX_LED_g <= '1';
                MAX_LED_b <= '0'; 
                -- redCount max
                --direc_sig <= "11";
            end if;         
     end if;        
        redCount <= 0;
        blueCount <= 0;
        greenCount <= 0;                
        
        iterations:=0;
        
    end if;    
    if led_on_sig = '1' then   
          if read_adc_sig = '1' then       
                if adc_value_sig = "1111111111" then 
                    redCount <= redCount +1;
                    adc_read_sig <= '1';
                    iterations := iterations + 1;                     
                elsif adc_value_sig = "0000000000" then 
                    blueCount <= blueCount +1;
                    adc_read_sig <= '1';
                    iterations := iterations + 1; 
                else
                    greenCount <= greenCount +1; 
                    adc_read_sig <= '1';
                    iterations := iterations + 1; 
                end if;                                               
            -- delay to settle LED, so ADC turned off--
          elsif read_adc_sig = '0' then      
                adc_read_sig <= '0'; 
          end if;                       
                  
        if adc_read_sig = '1'  then 
            next_state_sig <= '1'; -- Saying start next state => turn off start_adc... 
        else 
            next_state_sig <= '0'; 
        end if; 
    else
        next_state_sig <= '0'; -- Saying start next state => turn off start_adc... 
    end if;
 end if;   
end process;


led.vhd
Code:
LEDprocess: process(led_on, state)
begin 
    if led_on = '1' then 
              case state is 
                 when red => 
                    led_red  <= '1';
                    led_green<= '0';
                    led_blue <= '0';
                    stateS <= "10";
                when green =>
                    led_red  <= '0';   
                    led_green<= '1';
                    led_blue <= '0';
                    stateS <= "01";
                when blue =>           
                    led_red   <= '0';
                    led_green <= '0';    
                    led_blue  <= '1'; 
                    stateS <= "11";   
                end case;      
    elsif led_on = '0' then   
          led_blue <= '0';
          led_red <= '0';
          led_green <= '0';
          stateS <= "00";             
    else
        led_blue <= '0';
        led_red <= '0';
        led_green <= '0';   
        stateS <= "00";             
    end if; 
end process;

state_changer: process(next_state,state, clk)
variable count: integer range 0 to 100000000 :=0;
begin    
    if next_state = '1' then 
        if count > 650 then 
            if state = red then
                state <= green;
            elsif state = green then 
                state <= blue;
            elsif state = blue then 
                state <= red;
            end if;
        end if;       
        count:= 0;        
    elsif rising_edge(clk) then         
        if count > 650 then 
            start_adc <= '1';
            --adc_on <= '1';
        elsif count <650 then 
            start_adc <= '0'; 
            --adc_on <= '1';  
        end if;   
        count  := count  +1 ;               
    end if;
    
end process;

servo.vhd
Code:
process (clk)
	--variable to count the clock pulse
variable count : integer range 0 to 1000000;
begin
if (rising_edge(CLK)) then
    count:= count+1;
    if count = 1000000 then
		count:= 0;
	end if;	
end if;  		
		
    case direc is
		    --increasing the count for each clock cycle				
			 when "11" =>
			     if count < 960000 then    --  900000, 950000 , 960000
            	     PWM_motor <= '0';
                 else 
            	     PWM_motor <= '1';
                 end if;
			 when "00" =>
			     if count < 900000 then    --  900000, 950000 , 960000
                    PWM_motor <= '0';
                 else 
                     PWM_motor <= '1';
                 end if;
              when others =>
                 if count < 950000 then    --  900000, 950000 , 960000
                       PWM_motor <= '0';
                 else 
                       PWM_motor <= '1';
                 end if;        
	        end case;			
end process;

I really don't get how this can become a problem to combine these within the top module , control. Can any of you see where i might affect some signals?
 

hi kidi3
-------
1. it is really hard to understand what your problem is from your depiction (what do you mean by "breaks the looks...").
2. again you didn't use VHDL code syntax.
3. if you don't have any company security issues , you should always post your entire code.

thanks a lot.
arui.
 

Hi again..

1. My problem is that this loop which consist of the connection between these element breaks, when i add the component servo .

Counter is the top module here, which controls the loop. Without the servo component in the top module, the led_red, led_green and led_blue keeps changing being on,

as seen here

Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
if led_on = '1' then 
              case state is 
                 when red => 
                    led_red  <= '1';
                    led_green<= '0';
                    led_blue <= '0';
                    stateS <= "10";
                when green =>
                    led_red  <= '0';   
                    led_green<= '1';
                    led_blue <= '0';
                    stateS <= "01";
                when blue =>           
                    led_red   <= '0';
                    led_green <= '0';    
                    led_blue  <= '1'; 
                    stateS <= "11";   
                end case;      
    elsif led_on = '0' then   
          led_blue <= '0';
          led_red <= '0';
          led_green <= '0';
          stateS <= "00";             
    else
        led_blue <= '0';
        led_red <= '0';
        led_green <= '0';   
        stateS <= "00";             
    end if;



when counter send a next state signal to it , which it does when the adc set the read_adc_sig high to tell counter.vhd, that it can read the adc value, and when it has read the adv_value, add_read_sig is set high which sets next_state high , making Led.vhdl change state.

(from counter.vhd)

Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
if led_on_sig = '1' then   
          if read_adc_sig = '1' then       
                if adc_value_sig = "1111111111" then 
                    redCount <= redCount +1;
                    adc_read_sig <= '1';
                    iterations := iterations + 1;                     
                elsif adc_value_sig = "0000000000" then 
                    blueCount <= blueCount +1;
                    adc_read_sig <= '1';
                    iterations := iterations + 1; 
                else
                    greenCount <= greenCount +1; 
                    adc_read_sig <= '1';
                    iterations := iterations + 1; 
                end if;                                               
            -- delay to settle LED, so ADC turned off--
          elsif read_adc_sig = '0' then      
                adc_read_sig <= '0'; 
          end if;                       
                  
        if adc_read_sig = '1'  then 
            next_state_sig <= '1'; -- Saying start next state => turn off start_adc... 
        else 
            next_state_sig <= '0'; 
        end if; 
    else
        next_state_sig <= '0'; -- Saying start next state => turn off start_adc... 
    end if;



(from led.vhd)

Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
state_changer: process(next_state,state, clk)
variable count: integer range 0 to 100000000 :=0;
begin    
    if next_state = '1' then 
        if count > 650 then 
            if state = red then
                state <= green;
            elsif state = green then 
                state <= blue;
            elsif state = blue then 
                state <= red;
            end if;
        end if;       
        count:= 0;        
    elsif rising_edge(clk) then         
        if count > 650 then 
            start_adc <= '1';
            --adc_on <= '1';
        elsif count <650 then 
            start_adc <= '0'; 
            --adc_on <= '1';  
        end if;   
        count  := count  +1 ;               
    end if;
end process;



but when I add the servo component into the top module, the led_red, led_green, led_blue doesn't change but keeps staying lid.

The way i want it added it into my top module can be seen in counter.

If an ADC_value = "1111111111" redCount increments
if an ADC_value = "0000000000" blueCount increments
If and ADC_value is something else greenCount increments

If after 30 iterations redCount is highest among the three values , direc_sig will be set to "10"
which the servo motor would read, and move it toward a certain position using a certain duty cycle. direct_sig will be set to different values according to the one being the max value.

But that doesn't seem to work.. Firstly the led_red,led_green,led_blue doesn't change keep changing, even though next_state changes.. and no PWM is sent to the servo motors either..

2. added.

3. this consist of the parts which is related to the issue.. the other reason i haven't posted the complete the full code, is to prevent posting a wall of code, and making it even harder harder to understand.
 
Last edited:

perhaps it is better you will post :

project a (working project) [src +tb files]
project b (with the servo) [src +tb files]

then we might have a better chance to understand what you were doing wrong.
you can rar them or zip them if possible,
 
Last edited:

hi kidi3.
----------
it is nice of you to share your code.
now i think that if you share your project you should akso tell everybody :
1 where are the relevant files (for example : my source files for pjt A are in /my/pjt/a/src/files)
2 then what their names means (for example : my xxx.vhd file is servo file, ttt.vhd is the tb file).
3 how to compile them, run them (for example a compile.bat or compile.do file).
otherwise it is very difficult to understand where and what to do...
thanks alot arui
 

Where is the .xdc constraints file?
 

Well.. i used PlanAhead to compile.. so if you open the head.ppr it would open everything..
I can see that i mistype the name of my top module which is control.vhd.

All the src files (components) is in head/head.src/sources_1/imports/components
the top module is at head/head.src/sources_1/imports/control.vhd


the ones which are I am having problems is
/head/head.srcs/sources_1/imports/components/led_driver/led_driver.srcs/sources_1/new/led_driver.vhd
/head/head.srcs/sources_1/imports/components/PWM/project_2.srcs/sources_1/new/pwm.vhd
/head/head.srcs/sources_1/imports/new/control.vhd

User constraints file
/head/head.srcs/constrs_1/imports/new/impl.ucf
 

I looked at the PAR report.

Code:
INFO:Par:282 - No user timing constraints were detected or you have set the option to ignore timing constraints ("par
   -x"). Place and Route will run in "Performance Evaluation Mode" to automatically improve the performance of all
   internal clocks in this design. Because there are not defined timing requirements, a timing score will not be
   reported in the PAR report in this mode. The PAR timing summary will list the performance achieved for each clock.
   Note: For the fastest runtime, set the effort level to "std".  For best performance, set the effort level to "high".
----------------------------------------------
WARNING:Route:455 - CLK Net:MAX_LED_b_not0001 may have excessive skew because 
      2 CLK pins and 0 NON_CLK pins failed to route using a CLK template.
WARNING:Route:455 - CLK Net:next_state_sig may have excessive skew because 
      0 CLK pins and 15 NON_CLK pins failed to route using a CLK template.
WARNING:Route:455 - CLK Net:led_on_sig may have excessive skew because 
      1 CLK pins and 12 NON_CLK pins failed to route using a CLK template.

not sure if these are the cause of your problems, but they should be fixed.
 

Besides.. MAX_led_b ...

The next_state_sig, and Led_on are two signals which should be able to remove.. As it add unessesary timing skews..

- - - Updated - - -

I removed them.. both signal.. and doesn't seem to work..
I might have missed changing at some other place.. but.. it is not working now..

- - - Updated - - -

Picking on those values... flat lines led_red,led_green,led_blue..
Instead turning it on, and shutting it off
 
Last edited:

I have removed the presence of led_on..
but still... when give values to direc_sig which controls the direction the motor has to turn.
the led_red, led_green, led_blue stays low.
 

You seem to have an anti-pattern of using async logic in state machines. I would do the following:

1.) remove gated clocks.
Code:
-- replace this code:
p_gated_clk : process (clk, en) is
  if (en = '1') then -- the clock gate
    if (rising_edge(clk)) then -- the clock
      -- logic
    end if;
  end if;
end process;

-- with this code:
p_normal : process (clk) is
  if (rising_edge(clk)) then -- the clock
    if (en = '1') then -- the clock enable to registers
      -- logic
    end if;
  end if;
end process;
Clock gating is a legitimate thing to do, but should be done using the specialized resources in the FPGA.

2.) remove async control.
Code:
-- this weird code is removed
p_async_ctrl : process (clk, async) is
begin
  if (async = '1') then
    -- something that isn't a pure reset/set/load.  (async load can also be dangerous, but it does have full support in Altera devices and can be emulated in Xilinx devices)
  elsif (rising_edge(clk)) then
    -- normal logic
  end if;
end if;

-- and this is used
p_sync_ctrl : process (clk) is
begin
  if (rising_edge(clk)) then
    if (sync = '1') then
      -- code for the special case
    else
      -- normal code
    end if;
  end if;
end if;
Also, if you have any truely async inputs where setup/hold can't be ensured by design, you should resynchronize them by using a chain of 2 registers (sufficient for 50MHz).

3.) remove locally generated clocks and favor clock enables. This is in your ADC/SPI code.

4.) add timing constraints to the UCF, ensure they are met.

gated clocks, logic-generated clock, and async signals should be avoided. It is easy to get simulation mismatches and hard to constrain them. The issue is probably that some path was previous routed favorably, and any small addition of logic would cause it to be routed unfavorably.

You should also choose one indentation scheme and stick with it, or at least keep it consistent for the same file. It is also nice to name register-inferring variables with some indication of how you intended to use them, or use signals instead.

--edit: also, you have some adc input that you use to determine led color. perhaps there is an issue there. eg, a loose connection or device held in reset or etc...
 

I not sure where these things you mention is an issue here, but I tested it earlier today, and seems that the hardware has an PORt which kills the rest of the ports on the FPGA.. After I changed the port, everything started working as it should.
 

hi kidi3 :
see my remark about using sensitivity list in synchronous process.
in general it is best only to include the clock in synchronous process, if you are using asynchronous reset it is ok to add it, but dont add other inputs.
sensitivity.jpg
 

I am for some reason switching from GRB, instead of RGB?... why is that?
 

because before part of the process act like combinatoric process.
after you fix the sensitivity list it is change after clock event, and now you have a shift.

basically you need to separate synchronous and combinatoric processes.
 

so if I removed rising_edge CLk it wouldn't be a problem?
 

because before part of the process act like combinatoric process.
after you fix the sensitivity list it is change after clock event, and now you have a shift.

basically you need to separate synchronous and combinatoric processes.

No you don't. Using a sync and async process is an old coding style that has fallen out of favour and is more prone to errors.

@kidi. Keep everything in the synchronous process and follow vgoodtimes advice

- - - Updated - - -

Added. Having a extra signals in a sensitivity list on a synchronous process does nothing more than slow your simulation down. It wont affect the results.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top