Inhoudsopgave:

4-staps digitale sequencer: 19 stappen (met afbeeldingen)
4-staps digitale sequencer: 19 stappen (met afbeeldingen)

Video: 4-staps digitale sequencer: 19 stappen (met afbeeldingen)

Video: 4-staps digitale sequencer: 19 stappen (met afbeeldingen)
Video: (START TODAY) $16,137 in One Month In 4 SIMPLE Steps | Make Money Online as a COMPLETE Beginner 2024, Juli-
Anonim
4-staps digitale sequencer
4-staps digitale sequencer
4-staps digitale sequencer
4-staps digitale sequencer

CPE 133, Cal Poly San Luis Obispo

Projectmakers: Jayson Johnston en Bjorn Nelson

In de hedendaagse muziekindustrie is een van de meest gebruikte "instrumenten" de digitale synthesizer. Elk muziekgenre, van hiphop tot pop en zelfs country, gebruikt een digitale synthesizer in de studio om de beats en geluiden te creëren die ze nodig hebben om hun muziek tot leven te brengen. In deze tutorial gaan we een heel eenvoudige synthesizer maken met het Basys 3 FPGA-bord.

De synthesizer kan vier geselecteerde kwartnoten spelen met een constant aantal tellen per minuut. Gebruikers zullen de schakelaars gebruiken om elke kwartnoot toe te wijzen aan een muzikale toonhoogte. Voor dit project gebruiken we een 4-bit digitaal naar analoog converter (DAC) om de output van het bord te nemen en om te zetten in een analoog signaal. De uitvoer van de DAC wordt vervolgens naar een standaard computerluidspreker gevoerd, waardoor onze muziek wordt gecreëerd. Er zijn zestien discrete staanplaatsen mogelijk. We zullen onze synthesizer beperken tot een enkel octaaf van 12 noten, die tussen de middelste C (261,6 Hz) en B4 (493,9 Hz) vallen. De gebruiker heeft ook de mogelijkheid om meerdere noten tegelijkertijd toe te wijzen, evenals een rust toe te wijzen door op toewijzen te drukken terwijl geen van de toonhoogteschakelaars naar boven is verschoven. Terwijl elke noot wordt geselecteerd en gespeeld, wordt de letternoot weergegeven op het 7-segments display. We zullen ook drie van de knoppen op het bord gebruiken, een om de muziek af te spelen en te pauzeren, een om de synthesizer te resetten en in de "selectie" -modus te zetten, en de derde om elke noot een toonhoogte toe te wijzen in de selectiemodus.

Zodra de gebruiker tevreden is met de keuze van de noten, en nadat hij op de afspeelknop heeft gedrukt, zal de synthesizer elke noot herhaaldelijk achter elkaar spelen totdat de gebruiker op pauze drukt of op selecteren drukt.

Hier is een lijst van de benodigde apparatuur:

  • Vivado (of een andere VHDL-werkruimte)
  • Basys 3 of vergelijkbaar FPGA-bord
  • Digitaal naar analoog converter (min. 4-bits)
  • Luidspreker met koptelefoonaansluiting
  • Draadgeleiders

Stap 1: Bediening door de gebruiker van de digitale sequencer

Gebruikersbediening van digitale sequencer
Gebruikersbediening van digitale sequencer

De volgende stappen zijn bedoeld om de digitale sequencer te bedienen. De digitale sequencer ondersteunt het afspelen van 12 verschillende toonhoogtes (C, Db, D, Eb, E, F, Gb, G, Ab, A, Bb, B), die variëren van 261,6 Hz tot 493,9 Hz.

1. Druk op de linkerknop om het bord in de selectiemodus te zetten. In deze modus worden de 4 meest linkse schakelaars (schakelaars 13 tot 16) elk gebruikt om een afzonderlijke toonhoogtewaarde op te slaan.

