Table des matières:
- Étape 1: Utilisation par l'utilisateur du séquenceur numérique
- Étape 2: Détails techniques
- Étape 3: Détails techniques
- Étape 4: Diviseur d'horloge à 7 segments
- Étape 5: Séparateur d'horloge de battements par minute
- Étape 6: diviseur d'horloge de lancements
- Étape 7: Lecture/Pause/Sélectionner la machine d'état
- Étape 8: Lecture/Pause/Sélectionner la machine d'état
- Étape 9: Sortie FSM
- Étape 10: Sortie FSM
- Étape 11: Attribuer une note
- Étape 12: Sélection de la sortie
- Étape 13: Génération d'onde carrée
- Étape 14: Affichage à 7 segments
- Étape 15: Sélection finale
- Étape 16: Périphériques externes: DAC
- Étape 17: Périphériques externes: haut-parleur
- Étape 18: Démo vidéo
- Étape 19: Code VHDL
Vidéo: Séquenceur numérique en 4 étapes : 19 étapes (avec images)
2024 Auteur: John Day | [email protected]. Dernière modifié: 2024-01-30 09:09
CPE 133, Cal Poly San Luis Obispo
Créateurs du projet: Jayson Johnston et Bjorn Nelson
Dans l'industrie musicale d'aujourd'hui, l'un des « instruments » les plus couramment utilisés est le synthétiseur numérique. Chaque genre de musique, du hip-hop à la pop et même à la country, utilise un synthétiseur numérique en studio pour créer les rythmes et les sons dont ils ont besoin pour donner vie à leur musique. Dans ce tutoriel, nous allons créer un synthétiseur très simple avec la carte FPGA Basys 3.
Le synthétiseur pourra jouer quatre noires sélectionnées à un nombre constant de battements par minute. Les utilisateurs utiliseront les commutateurs pour attribuer chaque noire à une hauteur musicale. Pour ce projet, nous utilisons un convertisseur numérique-analogique (DAC) 4 bits pour prendre la sortie de la carte et la convertir en un signal analogique. La sortie du DAC sera ensuite transmise à un haut-parleur d'ordinateur standard, créant ainsi notre musique. Seize emplacements discrets sont possibles. Nous limiterons notre synthétiseur à une seule octave de 12 notes, qui se situent entre le do moyen (261,6 Hz) et le B4 (493,9 Hz). L'utilisateur aura également la possibilité d'assigner plusieurs notes en même temps, ainsi que d'assigner un silence en appuyant sur assigner sans qu'aucun des commutateurs de hauteur ne soit déplacé vers le haut. Au fur et à mesure que chaque note est sélectionnée et jouée, la note s'affiche sur l'affichage à 7 segments. Nous utiliserons également trois des boutons du tableau, un pour jouer et mettre en pause la musique, un pour réinitialiser le synthétiseur et le mettre en mode « sélection », et le troisième pour attribuer une hauteur à chaque note en mode sélection.
Une fois que l'utilisateur est satisfait de son choix de notes, et après avoir appuyé sur le bouton de lecture, le synthétiseur jouera successivement chaque note à plusieurs reprises jusqu'à ce que l'utilisateur appuie sur pause ou sur sélection.
Voici la liste du matériel nécessaire:
- Vivado (ou n'importe quel espace de travail VHDL)
- Carte FPGA Basys 3 ou similaire
- Convertisseur numérique-analogique (min. 4 bits)
- Haut-parleur avec prise casque
- Fils conducteurs
Étape 1: Utilisation par l'utilisateur du séquenceur numérique
Les étapes suivantes consistent à faire fonctionner le séquenceur numérique. Le séquenceur numérique prend en charge la lecture de 12 hauteurs distinctes (C, Db, D, Eb, E, F, Gb, G, Ab, A, Bb, B), qui vont de 261,6 Hz à 493,9 Hz.
1. Appuyez sur le bouton gauche pour mettre la carte en mode sélection. Dans ce mode, les 4 commutateurs les plus à gauche (commutateurs 13 à 16) seront chacun utilisés pour stocker une valeur de hauteur distincte.
2. Pour effectuer une sélection, activez l'un des commutateurs de gauche, puis utilisez les 4 commutateurs les plus à droite (commutateurs 1 à 4) pour choisir la hauteur souhaitée. La hauteur associée à une combinaison spécifique de commutateurs de droite sera affichée sur l'affichage à sept segments, et l'affichage se mettra à jour avec la nouvelle hauteur associée chaque fois que les commutateurs de droite sont déplacés vers une nouvelle combinaison. Un silence peut être assigné en n'assignant jamais de hauteur à l'un des commutateurs de gauche, ou en assignant une hauteur indiquée par 0 à l'écran à la note. Une fois que la hauteur souhaitée a été trouvée et affichée à l'écran, appuyez sur le bouton d'assignation du bas pour attribuer cette hauteur spécifique à la note.
3. Répétez l'étape 2 pour les trois notes restantes, en activant individuellement chacun des commutateurs de gauche restants, en choisissant la hauteur respective avec les commutateurs de droite et en appuyant sur le bouton du bas pour affecter la hauteur à la note. Plusieurs notes peuvent être affectées à la même hauteur en déplaçant plus d'un des commutateurs de gauche vers le haut en même temps.
4. Maintenant que toutes les hauteurs de note ont été affectées, le séquenceur numérique est prêt à jouer. Pour jouer les notes sur le haut-parleur, appuyez simplement sur le bouton lecture/pause droit pour commencer à jouer la musique. L'ordre de la séquence de lecture reflète les hauteurs associées aux commutateurs de gauche, de gauche à droite. Les notes seront jouées à un nombre défini de battements par minute, dans l'ordre 1, 2, 3, 4, 1, 2…. L'écran affichera la note en cours de lecture pendant que les haut-parleurs jouent la musique. Pour mettre en pause la lecture de la musique, appuyez simplement sur le bouton droit, puis la musique s'arrêtera et un symbole de pause s'affichera à l'écran. Appuyez à nouveau sur le bouton droit pour reprendre la lecture.
Étape 2: Détails techniques
Notre synthétiseur utilise de nombreux composants numériques différents. Sont inclus des machines à états finis, des registres, des multiplexeurs, des diviseurs d'horloge et plus encore. Pour construire notre synthétiseur, nous avons utilisé 10 fichiers modulaires uniques. Plutôt que de faire de chaque module un composant, nous avons décomposé les fichiers modulaires par fonction. La plupart des modules, par conséquent, sont plus d'un composant. Notez que l'image ci-dessus montre chaque bloc lié ensemble dans notre conception supérieure.
Nous discuterons de chaque module en décrivant les entrées et les sorties, en décomposant ses composants et en expliquant son objectif dans la conception globale. Un fichier ZIP est inclus au bas de l'instructable, qui contient chaque fichier de code VHDL utilisé dans le projet.
Contributions
- Clk (signal d'horloge natif)
- PP (lecture/pause)
- Sel (mettre le synthétiseur en mode sélection)
- Assigner (assigner un pas à un pitch)
- Pas (les notes de position)
- Freq (les commutateurs créant la hauteur désirée)
Les sorties
- Anode (anodes à 7 segments)
- Cathode (cathode 7 segments)
- DAC (4 bits pilotant le DAC)
Étape 3: Détails techniques
Étape 4: Diviseur d'horloge à 7 segments
Notre synthétiseur utilise trois diviseurs d'horloge, tous produisant des signaux qui servent un objectif différent dans notre projet. Un diviseur d'horloge prend un signal d'horloge natif et produit un signal modifié dont la fréquence est inférieure au signal d'horloge d'origine. L'horloge native du Basys 3 est de 100 MHz. C'est la fréquence que nos diviseurs d'horloge utilisent. Si vous utilisez une carte FPGA différente avec une fréquence d'horloge native différente, vous devrez peut-être modifier le code.
Le diviseur d'horloge à 7 segments produit un signal qui pilote le fichier seg_display. Nous expliquerons plus en détail le fonctionnement de ce fichier lorsque nous arriverons à sa section. Essentiellement, ce diviseur d'horloge produit un signal de 240 Hz qui sera utilisé pour basculer entre les anodes et les cathodes sur l'écran. Le signal est de 240 Hz car la fréquence à laquelle l'œil humain ne peut pas reconnaître l'absence de lumière est de 60 Hz. Nous utilisons deux chiffres, donc en doublant cette fréquence, chaque chiffre oscillera à 60 Hz. Ensuite, nous le doublons pour obtenir 240 Hz car le système ne change que lorsque le signal monte, pas quand il descend.
Pour ce faire, le diviseur prend le signal natif de 100 MHz et compte à chaque front montant. Lorsque le compteur atteint 416667, la sortie passera de bas en haut, ou vice versa.
Contributions
Clk (signal d'horloge natif)
Les sorties
Clk_7seg (vers seg_display)
Composants
- Registre D
- MUX
- Onduleur
- Additionneur
Étape 5: Séparateur d'horloge de battements par minute
Le diviseur d'horloge BPM fonctionne de manière similaire. Ce diviseur produit la fréquence d'horloge qui commande la commutation entre les quatre étapes lors de la sortie des tonalités dans l'état de lecture. Nous avons décidé de basculer entre les notes à 100 BPM. À 100 BPM, chaque note sera jouée pendant 3/5 de seconde. Le signal résultant aurait une fréquence de 1,67 Hz.
Pour produire un signal de cette fréquence, nous avons à nouveau utilisé un système de comptage, mais cette fois le comptage était de 60 millions. Chaque fois que le compteur atteignait 60 millions, le signal de sortie basculait haut ou bas.
Contributions
Clk (fréquence d'horloge native)
Les sorties
Clk_BPM (vers output_FSM)
Composants
- Registre D
- MUX
- Onduleur
- Additionneur
Étape 6: diviseur d'horloge de lancements
Le diviseur d'horloge Pitchs est le plus grand de nos diviseurs d'horloge. Ce diviseur produit 12 signaux différents correspondant aux 12 notes différentes que notre synthétiseur peut jouer. En utilisant des connaissances de base en théorie musicale, nous avons déduit qu'un bit ou un bus pouvait osciller à une vitesse qui correspond à la fréquence des notes musicales. Pour voir les fréquences que nous avons utilisées, regardez ici. Nous avons utilisé la quatrième octave des hauteurs.
Le même système de comptage est utilisé ici. Pour les valeurs spécifiques auxquelles nous avons compté, consultez le fichier intitulé Clk_div_pitches.
Contributions
Clk (fréquence d'horloge native)
Les sorties
C, Db, D, Eb, E, F, Gb, G, Ab, A, Bb, B (pour output_select)
Composants
- Registre D
- MUX
- Onduleur
- Additionneur
Étape 7: Lecture/Pause/Sélectionner la machine d'état
Dans notre projet, il y a deux machines à états finis (FSM). Un FSM est un dispositif logique qui ne peut exister que dans un seul état parmi un nombre fini d'états. À l'aide d'un FSM, un circuit numérique peut passer à un nouvel état basé sur une combinaison d'entrées. En utilisant la logique d'entrée, l'état d'un FSM change lorsqu'il y a un front montant de l'horloge. À partir de l'état et des entrées dans le circuit, vous pouvez créer une logique de sortie qui donne des sorties qui n'existent que si le FSM est dans un certain état.
La machine d'état PPS est le premier FSM de notre circuit. Il y a trois états dans ce FSM; Mode lecture, pause et sélection. Pour parcourir les différents états, nous avons utilisé les boutons PP et Sélection. Voir le diagramme d'état ci-dessus pour voir comment les transitions entre les états se produisent. Nous avons effectué cette transition FSM sur le front montant de l'horloge native 100 MHz, de sorte qu'il serait impossible pour la machine de ne pas effectuer de transition lorsque l'un des boutons était enfoncé, même pendant un très court laps de temps. L'état actuel (P_state) est la seule sortie de ce module.
Contributions
- Clk (fréquence d'horloge native)
- Sél (bouton gauche)
- PP (bouton droit)
Les sorties
P_state (état actuel, vers output_FSM, note_assign, seg_dsiplay, final_select)
Composants
- MUX
- Registre D
Étape 8: Lecture/Pause/Sélectionner la machine d'état
Étape 9: Sortie FSM
Il s'agit du deuxième FSM référencé dans la section précédente. Ce FSM remplit une fonction différente de l'autre, mais la base de celui-ci est essentiellement la même.
La sortie FSM ne fonctionne que si l'état actuel du premier FSM est "01" (l'état de lecture). Il s'agit essentiellement de l'activation du module. Si l'état est "01", alors le FSM va basculer entre les états sur le front montant du signal d'horloge BPM. Nous faisons cela parce que output_FSM contrôle quel nombre binaire pour la hauteur sélectionnée est envoyé aux modules output_select et seg_display. Le FSM a une entrée 16 bits provenant du module d'assignation de notes, qui sera couvert par la suite. Dans l'état "00" pour output_FSM, le module affichera "xxxx" pour la première note attribuée. Ensuite, dans "01", il affichera "yyyy" pour la deuxième note et ainsi de suite pour chaque note avant de revenir à la première note. Voir le diagramme d'état ci-dessus.
Ce FSM diffère du premier car il n'y a pas de logique d'entrée pour contrôler la commutation entre les états. Au lieu de cela, le FSM ne fonctionnera que lorsque l'état du premier FSM est "01", puis ce FSM passera d'un état à l'autre uniquement sur le front montant du signal d'horloge. Une autre différence est que ce module a une logique de sortie, ce qui signifie qu'il ne sort pas l'état actuel, il sort le nombre binaire pour le pas à cet état.
Contributions
- Clk_BPM (signal d'horloge BPM du diviseur d'horloge)
- FSM1_state (PS de PPS FSM)
- Pitch_in (pitchs de note_assign)
Les sorties
Pitch_out (un pas à la fois, vers output_select et seg_display)
Composants
- MUX
- Registre D
Étape 10: Sortie FSM
Étape 11: Attribuer une note
Le module d'assignation de note est responsable de l'assignation effective d'une hauteur à la note de position, ou pas. Ce module est en fait assez simple. Il vérifie d'abord si le circuit est dans l'état "sélection" et si un interrupteur à pas (extrême gauche) est haut. Si cela est vrai et que le bouton d'affectation est enfoncé, la sortie du module sera égale au nombre binaire représenté par les commutateurs de fréquence (à l'extrême droite).
À l'origine, nous avions tenté de créer un module qui enregistrerait réellement l'un des signaux d'horloge de hauteur sur la sortie, mais nous avons rencontré des problèmes avec la sortie qui changeait pour suivre les signaux d'horloge d'entrée. C'est le seul module utilisé plus d'une fois dans la conception finale. Chaque étape est associée à un module note_assign, et à cause de cela, chaque instance du module obtient un bit du bus Step.
Contributions
- P_state (état actuel de PPS FSM)
- Sél (bouton gauche)
- Commutateur (commutateur à une étape)
- Freq (commutateurs d'extrême droite pour la hauteur)
- Assigner (bouton du bas, assigne une note)
Les sorties
Pas (numéro binaire, vers output_FSM)
Composants
- MUX
- D s'inscrire
Étape 12: Sélection de la sortie
La sélection de sortie est chargée de prendre le nombre binaire pour un pas et de le connecter à son signal d'horloge respectif. Malgré sa taille, il s'agit également d'un module relativement simple. Output_select est essentiellement un décodeur binaire, décodant le nombre binaire pour un pas en un signal d'horloge spécifique. En fait, l'affectation de la sortie à une fréquence d'horloge fonctionnait mieux ici par rapport au module note_assign, car tout ce que ce module avait à faire était de MUX les signaux d'horloge avec le nombre binaire représentant l'entrée de contrôle.
Nous nous excusons pour l'étrange routage, Vivado a organisé les signaux de hauteur par ordre alphabétique pour le fichier clk_div_pitches, mais pour ce fichier, il les a organisés par nombre binaire croissant, ce qui fait que les hauteurs sont dans un ordre différent. Notez également que si le nombre binaire de output_FSM était « 0000 » ou quelque chose de plus grand que « 1100 », alors le MUX a envoyé un signal « 0 » plat.
Saisir
- Pas (de output_FSM);
- C, Db, D, Eb, E, F, Gb, G, Ab, A, Bb, B (signaux d'horloge de hauteur)
Sortir
Tone (un seul bit qui correspond au signal d'horloge sélectionné, à square_wave)
Composants
MUX
Étape 13: Génération d'onde carrée
Le module square_wave est le générateur de l'onde carrée qui est sortie de la carte vers le DAC. En utilisant le signal de tonalité du fichier précédent, ce square_wave inverse le nombre de 4 bits entre "0000" et "1111" sur le front montant de Tone. La tonalité est une fréquence de hauteur spécifique, donc square_wave produit une onde avec une fréquence différente lorsque output_FSM passe à un autre état. La sortie 4 bits de ce module va au module fin_sel, où la logique dicte si ce bus sera sorti en fonction de l'état de PPS FSM.
Une alternative à ce générateur d'onde carrée produit une onde sinusoïdale. Bien que cela produise très probablement un meilleur ton final, il est considérablement plus difficile à mettre en œuvre, nous avons donc choisi de générer simplement une onde carrée.
Contributions
Tonalité (bit oscillant de output_select)
Les sorties
DAC_input (bus oscillant de 4 bits qui change à la même fréquence de tonalité)
Composants
- Onduleur
- Registre D
Étape 14: Affichage à 7 segments
Le module seg_display contrôle l'affichage à 7 segments sur notre carte basys. Dans le module, deux processus se produisent. Le premier processus décode Freq lorsqu'il est dans l'état « sélection » ou Pitch lorsqu'il est en mode « jeu ». En mode "pause", le module décode pour afficher le symbole de pause. En regardant le code VHDL, vous pouvez voir que le décodeur binaire décode en fait l'entrée en deux signaux différents, cathode1 et cathode2. Cathode1 représente la lettre correspondant au pas à afficher, et cathode2 représente le symbole plat (b) s'il y en a un. La raison en est liée au deuxième processus effectué par le module seg_display.
Sur une carte basys3, l'affichage à segments a des cathodes communes. Alors que les anodes contrôlent quel chiffre est allumé, les cathodes contrôlent quels segments sont allumés. Étant donné que l'écran a des cathodes communes, cela signifie que vous ne pouvez afficher qu'un seul ensemble de segments à la fois. Cela pose un problème pour ce projet car nous voulons afficher une lettre au premier chiffre et le symbole plat, si nécessaire, en même temps. Vous vous souvenez maintenant du signal d'horloge 7seg ? Pour contourner ce problème, nous changeons les anodes et les cathodes d'avant en arrière sur le signal d'horloge 7seg. Parce que le signal d'horloge est de 240 Hz et que nous utilisons deux chiffres, chaque chiffre oscillera à 60 Hz. À l'œil humain, il semblera que les chiffres n'oscillent pas du tout.
Notez également que l'affichage de la carte basys3 utilise une logique négative. Cela signifie que si une anode ou une cathode est définie sur « 0 », ce chiffre ou segment sera activé, et vice versa.
Contributions
- Pitch (numéro binaire pour une note, utilisé dans l'état de jeu)
- Freq (commutateurs de fréquence, utilisés en état de sélection)
- P_state (état actuel de PPS FSM)
- Clk_240Hz (signal d'horloge de Clk_div_7seg, double 120 car nous n'utilisons que le front montant)
Les sorties
- Cathode (bus qui contrôle les segments sur l'afficheur, sortie finale)
- Anode (bus qui contrôle les chiffres sur l'affichage, sortie finale)
Composants
- Loquet
- MUX
- Registre D
Étape 15: Sélection finale
La sélection finale est le dernier module utilisé dans ce projet. Autre module simple, ce module contrôle la sortie finale qui ira au DAC. Lorsqu'il est dans l'état "sélection" ou "pause", le module va émettre un "0000" statique afin qu'aucune musique ne soit jouée par les haut-parleurs. Dans l'état "play", le module produira les 4 bits oscillants déterminés par square_wave.
Contributions
- P_state (état actuel de PPS FSM)
- DAC_input (les 4 bits oscillants de square_wave)
Les sorties
DAC (égal à DAC_input dans l'état de lecture, sortie finale)
Composants
MUX
Étape 16: Périphériques externes: DAC
Un convertisseur numérique-analogique (DAC) prend un signal discret et le convertit en un signal continu. Notre DAC a quatre bits et est composé d'un amplificateur sommateur. En utilisant un rapport de résistances dans la boucle d'alimentation et de rétroaction, nous avons pu créer un système qui produit à 16 niveaux différents en créant par la "somme" de chaque branche. Bit0, la branche supérieure, porte le moins de poids et contribue le plus petit potentiel lorsqu'il est élevé en raison de la résistance plus élevée de cette branche. Le poids augmente au fur et à mesure que vous descendez les branches. Si vous deviez compter en binaire puis redescendre en utilisant les entrées de bits, les tensions de sortie ressembleraient à une onde sinusoïdale pas à pas. L'entrée du DAC était connectée à l'un des PMOD de la carte pour transférer le signal 4 bits.
Le DAC a été assemblé à l'origine pour un cours de génie électrique et a été conçu et soudé par nous, pas acheté dans un magasin. Ci-dessus, une image du fichier de conception pour la création de la carte de circuit imprimé.
Étape 17: Périphériques externes: haut-parleur
Pour ce projet, vous n'allez pas vouloir acheter une super belle paire d'enceintes. Comme vous pouvez le constater, le son est assez basique. Nous sommes allés acheter un ensemble de haut-parleurs d'ordinateur à 8 $ chez Best Buy. Tout ce qui a une prise casque fonctionne bien. Monotone fonctionne également très bien. Vous pouvez même utiliser des écouteurs, mais vous pourriez les faire sauter !
Pour connecter la sortie du DAC aux haut-parleurs, nous avons utilisé des câbles de démarrage, puis avons maintenu le câble de sortie à l'extrémité de la prise casque et le câble de masse à la base. Nous avons essayé d'utiliser du ruban isolant pour maintenir les câbles en place, mais cela a causé beaucoup d'interférences. Essayer un autre style de bande pourrait résoudre ce problème.
Pour nos haut-parleurs, nous les avons réglés sur le réglage le plus élevé et avons obtenu un bruit assez fort.
Et c'est la dernière étape pour créer un séquenceur numérique à partir d'une carte FPGA ! Passez aux deux sections suivantes pour télécharger tout notre code VHDL et voir le séquenceur en action.
Étape 18: Démo vidéo
Cette vidéo montre la version finale du projet de travail, y compris le processus d'attribution des commutateurs à 4 hauteurs distinctes et les haut-parleurs jouant les notes respectives.
Étape 19: Code VHDL
Voici le code pour l'ensemble du projet, y compris les fichiers de contraintes et sim utilisés lors de la construction du séquenceur. Notez que les fichiers de conception inutilisés l'indiquent dans l'architecture.
Conseillé:
Séquenceur de section rythmique Arduino MIDI : 8 étapes (avec images)
Séquenceur Arduino MIDI Rhythm Section : Avoir une bonne boîte à rythmes logicielle est facile et bon marché aujourd'hui, mais l'utilisation d'une souris tue le plaisir pour moi. C'est pourquoi j'ai réalisé ce qui était initialement conçu comme un pur séquenceur de batterie MIDI matériel de 64 étapes capable de déclencher jusqu'à 12 éléments de batterie différents
Synthé séquenceur parallèle : 17 étapes (avec images)
Parallel Sequencer Synth : Il s'agit d'un guide pour créer un séquenceur simple. Un séquenceur est un appareil qui produit cycliquement une série d'étapes qui entraînent ensuite un oscillateur. Chaque étape peut être affectée à une tonalité différente et ainsi créer des séquences ou des effets audio intéressants
Séquenceur simple : 16 étapes (avec images)
Séquenceur simple : l'une des clés pour faire de la bonne musique est la répétition insensée. C'est ce à quoi le séquenceur simple est excellent. Il fait la même chose encore et encore dans une séquence de huit notes. Vous pouvez régler la fréquence de la note, la durée de la note et
Séquenceur LED RVB programmable (utilisant Arduino et Adafruit Trellis) : 7 étapes (avec images)
Séquenceur LED RVB programmable (utilisant Arduino et Adafruit Trellis) : mes fils voulaient des bandes LED de couleur pour éclairer leurs bureaux, et je ne voulais pas utiliser un contrôleur de bande RVB en conserve, car je savais qu'ils s'ennuieraient avec les motifs fixes ces contrôleurs ont. J'ai aussi pensé que ce serait une excellente occasion de créer
Visionneuse d'images 3D numérique - "Le DigiStereopticon": 6 étapes (avec images)
Visionneuse d'images 3D numérique - "Le DigiStereopticon": La photographie stéréoscopique est tombée en désuétude. Cela est probablement dû au fait que les gens n'aiment pas avoir à porter des lunettes spéciales pour voir des photos de famille. Voici un petit projet amusant que vous pouvez réaliser en moins d'une journée pour réaliser votre image 3D