2013-08-13 3 views
0

저는 VHDL에있어서 정말 새로운 제품입니다. KIT가 주도하는 기계 장치를 만들고 싶습니다. 내 코드는 다음과 같이 작동해야합니다. led0에서 led7까지 light-led에 대해 18 개의 다른 상태를 사용합니다. 그리고 led7에서 led0 등으로 돌아옵니다. 실제로 상태와 select 함수를 사용하여 원하는 것을 수행하고 꿈,하지만 난이 모드를 터보 싶었 및이 코드에 대한 다른 2 pwm 신호를 추가하십시오. 나는 pwm 신호를 썼지 만 그럴 수는 없다.PWM 신호가 vhdl-KIT에서 구동되었습니다.

현재 상태에 따라 다릅니다. 예를 들어. 내가 S5에있을 때, 나는 this-

led5-100 % led4-60 % led3-20 %

과 같은 몇 가지를하고 싶지 나는 다른의 PWM 신호를 작성해야 문제인가 2 가지 절차, 또는 그 작업과 관련하여 어떻게해야합니까? 도움 주셔서 감사합니다.

Here is my code: 

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
use IEEE.STD_LOGIC_UNSIGNED.ALL; 
use IEEE.STD_LOGIC_ARITH.ALL; 

entity knight_rider is 
port(
LED0, LED1, LED2, LED3, LED4, LED5, LED6, LED7: out std_logic; 
clk, reset: in std_logic); 

end knight_rider; 

architecture Behavioral of knight_rider is 
type state_type is (start0,s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15,s16); 
signal current_s: state_type; 
signal Counter: std_logic_vector(24 downto 0); 
signal temp1_20: std_logic; 
signal temp1_60: std_logic; 
signal temp2_20: std_logic; 
signal temp2_60: std_logic; 
signal temp3_20: std_logic; 
signal temp3_60: std_logic; 
signal counter1_20: integer range 0 to 2048 := 0; -- counter1 for 20% bright 
signal counter1_60: integer range 0 to 2048 := 0; -- counter1 for 60% bright 
signal counter2_20: integer range 0 to 2048 := 0; -- counter2 for 20% bright 
signal counter2_60: integer range 0 to 2048 := 0; -- counter2 for 60% bright 
signal clkout60,clkout20: std_logic; 
begin 

knight_rider: process (clk, reset) 

begin 

    if (reset='1') then 
    current_s <=start0; 

    elsif rising_edge(clk) then 
    counter1_60<=counter1_60 + 1;     --pwm for 60% briht 

     if (counter1_60 = 2048) then 
       temp1_60 <= '1'; 

       counter1_60 <= 0; 

    end if; 

       if temp1_60 = '1' then 
        temp3_60 <='1'; 
        temp2_60 <= '1'; 
        temp1_60 <='0'; 
       end if; 

       if temp3_60 = '1' then 

        counter2_60 <=counter2_60 + 1; 
        if (counter2_60 =1230) then 
          temp2_60 <= '0'; 
          temp3_60 <='0'; 
          counter2_60 <= 0; 
          clkout60<=temp2_60; 
        end if; 
       end if; 
    counter1_20<=counter1_20 + 1; --pwm for 20% bright 

     if (counter1_20 = 2048) then 
       temp1_20 <= '1'; 

       counter1_20 <= 0; 

      end if; 

       if temp1_20 = '1' then 
        temp3_20 <='1'; 
        temp2_20 <= '1'; 
        temp1_20 <='0'; 
       end if; 

       if temp3_20 = '1' then 

        counter2_20 <=counter2_20 + 1; 
        if (counter2_20 <=410) then 
          temp2_20 <= '0'; 
          temp3_20 <='0'; 
          counter2_20 <= 0; 
          clkout20<=temp2_20; 
        end if; 
       end if; 

     Counter<= Counter + 1;        -- statements: From here, its actually do what I want... 
     if Counter="10011000100101101000000" then  -- but with clkout20, and clkout60 something's wrong 
      Counter<="0000000000000000000000000"; 
      case current_s is 

       when start0 => 
        current_s <=s0; 

       when s0 => 
        if (reset ='0') then 
         current_s <=s1; 

        else 
         current_s <= start0; 
        end if; 

       when s1 => 
        if (reset = '0') then 
         current_s <=s2; 
        else 
         current_s <= s0; 
        end if; 

       when s2 => 
        if (reset = '0') then 
         current_s <=s3; 

        else 
         current_s <= s1; 
        end if; 

       when s3 => 
        if (reset = '0') then 
         current_s <=s4; 

        else 
         current_s <= s2; 
        end if; 

       when s4 => 
        if (reset = '0') then 
         current_s <=s5; 

        else 
         current_s <= s3; 
        end if; 

       when s5 => 
        if (reset = '0') then 
         current_s <=s6; 

        else 
         current_s <= s4; 
        end if; 

       when s6 => 
        if (reset = '0') then 
         current_s <=s7; 

        else 
         current_s <= s5; 
        end if; 

       when s7 => 
        if (reset = '0') then 
         current_s <=s8; 

        else 
         current_s <= s6; 
        end if; 

       when s8 => 
        if (reset = '0') then 
         current_s <=s9; 
        else 
         current_s <= s7; 
        end if; 

       when s9 => 
        if (reset = '0') then 
         current_s <=s10; 
        else 
         current_s <= s8; 
        end if; 

       when s10 => 
        if (reset = '0') then 
         current_s <=s11; 
        else 
         current_s <= s9; 
        end if; 

       when s11 => 
        if (reset = '0') then 
         current_s <=s12; 
        else 
         current_s <= s10; 
        end if; 

       when s12 => 
        if (reset = '0') then 
         current_s <=s13; 
        else 
         current_s <= s11; 
        end if; 


       when s13 => 
        if (reset = '0') then 
         current_s <=s14; 
        else 
         current_s <= s12; 
        end if; 

       when s14 => 
        if (reset = '0') then 
         current_s <=s15; 
        else 
         current_s <= s13; 
        end if; 

       when s15 => 
        if (reset = '0') then 
         current_s <=s16; 
        else 
         current_s <= s14; 
        end if; 

       when s16=> current_s <= s0; 

       when others => null; 
      end case; 
      end if; 
      end if; 