2. Om een selectie te maken, zet u een van de linker schakelaars aan en gebruikt u vervolgens de meest rechtse 4 schakelaars (schakelaars 1 t/m 4) om de gewenste toonhoogte te kiezen. De toonhoogte die hoort bij een specifieke combinatie van rechterschakelaars wordt weergegeven op het display met zeven segmenten, en de display wordt bijgewerkt naar de nieuwe bijbehorende toonhoogte wanneer de rechterschakelaars worden verschoven naar een nieuwe combinatie. Een rust kan worden toegewezen door nooit een toonhoogte toe te wijzen aan een van de linkerschakelaars, of door een toonhoogte die op de display als 0 wordt weergegeven aan de noot toe te wijzen. Zodra de gewenste toonhoogte is gevonden en op de display wordt weergegeven, drukt u op de onderste toewijzingsknop om die specifieke toonhoogte aan de noot toe te wijzen.

3. Herhaal stap 2 voor de drie resterende noten, door elk van de resterende linkerschakelaars afzonderlijk aan te zetten, de respectieve toonhoogte te kiezen met de rechterschakelaars en op de onderste knop te drukken om de toonhoogte aan de noot toe te wijzen. Meerdere noten kunnen dezelfde toonhoogte worden toegewezen door meer dan één van de linkerschakelaars tegelijkertijd omhoog te schuiven.

4. Nu alle toonhoogtes zijn toegewezen, is de digitale sequencer klaar om te spelen. Om de noten op de luidspreker te spelen, drukt u eenvoudig op de rechter afspeel-/pauzeknop om de muziek af te spelen. De volgorde van de afspeelvolgorde weerspiegelt de toonhoogtes die horen bij de linkerschakelaars, van links naar rechts. De noten worden gespeeld met een bepaald aantal tellen per minuut, in de volgorde 1, 2, 3, 4, 1, 2…. Het display toont de noot die momenteel wordt afgespeeld terwijl de luidsprekers de muziek afspelen. Om het afspelen van muziek te pauzeren, drukt u eenvoudig op de rechterknop, waarna de muziek stopt met spelen en een pauzesymbool op het display wordt weergegeven. Als u nogmaals op de rechterknop drukt, wordt het afspelen hervat.

Stap 2: Technische details

Technische details
Technische details

Onze synthesizer maakt gebruik van veel verschillende digitale componenten. Inbegrepen zijn eindige-toestandsmachines, registers, multiplexers, klokverdelers en meer. Om onze synthesizer te bouwen, hebben we 10 unieke modulaire bestanden gebruikt. In plaats van van elke module een onderdeel te maken, hebben we de modulaire bestanden onderverdeeld per functie. De meeste modules zijn daarom meer dan één component. Let op: de afbeelding hierboven toont elk blok samengebonden in ons topontwerp.

We zullen elke module bespreken door de inputs en outputs te beschrijven, de componenten op te splitsen en het doel ervan in het algehele ontwerp uit te leggen. Een ZIP-bestand is opgenomen aan de onderkant van de instructable, die elk VHDL-codebestand bevat dat in het project wordt gebruikt.

Ingangen

  • Clk (native kloksignaal)
  • PP (afspelen/pauzeren)
  • Sel (zet synthesizer in selectiemodus)
  • Toewijzen (een stap toewijzen aan een toonhoogte)
  • Stap (de positionele noten)
  • Freq (de schakelaars die de gewenste toonhoogte creëren)

Uitgangen

  • Anode (7-segment anoden)
  • Kathode (7-segment kathoden)
  • DAC (4-bits die de DAC aansturen)

Stap 3: Technische details

Technische details
Technische details

Stap 4: 7-segment klokverdeler

7-segments klokverdeler
7-segments klokverdeler

Onze synthesizer maakt gebruik van drie klokverdelers, die allemaal signalen produceren die een ander doel dienen in ons project. Een klokdeler neemt een eigen kloksignaal en produceert een gewijzigd signaal met een frequentie die lager is dan het oorspronkelijke kloksignaal. De native klok van de Basys 3 is 100 MHz. Dit is de frequentie die onze klokverdelers gebruiken. Als u een ander FPGA-bord met een andere native klokfrequentie gebruikt, moet u mogelijk de code wijzigen.

De klokverdeler met 7 segmenten produceert een signaal dat het seg_display-bestand aanstuurt. We zullen in meer detail uitleggen hoe dit bestand werkt wanneer we naar de sectie gaan. In wezen produceert deze klokverdeler een 240 Hz-signaal dat zal worden gebruikt om te schakelen tussen anodes en kathodes op het display. Het signaal is 240 Hz omdat de frequentie waarop het menselijk oog de afwezigheid van licht niet kan herkennen 60 Hz is. We gebruiken twee cijfers, dus door deze frequentie te verdubbelen, oscilleert elk cijfer op 60 Hz. Dan verdubbelen we het om 240 Hz te krijgen omdat het systeem alleen verandert wanneer het signaal hoog wordt, niet wanneer het laag wordt.

