Périphérique Générateur de Signal PWM

Périphérique Générateur de Signal PWM

Présentation

Le signal MLI ( Modulation de Largeur d’Impulsion ) ou PWM ( Pulse Width Modulation ) présent sur la broche pin_PWM résulte de la comparaison entre la valeur de comptage Period d’un compteur et le contenu d’un registre Duty.
Le compteur revient à zéro périodiquement, et réinitialise alors l’état logique de pin_PWM.

gene_PWM_chronographe.svg

Dans le contexte d’un système à processeurs, le dialogue entre le processeur et le périphérique PWM se fait par l’intermédiaire de registres via les bus d’adresse et de donnée ( cf les-peripheriques ) Le registre de contrôle permet d’authoriser le comptage, ou de réaliser une remise à zéro du compteur.

gene_PWM.svg


Description des Composants

Decodeur

decodeur.svg

library IEEE;
use IEEE.std_logic_1164.all;

entity decodeur is
    port(
        E  : in std_logic_vector(1 downto 0);
        S0, S1, S2 : out std_logic
    );
end decodeur;

architecture arch_decodeur of decodeur is
begin
    S0 <= '1' when E = "00" else '0';
    S1 <= '1' when E = "01" else '0';
    S2 <= '1' when E = "10" else '0';
end arch_decodeur;

Comparateur

comparateur.svg

library IEEE;
use IEEE.std_logic_1164.all;

entity comparateur is
    port(
        A, B : in std_logic_vector(7 downto 0);
        egal  : out std_logic
    );
end comparateur;

architecture arch_comparateur of comparateur is
begin
    egal <= '1' when A = B else '0';
end arch_comparateur;

Registre

registre.svg

library IEEE;
use IEEE.std_logic_1164.all;

entity registre is
    port(
        clk, reset, load : in std_logic;
        d_in  : in std_logic_vector(7 downto 0);
        d_out : out std_logic_vector(7 downto 0)
    );
end registre;

architecture arch_registre of registre is
begin
    process(clk, reset)
    begin
        if reset = '1' then
            d_out <= (others => '0');
        elsif rising_edge(clk) then
            if load = '1' then
                d_out <= d_in;
            end if;
        end if;
    end process;
end arch_registre;

Compteur

compteur.svg

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

entity compteur is
    port(
        clk, raz, ce : in std_logic;
        count         : out std_logic_vector(7 downto 0)
    );
end compteur;

architecture arch_compteur of compteur is
    signal count_int : unsigned(7 downto 0);
begin
    process(clk)
    begin    
        if rising_edge(clk) then
            if raz = '1' then
                count_int <= (others => '0');
            elsif ce = '1' then            
                if count_int = "11111111" then
                    count_int <= (others => '0'); -- fin de comptage
                else
                    count_int <= count_int + 1; -- "+"(unsigned,int)
                end if;
            end if;
        end if;
    end process;

    count <= std_logic_vector(count_int); -- count copie de count_int
end arch_compteur;

Bascule_PIO

bascule.svg

library IEEE;
use IEEE.std_logic_1164.all;

entity bascule_PIO is
    port(
        reset, clk, set, raz : in std_logic;
        d_out : out std_logic
    );
end bascule_PIO;

architecture arch_bascule_PIO of bascule_PIO is
begin
    process(reset, clk)
    begin
        if reset='1' then
            d_out <= '0';
        elsif rising_edge(clk) then
            if raz='1' then
                d_out <= '0';
            elsif set='1' then
                d_out <= '1';
            end if;
        end if;
    end process;
end arch_bascule_PIO;

Instanciation

Une fois que tous les composants constitutifs du systèmes sont décrits, il ne reste plus qu’à les relier entre via des signaux pour réaliser le périphérique.

!!! TRES IMPORTANT : Lors de l’instanciation, il faut respecter l’ordre des entrées sorties de chaque composant tel qu’il a été décrit précédemment.

Cliquer sur la figure ci dessous:

gene_pwm_composant.svg

library IEEE;
use IEEE.std_logic_1164.all;
use work.all;

entity gene_pwm is
    port(
        clk, reset : in std_logic;
        Data       : inout std_logic_vector(7 downto 0);
        Address    : in std_logic_vector(1 downto 0);
        pin_pwm    : out std_logic
    );
end gene_pwm;

architecture arch_gene_pwm of gene_pwm is
    signal ld_ctl, ld_per, ld_duty, period_match, duty_match, raz_count : std_logic;
    signal period, duty, comptage, ctl_out : std_logic_vector(7 downto 0);
begin
    raz_count <= period_match or ctl_out(0);

    compteur_0: entity compteur
        port map(
            clk   => clk,
            raz   => raz_count,
            ce    => ctl_out(1),
            count => comptage
        );

    reg_ctl: entity registre
        port map(
            clk   => clk,
            reset => reset,
            load  => ld_ctl,
            d_in  => Data,
            d_out => ctl_out
        );

    reg_period: entity registre
        port map(
            clk   => clk,
            reset => reset,
            load  => ld_per,
            d_in  => Data,
            d_out => period
        );

    reg_duty: entity registre
        port map(
            clk   => clk,
            reset => reset,
            load  => ld_duty,
            d_in  => Data,
            d_out => duty
        );

    decoder: entity decodeur
        port map(
            E  => Address,
            S0 => ld_ctl,
            S1 => ld_per,
            S2 => ld_duty
        );

    comp_per: entity comparateur
        port map(
            A    => period,
            B    => comptage,
            egal => period_match
        );

    comp_duty: entity comparateur
        port map(
            A    => duty,
            B    => comptage,
            egal => duty_match
        );

    basc_PIO: entity bascule_PIO
        port map(
            reset => reset,
            clk   => clk,
            set   => period_match,
            raz   => duty_match,
            d_out => pin_pwm
        );
end arch_gene_pwm;

gene_PWM.svg