Code VHDL Générateur Onde Carrée Paramétrable
Générateur Onde Carré Synthétisable en VHDL
Ci-dessous une implémentation propre, paramétrable, basée compteur. Supporte ajustement fréquence temps réel via port entrée et inclut reset synchrone actif haut.
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity square_wave_gen is generic ( CLK_FREQ_HZ : positive := 50_000_000; -- Fréquence horloge entrée CNT_WIDTH : positive := 24 -- Largeur compteur bits (période max) ); port ( clk : in std_logic; rst_n : in std_logic; -- Reset synchrone actif bas freq_hz : in positive range 1 to CLK_FREQ_HZ/2; -- Fréquence sortie wave_out : out std_logic ); end entity square_wave_gen; architecture rtl of square_wave_gen is constant MAX_CNT : natural := CLK_FREQ_HZ / 2; -- Demi-période max à 1 Hz signal half_period : natural range 1 to MAX_CNT; signal ctr : natural range 0 to MAX_CNT; begin -- Calcul combinatoire demi-période (synthétise diviseur ou LUT) half_period <= CLK_FREQ_HZ / (2 * freq_hz); process (clk) begin if rising_edge(clk) then if rst_n = '0' then ctr <= 0; wave_out <= '0'; elsif ctr = half_period - 1 then ctr <= 0; wave_out <= not wave_out; else ctr <= ctr + 1; end if; end if; end process; end architecture rtl; Notes Conception
- Génériques :
CLK_FREQ_HZetCNT_WIDTHrendent portable domaines horloge (ex: 50 MHz, 100 MHz, 125 MHz). - Fréquence Temps Réel : Entrée
freq_hzpermet reconfiguration dynamique (ex: depuis CPU, UART, switch DIP). Plage contrainte valeurs valides. - Reset Actif Bas :
rst_nsuit convention FPGA courante ; synchrone pour fermeture timing. - Rapport Cyclique 50% : Compteur bascule sortie à
half_period→ onde carrée symétrique. - Pas Verrous : Entièrement synchrone, processus unique horloge.
- Utilisation Ressources : ~1 registre compteur + comparateur + additionneur + 1 FF. LUTs/FFs minimaux.
Extrait Testbench
-- Stimulus: 50 MHz clk, générer 1 kHz → 10 kHz → 100 kHz freq_hz <= 1_000; wait for 5 ms; freq_hz <= 10_000; wait for 5 ms; freq_hz <= 100_000; wait for 5 ms; Pièges Courants à Éviter
- Utiliser
std_logic_vectorpour fréquence sans conversionunsigned. - Durcir fréquence horloge (utiliser générique).
- Reset asynchrone sans gestion CDC appropriée.
- Oublier comparaison
half_period - 1(erreur off-by-one → erreur fréquence). - Ne pas contraindre plage
freq_hz→ synthèse infère diviseur énorme.
Extensions
- Ajouter générique/entrée
duty_cyclepour PWM (compteurs haut/bas séparés). - Ajouter
phase_offsetpour génération multiphase. - Utiliser tranche DSP pour division si
CLK_FREQ_HZgrande et plage dynamique large.