Om dit te bereiken, neemt de deler het oorspronkelijke 100 MHz-signaal en telt op bij elke stijgende flank. Wanneer de teller 416667 bereikt, gaat de output van laag naar hoog, of omgekeerd.

Ingangen

Clk (native kloksignaal)

Uitgangen

Clk_7seg (naar seg_display)

Componenten

  • D registreren
  • MUX
  • Omvormer
  • Adder

Stap 5: Beats Per Minute Clock Divider

Slagen per minuut klokverdeler
Slagen per minuut klokverdeler

De BPM-klokverdeler werkt op een vergelijkbare manier. Deze verdeler produceert de klokfrequentie die het schakelen tussen de vier stappen aanstuurt bij het uitvoeren van tonen in de afspeelstatus. We besloten om te wisselen tussen noten bij 100 BPM. Bij 100 BPM wordt elke noot 3/5 van een seconde gespeeld. Het resulterende signaal zou een frequentie van 1,67 Hz hebben.

Om een signaal van deze frequentie te produceren, gebruikten we opnieuw een telsysteem, maar dit keer was de telling 60 miljoen. Elke keer dat de teller 60 miljoen bereikte, wisselde het uitgangssignaal van hoog of laag.

Ingangen

Clk (native klokfrequentie)

Uitgangen

Clk_BPM (naar output_FSM)

Componenten

  • D registreren
  • MUX
  • Omvormer
  • Adder

Stap 6: Standplaatsen klokverdeler

Standplaatsen Klokverdeler
Standplaatsen Klokverdeler

De Pitches Clock Divider is de grootste van onze klokverdelers. Deze verdeler voert 12 verschillende signalen uit die overeenkomen met de 12 verschillende noten die onze synthesizer kan spelen. Met behulp van basiskennis van muziektheorie hebben we afgeleid dat een bit of bus kan oscilleren met een snelheid die overeenkomt met de frequentie van muzieknoten. Kijk hier om de frequenties te zien die we hebben gebruikt. We gebruikten het vierde octaaf van toonhoogtes.

Hier wordt hetzelfde telsysteem gebruikt. Zie het bestand met het label Clk_div_pitches voor de specifieke waarden waarnaar we hebben geteld.

Ingangen

Clk (native klokfrequentie)

Uitgangen

C, Db, D, Eb, E, F, Gb, G, Ab, A, Bb, B (naar output_select)

Componenten

  • D registreren
  • MUX
  • Omvormer
  • Adder

Stap 7: Afspelen/Pauzeren/Selecteren Staatsmachine

Afspelen/Pauzeren/Selecteren Staatsmachine
Afspelen/Pauzeren/Selecteren Staatsmachine

In ons project zijn er twee eindige toestandsmachines (FSM). Een FSM is een logisch apparaat dat slechts in één toestand kan bestaan uit een eindig aantal toestanden. Met behulp van een FSM kan een digitaal circuit naar een nieuwe staat gaan op basis van een combinatie van ingangen. Met behulp van invoerlogica zal de status van een FSM veranderen wanneer er een stijgende flank van de klok is. Vanuit de status en ingangen in het circuit, kunt u uitgangslogica maken die uitgangen geeft die alleen bestaan als de FSM zich in een bepaalde staat bevindt.

De PPS-statusmachine is de eerste FSM in ons circuit. Er zijn drie staten in deze FSM; Afspeel-, Pauze- en Selectiemodus. Om door de verschillende statussen te bladeren, gebruikten we de PP- en Selectieknoppen. Zie het toestandsdiagram hierboven om te zien hoe overgangen tussen toestanden plaatsvinden. We hebben deze FSM-overgang gemaakt op de stijgende flank van de oorspronkelijke 100 MHz-klok, zodat het onmogelijk zou zijn voor de machine om niet over te schakelen wanneer een van de knoppen werd ingedrukt, zelfs voor een zeer korte tijd. De huidige status (P_state) is de enige uitvoer van deze module.