end process; 


       with current_s select 
       LED0 <= '1' when s0|s15, 
          'clkout60' when s1, 
          'clkout20' when s2, 
          '0' when others; 

       with current_s select 
       LED1 <= '1' when s1|s14, 
          'temp2_60' when s2|s15, 
          'clkout20' when s3, 
          '0' when others; 

       with current_s select 
       LED2 <= '1' when s2|s13, 
          'clk_out_60' when s3|s14, 
          'clk_out_20' when s4|s15, 
          '0' when others; 

       with current_s select 
       LED3 <= '1' when s3|s12, 
          'clk_out_60' when s4|13, 
          'clk_out_20' when s5|s14, 
          '0' when others; 

       with current_s select 
       LED4 <= '1' when s4|s11, 
          'clk_out_60' when s5|12, 
          'clk_out_20' when s6|s13, 
          '0' when others; 

       with current_s select 
       LED5 <= '1' when s5|s10, 
          'clk_out_60' when s6|s11, 
          'clk_out_20' when s7|s12, 
          '0' when others; 

       with current_s select 
       LED6 <= '1' when s6 | s9, 
          'clk_out_60' when s7|s10, 
          'clk_out_20' when s8|s11, 
          '0' when others; 

       with current_s select 
       LED7 <= '1' when s7 |s8, 
          'clk_out_60' when s9, 
          'clk_out_20' when s10, 
          '0' when others; 

    end Behavioral; 

답변

1

따라서 쉽게 당신이 일할 수있는 코드를 얻을 할 수있어 그 구조와 가독성에 도움이 될 수 있습니다 당신이 별도의 프로세스로 PWM과 코드를 다시 작성하지만 을 필요하지 된다. 일부 관찰과 제안 다음 다른 PWM 신호의 생성 직접 상태 업데이트에 연결하거나 드라이브를 LED되지 않기 때문에

  • , 별도의 프로세스에서 PWM 출력을 생성, 은 그래서에 당신을 위해 아마 쉽게 관련없는 기능을 별도의 프로세스로 분리하면 좋은 개요를 유지할 수 있습니다. 리셋 의 첫 부분을 통해 비동기 리셋로서 사용되기 때문에, 그 과정에서, 두 번째 부분은 영향을 취하므로 경우 '0'의

  • 리셋 신호 검사는 knight_rider 과정에서 케이스로부터 제거 될 수있다 항상 '0'입니다. 당신이 상태 그 방법을 사용하여 표시하기 때문에 대신 state_type에서 18 개 상태

  • , 당신은, 업 - 다운 카운터로 제어되는 std_logic_vector 사용을 고려할 수 있습니다.

  • 가 대신 별도의 출력 std_logic_vector(0 to 7), 으로 LED와 사용 std_logic_vector 상태 색인, 위의 LED를 제안 확인, 각 LED의 그래서 명시 적 드라이브 코드에 방지 할 수 있습니다. 이 훨씬 쉽게 값을 읽을 수 있기 때문에

  • 대신 사용 CONV_STD_LOGIC_VECTOR(5000000, Counter'length)Counter = "10011000100101101000000"

    .

  • 가독성을 위해 Counter <= "0000000000000000000000000" 대신 Counter <= (others => '0') 또는 CONV_STD_LOGIC_VECTOR (0, 카운터 길이)를 사용하십시오.

  • 일관된 들여 쓰기를 사용하면 코드의 가독성을 크게 향상시킬 수 있습니다. 3 개를 가지고 있지 않다면 end case; end if; end if;가 모두 에있다. 또한 탭을 사용할 때 발생할 수있는 이상한 서식을 방지하려면 들여 쓰기 용 공간 만 사용하십시오.clkout60 및 clkout20 이후 with ... select

  • 구문 오류는 'clkout60'과 'clkout20', 그냥 일반 clkout60 및 clkout20을하지 한다.

  • with ... select의 clk_out_20 및 clk_out_60은 존재하지 않지만 그 중 이 진행 중일 수 있습니다.