2013-08-13 3 views
0

Je suis vraiment nouveau dans vhdl, et je veux faire un certain type de mécanisation dirigée KIT. Mon code devrait fonctionner comme ceci: j'utilise 18 états différents pour allumer les LED de led0 à led7, et il revient de led7 à led0, etc. Acctuellement mes états, et avec la fonction select ont fait ce que je veux, et cela a fonctionné comme un rêve, mais je voulais turbo ce mod, et ajouter 2 autres signaux pwm pour ce code. J'ai écrit les signaux pwm mais je ne peux pas utiliser ceux avec l'état du cas.Signal PWM dans vhdl-KIT led mechanizm

Cela dépend de l'état actuel. Par exemple. quand je suis s5, je veux faire un peu comme this-

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

Le problème est que je dois écrire les signaux MLI dans d'autres 2 processus, ou que devrais-je en faire pour travailler? Merci pour l'aide.

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; 

Répondre

1

Il n'est pas nécessaire que vous réécrivez le code avec PWM à un processus distinct, mais il peut aider sur la structure et la lisibilité, rendant ainsi plus facile pour vous d'obtenir le code au travail. Quelques observations et suggestions:

  • Créer les sorties PWM dans un processus distinct, étant donné que la génération des différents signaux PWM est pas directement liée à la mise à jour de l'état ou le lecteur LED, il est donc probablement plus facile pour vous gardez une bonne vue d'ensemble si vous séparez des fonctionnalités non liées dans des processus distincts.

  • contrôle du signal de remise à zéro peut être retiré pour « 0 » dans le cas du processus knight_rider , depuis la réinitialisation est utilisée en tant que remise à zéro asynchrone à travers la première partie de le cas dans ce processus, de sorte que lorsque la seconde partie prend effet , c'est toujours '0'.

  • au lieu des 18 états de state_type, vous pouvez envisager d'utiliser un std_logic_vector contrôlé comme un compteur vers le bas, car il semble que vous utilisez les états de cette façon.

  • faire de la LED en tant que std_logic_vector(0 to 7) lieu de sorties séparées, et l'utilisation de l'état de std_logic_vector suggéré ci-dessus, pour indexer les LEDs, entraînement de manière explicite de chaque LED peut être évitée dans le code.

  • Au lieu de Counter = "10011000100101101000000" utilisation CONV_STD_LOGIC_VECTOR(5000000, Counter'length), car cela rend la lecture la valeur beaucoup plus facile. Au lieu de Counter <= "0000000000000000000000000", utilisez Counter <= (others => '0') ou CONV_STD_LOGIC_VECTOR (0, longueur de compteur) pour plus de lisibilité.

  • Vous pouvez améliorer considérablement la lisibilité de votre code si vous utilisez une indentation cohérente, par ex. ne pas avoir les trois end case; end if; end if; tous au même niveau. N'utilisez également que de l'espace pour le retrait afin d'éviter tout formatage bizarre pouvant survenir lors de l'utilisation d'onglets.

  • Erreur de syntaxe dans with ... select, puisque clkout60 et clkout20 ne doit pas être 'clkout60' et 'clkout20', juste clkout60 simple et clkout20. Le clk_out_20 et clk_out_60 dans with ... select n'existe pas, mais est probablement en cours de développement.