Ingangen

  • Clk (native klokfrequentie)
  • Sel (linker knop)
  • PP (rechter knop)

Uitgangen

P_state (huidige staat, naar output_FSM, note_assign, seg_dsiplay, final_select)

Componenten

  • MUX
  • D registreren

Stap 8: Afspelen/Pauzeren/Selecteren Staatsmachine

Afspelen/Pauzeren/Selecteren Staatsmachine
Afspelen/Pauzeren/Selecteren Staatsmachine

Stap 9: Uitgang FSM

Uitgang FSM
Uitgang FSM

Dit is de tweede FSM waarnaar in de vorige sectie wordt verwezen. Deze FSM heeft een andere functie dan de andere, maar de basis voor deze is in wezen hetzelfde.

De uitgang FSM werkt alleen als de huidige status van de eerste FSM "01" is (de afspeelstatus). In wezen is dit de enable-in voor de module. Als de status "01" is, gaat de FSM schakelen tussen statussen op de stijgende flank van het BPM-kloksignaal. We doen dit omdat de output_FSM bepaalt welk binair getal voor de geselecteerde toonhoogte wordt verzonden naar de output_select en seg_display-modules. De FSM heeft een 16-bits invoer afkomstig van de module voor het toewijzen van notities, die hierna wordt besproken. In de "00" status voor de output_FSM, zal de module "xxxx" uitvoeren voor de eerste toegewezen noot. Dan zal het in "01" "yyyy" uitvoeren voor de tweede noot enzovoort voor elke noot voordat het teruggaat naar de eerste noot. Zie het toestandsdiagram hierboven.

Deze FSM verschilt van de eerste omdat er geen inputlogica is om het schakelen tussen toestanden te regelen. In plaats daarvan gaat de FSM alleen werken wanneer de toestand van de eerste FSM "01" is, en dan zal deze FSM alleen overgaan tussen toestanden op de stijgende flank van het kloksignaal. Een ander verschil is dat deze module outputlogica heeft, wat betekent dat het de huidige toestand niet uitvoert, maar het binaire getal voor de toonhoogte in die toestand uitvoert.

Ingangen

  • Clk_BPM (BPM-kloksignaal van klokverdeler)
  • FSM1_state (PS van PPS FSM)
  • Pitch_in (pitch van note_assign)

Uitgangen

Pitch_out (één toonhoogte per keer, naar output_select en seg_display)

Componenten

  • MUX
  • D registreren

Stap 10: Uitgang FSM

Uitgang FSM
Uitgang FSM

Stap 11: Noteer toewijzen

Opmerking Toewijzen
Opmerking Toewijzen

De noottoewijzingsmodule is verantwoordelijk voor het daadwerkelijk toewijzen van een toonhoogte aan de positionele noot of stap. Deze module is eigenlijk vrij eenvoudig. Het controleert eerst of het circuit in de "selectie" staat staat en of een stappenschakelaar (uiterst links) hoog staat. Als dit waar is en de toewijzingsknop wordt ingedrukt, is de output van de module gelijk aan het binaire getal dat wordt weergegeven door de frequentieschakelaars (uiterst rechts).

Oorspronkelijk hadden we geprobeerd een module te maken die een van de pitchkloksignalen daadwerkelijk naar de uitgang zou opslaan, maar we ondervonden problemen met het veranderen van de uitgang om de ingangskloksignalen te volgen. Dit is de enige module die meer dan eens is gebruikt in het definitieve ontwerp. Aan elke stap is een note_assign-module gekoppeld, en daarom krijgt elke instantie van de module één bit van de Step-bus.

Ingangen

  • P_state (huidige status van PPS FSM)
  • Sel (linker knop)
  • Schakelaar (eenstapsschakelaar)
  • Freq (uiterst rechts schakelt voor toonhoogte)
  • Toewijzen (onderste knop, wijst een noot toe)

Uitgangen

Pitch (binair getal, naar output_FSM)

Componenten

  • MUX
  • D registreer

Stap 12: Uitgang selecteren

Uitgang selecteren
Uitgang selecteren

Uitgangsselectie is verantwoordelijk voor het nemen van het binaire getal voor een toonhoogte en het verbinden daarvan met het respectieve kloksignaal. Ondanks zijn grootte is dit ook een relatief eenvoudige module. Output_select is in wezen een binaire decoder, die het binaire getal decodeert voor een toonhoogte naar een specifiek kloksignaal. Het feitelijk toewijzen van de uitgang aan een klokfrequentie werkte hier beter dan de note_assign module, omdat deze module alleen de kloksignalen MUX moest geven met het binaire getal dat de besturingsingang vertegenwoordigt.

Onze excuses voor de vreemde routing, Vivado organiseerde de toonhoogtesignalen alfabetisch voor het bestand clk_div_pitches, maar voor dit bestand organiseerde het ze op oplopend binair getal, waardoor de toonhoogtes in een andere volgorde stonden. Merk ook op dat als het binaire getal van de output_FSM "0000" of iets groter dan "1100" was, de MUX dan een plat '0'-signaal heeft verzonden.

Invoer

  • Toonhoogte (van output_FSM);
  • C, Db, D, Eb, E, F, Gb, G, Ab, A, Bb, B (pitchkloksignalen)

Uitgang:

Toon (een enkele bit die overeenkomt met het geselecteerde kloksignaal, naar square_wave)

Componenten

MUX

Stap 13: Square Wave Gen

Square Wave Gen
Square Wave Gen

Module square_wave is de generator voor de blokgolf die van het bord naar de DAC wordt uitgevoerd. Gebruikmakend van het toonsignaal van het vorige bestand, inverteert deze square_wave het 4-bits getal tussen "0000" en "1111" op de stijgende flank van Tone. Toon is een specifieke toonhoogtefrequentie, dus square_wave produceert een golf met een andere frequentie wanneer output_FSM overgaat naar een andere toestand. De 4-bits uitvoer van deze module gaat naar de fin_sel-module, waar logica bepaalt of deze bus wordt uitgevoerd op basis van de status van PPS FSM.

Een alternatief voor deze blokgolfgenerator is het produceren van een sinusgolf. Hoewel dit hoogstwaarschijnlijk een betere eindtoon zou opleveren, is het aanzienlijk moeilijker te implementeren, dus hebben we ervoor gekozen om gewoon een blokgolf te genereren.

Ingangen

Toon (oscillerend bit van output_select)

Uitgangen

DAC_input (oscillerende 4-bits bus die verandert met dezelfde toonfrequentie)

Componenten

  • Omvormer
  • D registreren

Stap 14: 7-segments display

7-segmentsdisplay
7-segmentsdisplay

De seg_display module bestuurt het 7-segment display op ons basys board. Binnen de module vinden twee processen plaats. Het eerste proces decodeert Freq in de "selection"-status of Pitch in de "play"-modus. In de "pauze"-modus decodeert de module om het pauzesymbool weer te geven. Als je naar de VHDL-code kijkt, kun je zien dat de binaire decoder de invoer feitelijk decodeert in twee verschillende signalen, kathode1 en kathode2. Kathode1 vertegenwoordigt de letter die overeenkomt met de toonhoogte die moet worden weergegeven, en kathode2 vertegenwoordigt het platte symbool (b) als er een is. De reden hiervoor heeft betrekking op het tweede proces dat door de seg_display-module wordt uitgevoerd.

Op een basys3-bord heeft het segmentdisplay gemeenschappelijke kathodes. Terwijl de anodes bepalen welk cijfer wordt ingeschakeld, bepalen de kathoden welke segmenten aan zijn. Omdat het display gemeenschappelijke kathodes heeft, betekent dit dat u slechts één set segmenten tegelijk kunt weergeven. Dat is een probleem voor dit project omdat we een letter bij het eerste cijfer en het platte symbool, indien nodig, tegelijkertijd willen weergeven. Onthoud nu het 7seg-kloksignaal? Om dit probleem te omzeilen, wisselen we de anodes en kathodes heen en weer op het 7seg-kloksignaal. Omdat het kloksignaal 240 Hz is en we twee cijfers gebruiken, oscilleert elk cijfer met 60 Hz. Voor het menselijk oog zal het lijken alsof de cijfers helemaal niet oscilleren.

Merk ook op dat het basys3-borddisplay negatieve logica gebruikt. Dit betekent dat als een anode of kathode is ingesteld op '0', dat cijfer of segment aan staat en vice versa.

Ingangen

  • Toonhoogte (binair getal voor een noot, gebruikt in afspeelstatus)
  • Freq (frequentieschakelaars, gebruikt in selectiestatus)
  • P_state (huidige status van PPS FSM)
  • Clk_240Hz (kloksignaal van Clk_div_7seg, dubbel 120 omdat we alleen de stijgende flank gebruiken)

Uitgangen

  • Kathode (bus die segmenten op het display bestuurt, einduitgang)
  • Anode (bus die de cijfers op het display bestuurt, einduitgang)

Componenten

  • Vergrendeling
  • MUX
  • D registreren

Stap 15: Definitieve selectie

Laatste selectie
Laatste selectie

Final select is de laatste module die in dit project wordt gebruikt. Een andere eenvoudige module, deze module regelt de uiteindelijke uitvoer die naar de DAC gaat. Wanneer in de "selectie" of "pauze" staat, zal de module een statische "0000" uitvoeren zodat er geen muziek uit de luidsprekers zal worden afgespeeld. In de "play"-status zal de module de oscillerende 4-bits uitvoeren zoals bepaald door square_wave.

Ingangen

  • P_state (huidige status van PPS FSM)
  • DAC_input (de oscillerende 4-bits van square_wave)

Uitgangen

DAC (gelijk aan DAC_input in afspeelstatus, uiteindelijke output)

Componenten

MUX

Stap 16: Externe apparaten: DAC

Externe apparaten: DAC
Externe apparaten: DAC

Een digitaal naar analoog omzetter (DAC) neemt een discreet signaal en zet dit om in een continu signaal. Onze DAC heeft vier bits en is gemaakt van een sommerende versterker. Door een verhouding van weerstanden in de toevoer- en feedbacklus te gebruiken, konden we een systeem creëren dat op 16 verschillende niveaus produceert door het "optellen" van elke tak. Bit0, de bovenste tak, draagt het minste gewicht en draagt het kleinste potentieel bij als hij hoog is, vanwege die hogere weerstand. Het gewicht neemt toe naarmate je de takken afdaalt. Als u binair zou tellen en vervolgens terug naar beneden met behulp van de bitingangen, zouden de uitgangsspanningen eruitzien als een stapsgewijze sinusgolf. De ingang naar de DAC was verbonden met een van de PMOD's op het bord om het 4-bits signaal over te dragen.

De DAC is oorspronkelijk geassembleerd voor een cursus Elektrotechniek en is door ons ontworpen en gesoldeerd, niet gekocht in een winkel. Hierboven ziet u een afbeelding van het ontwerpbestand voor het maken van de printplaat.

Stap 17: Externe apparaten: luidspreker

Externe apparaten: luidspreker
Externe apparaten: luidspreker

Voor dit project wil je geen supermooi paar luidsprekers kopen. Zoals je kunt zien, is het geluid vrij eenvoudig. We gingen en kochten een set computerluidsprekers van $ 8 van Best Buy. Alles met een koptelefoonaansluiting werkt prima. Monotoon werkt ook prima. Je kunt zelfs een koptelefoon gebruiken, maar je zou ze kunnen opblazen!

Om de uitgang van de DAC op de luidsprekers aan te sluiten, gebruikten we startkabels en hielden we de uitgangskabel tegen het uiteinde van de koptelefoonaansluiting en de kabel voor aarde aan de basis. We hebben geprobeerd om de kabels op hun plaats te houden met isolatietape, maar dat veroorzaakte veel storing. Het proberen van een ander soort tape zou dit probleem kunnen oplossen.

Voor onze luidsprekers hebben we ze op de hoogste stand gezet en kregen we een behoorlijk hard geluid.

En dat is de laatste stap voor het maken van een digitale sequencer van een FPGA-bord! Ga naar de volgende twee secties om al onze VHDL-code te downloaden en de sequencer in actie te zien.

Stap 18: Videodemo

Deze video toont de definitieve versie van het werkproject, inclusief het toewijzen van de schakelaars aan 4 verschillende toonhoogtes en de luidsprekers die de respectieve noten spelen.

Stap 19: VHDL-code

Hier is de code voor het hele project, inclusief de beperking en simbestanden die zijn gebruikt tijdens het bouwen van de sequencer. Merk op dat ongebruikte ontwerpbestanden dit in de architectuur aangeven.

Aanbevolen: