Innholdsfortegnelse:
- Trinn 1: Brukerbetjening av Digital Sequencer
- Trinn 2: Tekniske detaljer
- Trinn 3: Tekniske detaljer
- Trinn 4: 7-segment Clock Divider
- Trinn 5: Beats Per Minute Clock Divider
- Trinn 6: Pitches Clock Divider
- Trinn 7: Spill/Pause/Velg State Machine
- Trinn 8: Spill/Pause/Velg State Machine
- Trinn 9: Utdata FSM
- Trinn 10: Utdata FSM
- Trinn 11: Merk Tildel
- Trinn 12: Velg utgang
- Trinn 13: Square Wave Gen
- Trinn 14: 7-segmenters display
- Trinn 15: Endelig valg
- Trinn 16: Eksterne enheter: DAC
- Trinn 17: Eksterne enheter: Høyttaler
- Trinn 18: Videodemo
- Trinn 19: VHDL -kode
Video: 4 trinns digital sekvensering: 19 trinn (med bilder)
2024 Forfatter: John Day | [email protected]. Sist endret: 2024-01-30 11:25
CPE 133, Cal Poly San Luis Obispo
Prosjektskapere: Jayson Johnston og Björn Nelson
I dagens musikkindustri er et av de mest brukte "instrumentene" den digitale synthesizeren. Hver musikksjanger, fra hip-hop til pop og til og med country, bruker en digital synthesizer i studio for å lage beats og lyder de trenger for å få liv i musikken sin. I denne opplæringen skal vi lage en veldig enkel synthesizer med Basys 3 FPGA -kortet.
Synthesizeren vil kunne spille fire utvalgte kvartnoter med et konstant antall slag per minutt. Brukere vil bruke bryterne for å tildele hver kvartnote til en musikalsk tonehøyde. For dette prosjektet bruker vi en 4-bits digital til analog omformer (DAC) for å ta utgangen fra kortet og konvertere det til et analogt signal. Utgangen fra DAC vil deretter bli matet til en standard datamaskinhøyttaler, og lage musikken vår. Seksten diskrete plasser er mulige. Vi vil begrense vår synthesizer til en enkelt oktav på 12 noter, som faller mellom midten C (261,6 Hz) og B4 (493,9 Hz). Brukeren vil også ha muligheten til å tilordne flere notater samtidig, i tillegg til å tildele en hvil ved å trykke på tildele mens ingen av pitch -bryterne er forskjøvet oppover. Etter hvert som hver tone velges og spilles, vises bokstavnoten på 7-segmenters display. Vi vil også bruke tre av knappene på brettet, en for å spille og sette musikken på pause, en for å tilbakestille synthesizeren og sette den i "utvalg" -modus, og den tredje for å tildele hver tone en tonehøyde i valgmodus.
Når brukeren er fornøyd med valget av notater, og etter å ha trykket på avspillingsknappen, spiller synthesizeren hver tone etter hverandre flere ganger inntil brukeren enten trykker på pause eller velger.
Her er en liste over nødvendig utstyr:
- Vivado (eller hvilken som helst VHDL -arbeidsplass)
- Basys 3 eller lignende FPGA -brett
- Digital til analog omformer (min. 4-bits)
- Høyttaler med hodetelefonkontakt
- Wire fører
Trinn 1: Brukerbetjening av Digital Sequencer
Følgende trinn er å betjene den digitale sequencer. Den digitale sequencer støtter avspilling av 12 forskjellige tonehøyder (C, Db, D, Eb, E, F, Gb, G, Ab, A, Bb, B), som varierer fra 261,6 Hz til 493,9 Hz.
1. Trykk på venstre knapp for å sette brettet i valgmodus. I denne modusen vil de fire bryterne til venstre (bryter 13 til 16) hver brukes til å lagre en distinkt tonehøydeverdi.
2. For å gjøre et valg, slå på en av de venstre bryterne, og bruk deretter de fire bryterne til høyre (bryterne 1 til 4) for å velge ønsket tonehøyde. Tonehøyden som er knyttet til en bestemt kombinasjon av høyre brytere vil bli vist på displayet med syv segmenter, og displayet vil oppdatere til den nye tilknyttede tonehøyden når de riktige bryterne flyttes til en ny kombinasjon. En hvil kan tildeles ved aldri å tilordne en tonehøyde til en av de venstre bryterne, eller ved å tilordne en tonehøyde vist som 0 på displayet til notatet. Når ønsket tonehøyde er funnet og vises på displayet, trykker du på nedre tildelingsknapp for å tilordne den spesifikke tonehøyden til notatet.
3. Gjenta trinn 2 for de tre gjenværende notene, ved å slå hver av de resterende venstre bryterne på hver for seg, velge den respektive tonehøyden med de høyre bryterne og trykke på den nederste knappen for å tilordne tonehøyden til notatet. Flere notater kan tildeles samme tonehøyde ved å flytte mer enn en av de venstre bryterne oppover samtidig.
4. Nå som alle notepitchene er tildelt, er den digitale sequencer klar til å spilles. For å spille notatene på høyttaleren, trykker du bare på høyre spill/pause -knapp for å begynne å spille musikken. Rekkefølgen på avspillingssekvensen gjenspeiler tonehøyde knyttet til venstre brytere, fra venstre til høyre. Notene vil bli spilt med et bestemt antall slag per minutt, i rekkefølgen 1, 2, 3, 4, 1, 2…. Displayet viser notatet som spilles av nå som høyttalerne spiller musikken. For å sette musikkavspillingen på pause, trykker du bare på høyre knapp. Så stopper musikken å spille og et pausesymbol vises på displayet. Trykk på høyre knapp igjen for å fortsette avspillingen.
Trinn 2: Tekniske detaljer
Vår synthesizer bruker mange forskjellige digitale komponenter. Inkludert er endelige tilstandsmaskiner, registre, multiplexere, klokkeavdelinger og mer. For å bygge vår synthesizer brukte vi 10 unike modulære filer. I stedet for å gjøre hver modul til en komponent, brøt vi modulfilene ned etter funksjon. De fleste moduler er derfor mer enn én komponent. Legg merke til at bildet ovenfor viser hver blokk knyttet sammen i vår toppdesign.
Vi vil diskutere hver modul ved å beskrive innganger og utganger, bryte ned komponentene og forklare formålet med den generelle designen. En ZIP -fil er inkludert nederst i instruksjonsboken, som inneholder hver VHDL -kodefil som brukes i prosjektet.
Innganger
- Clk (opprinnelig klokkesignal)
- PP (spill/pause)
- Sel (sett synthesizer i valgmodus)
- Tilordne (tilordne et trinn til en tonehøyde)
- Trinn (posisjonsnotatene)
- Freq (bryterne som skaper ønsket tonehøyde)
Utganger
- Anode (anoder med 7 segmenter)
- Katode (7-segment katoder)
- DAC (4-bits driver DAC)
Trinn 3: Tekniske detaljer
Trinn 4: 7-segment Clock Divider
Vår synthesizer bruker tre klokkeavdelere, som alle produserer signaler som tjener et annet formål i prosjektet vårt. En klokkeavdeler tar et native klokkesignal og produserer et endret signal som har en frekvens som er mindre enn det opprinnelige klokkesignalet. Den opprinnelige klokken til Basys 3 er 100 MHz. Dette er frekvensen som våre klokkeavdelinger bruker. Hvis du bruker et annet FPGA -kort med en annen innfødt klokkefrekvens, må du kanskje endre koden.
Den 7-segmenters klokkedeleren produserer et signal som driver filen seg_display. Vi vil forklare hvordan denne filen fungerer mer detaljert når vi kommer til delen. I hovedsak produserer denne klokkeavdeleren et 240 Hz signal som vil bli brukt til å bytte mellom anoder og katoder på displayet. Signalet er 240 Hz fordi frekvensen som det menneskelige øye ikke kan gjenkjenne fravær av lys er 60 Hz. Vi bruker to siffer, så ved å doble denne frekvensen vil hvert siffer svinge ved 60 Hz. Så dobler vi det for å få 240 Hz fordi systemet bare endres når signalet går høyt, ikke når det går lavt.
For å oppnå dette tar divideren det opprinnelige 100 MHz -signalet og teller opp på hver stigende kant. Når telleren når 416667, går utgangen fra lav til høy, eller omvendt.
Innganger
Clk (opprinnelig klokkesignal)
Utganger
Clk_7seg (til seg_display)
Komponenter
- D registrere
- MUX
- Inverter
- Adder
Trinn 5: Beats Per Minute Clock Divider
BPM -klokkeavdeleren fungerer på en lignende måte. Denne divideren produserer klokkefrekvensen som driver vekslingen mellom de fire trinnene når du sender ut toner i avspillingstilstanden. Vi bestemte oss for å bytte mellom notater ved 100 BPM. Ved 100 BPM vil hver tone bli spilt i 3/5 sekund. Det resulterende signalet vil ha en frekvens på 1,67 Hz.
For å produsere et signal om denne frekvensen brukte vi igjen et tellesystem, men denne gangen var tellingen 60 millioner. Hver gang telleren traff 60 millioner, ville utgangssignalet veksle høyt eller lavt.
Innganger
Clk (egen klokkefrekvens)
Utganger
Clk_BPM (til output_FSM)
Komponenter
- D registrere
- MUX
- Inverter
- Adder
Trinn 6: Pitches Clock Divider
Pitches Clock Divider er den største av våre klokkeutskillere. Denne divideren sender ut 12 forskjellige signaler som tilsvarer de 12 forskjellige notene som vår synthesizer kan spille. Ved å bruke grunnleggende kunnskap om musikkteori, fant vi ut at en bit eller buss kunne svinge med en hastighet som tilsvarer frekvensen av musikknoter. For å se frekvensene vi brukte, se her. Vi brukte den fjerde oktaven av tonehøyder.
Det samme tellesystemet brukes her. For de spesifikke verdiene vi teller til, se filen merket Clk_div_pitches.
Innganger
Clk (egen klokkefrekvens)
Utganger
C, Db, D, Eb, E, F, Gb, G, Ab, A, Bb, B (til output_select)
Komponenter
- D registrere
- MUX
- Inverter
- Adder
Trinn 7: Spill/Pause/Velg State Machine
I vårt prosjekt er det to finite state machines (FSM). En FSM er en logisk enhet som bare kan eksistere i en tilstand ut av en begrenset mengde tilstander. Ved hjelp av en FSM kan en digital krets flytte til en ny tilstand basert på en kombinasjon av innganger. Ved å bruke inngangslogikk vil tilstanden til en FSM endres når det er en stigende kant på klokken. Fra tilstanden og innganger til kretsen kan du lage utgangslogikk som gir utganger som bare eksisterer hvis FSM er i en bestemt tilstand.
PPS -tilstandsmaskinen er den første FSM i vår krets. Det er tre stater i denne FSM; Spill, pause og valgmodus. For å bevege oss gjennom de forskjellige statene brukte vi knappene PP og Selection. Se tilstandsdiagrammet ovenfor for å se hvordan overganger mellom tilstander skjer. Vi foretok denne FSM -overgangen på den økende kanten av den opprinnelige 100 MHz -klokken, slik at det ville være umulig for maskinen å ikke gå over når en av knappene ble trykket, selv i veldig kort tid. Den nåværende tilstanden (P_state) er den eneste utgangen fra denne modulen.
Innganger
- Clk (egen klokkefrekvens)
- Sel (venstre knapp)
- PP (høyre knapp)
Utganger
P_state (nåværende tilstand, til output_FSM, note_assign, seg_dsiplay, final_select)
Komponenter
- MUX
- D registrere
Trinn 8: Spill/Pause/Velg State Machine
Trinn 9: Utdata FSM
Dette er den andre FSM det er referert til i forrige seksjon. Denne FSM har en annen funksjon enn den andre, men grunnlaget for denne er i hovedsak den samme.
Utgangen FSM fungerer bare hvis nåværende tilstand fra den første FSM er "01" (avspillingstilstanden). I hovedsak er dette aktiveringen for modulen. Hvis tilstanden er "01", vil FSM bytte mellom tilstander på den stigende kanten av BPM -klokkesignalet. Vi gjør dette fordi output_FSM kontrollerer hvilket binært tall for den valgte tonehøyden som sendes til output_select og seg_display modulene. FSM har en 16-biters inngang som kommer fra notattildelingsmodulen, som vil bli dekket neste. I tilstanden "00" for output_FSM sender modulen "xxxx" for det første notatet som er tildelt. Så i "01", vil den sende "åååå" for den andre noten og så videre for hver note før den ruller tilbake til den første noten. Se tilstandsdiagrammet ovenfor.
Denne FSM skiller seg fra den første fordi det ikke er noen inngangslogikk for å kontrollere bytte mellom tilstander. I stedet skal FSM bare fungere når staten fra den første FSM er "01", og deretter vil denne FSM overgå mellom tilstander bare på den stigende kanten av klokkesignalet. En annen forskjell er at denne modulen har utgangslogikk, noe som betyr at den ikke sender ut nåværende tilstand, den sender ut det binære tallet for tonehøyden ved den tilstanden.
Innganger
- Clk_BPM (BPM klokkesignal fra klokkeskille)
- FSM1_state (PS fra PPS FSM)
- Pitch_in (plasser fra note_assign)
Utganger
Pitch_out (én tonehøyde om gangen, for å velge output og seg_display)
Komponenter
- MUX
- D registrere
Trinn 10: Utdata FSM
Trinn 11: Merk Tildel
Note -tildelingsmodulen er ansvarlig for å faktisk tilordne en tonehøyde til posisjonsnotatet eller trinnet. Denne modulen er faktisk ganske enkel. Den sjekker først om kretsen er i "utvalg" -tilstand og om en trinnbryter (helt til venstre) er høy. Hvis dette er sant og tildelingsknappen trykkes, vil modulens utgang være lik det binære tallet representert av frekvensbryterne (helt til høyre).
Opprinnelig hadde vi forsøkt å lage en modul som faktisk ville lagre et av pitch -klokkesignalene til utgangen, men vi opplevde problemer med at utgangen endret seg for å følge inngangssignalene. Dette er den eneste modulen som ble brukt mer enn én gang i den endelige designen. Hvert trinn har en note_assign -modul tilknyttet, og på grunn av det får hver forekomst av modulen en bit av Step -bussen.
Innganger
- P_state (nåværende tilstand fra PPS FSM)
- Sel (venstre knapp)
- Bryter (ett -trinns bryter)
- Freq (brytere til høyre for tonehøyde)
- Tildel (nederste knapp, tilordner et notat)
Utganger
Pitch (binært tall, til output_FSM)
Komponenter
- MUX
- D resgister
Trinn 12: Velg utgang
Output select er ansvarlig for å ta det binære tallet for en tonehøyde og koble det til det respektive klokkesignalet. Til tross for størrelsen er dette også en relativt enkel modul. Output_select er i hovedsak en binær dekoder, som dekoder det binære tallet for en tonehøyde til et bestemt klokkesignal. Faktisk fungerte det å tilordne utgangen til en klokkefrekvens bedre her sammenlignet med note_assign -modulen, fordi alt denne modulen måtte gjøre var MUX klokkesignalene med det binære nummeret som representerer kontrollinngangen.
Vi beklager den merkelige routingen, Vivado organiserte tonehøyde -signalene alfabetisk for filen clk_div_pitches, men for denne filen organiserte de dem ved å stige binært tall, noe som fikk pitchene til å være i en annen rekkefølge. Vær også oppmerksom på at hvis det binære tallet fra output_FSM var "0000" eller noe større enn "1100", sendte MUX gjennom et flatt "0" -signal.
Inngang
- Pitch (fra output_FSM);
- C, Db, D, Eb, E, F, Gb, G, Ab, A, Bb, B (stigningssignaler)
Produksjon
Tone (en enkelt bit som matcher det valgte klokkesignalet, til square_wave)
Komponenter
MUX
Trinn 13: Square Wave Gen
Modul square_wave er generatoren for firkantbølgen som sendes ut fra brettet til DAC. Ved å bruke tonesignalet fra den forrige filen, inverterer denne square_wave 4 -bits tallet mellom "0000" og "1111" på den stigende kanten av Tone. Tone er en bestemt tonehøydefrekvens, så square_wave produserer en bølge med en annen frekvens når output_FSM overgår til en annen tilstand. 4-biters utgang fra denne modulen går til fin_sel-modulen, der logikken tilsier om denne bussen vil bli sendt ut basert på tilstanden fra PPS FSM.
Et alternativ til denne firkantbølgeneratoren produserer en sinusbølge. Selv om dette sannsynligvis vil gi en bedre sluttone, er det betydelig vanskeligere å implementere, så vi valgte å bare generere en firkantbølge.
Innganger
Tone (oscillerende bit fra output_select)
Utganger
DAC_input (oscillerende 4-biters buss som endres med samme frekvens)
Komponenter
- Inverter
- D registrere
Trinn 14: 7-segmenters display
Seg_display-modulen styrer 7-segmentet displayet på vårt grunnkort. Innen modulen skjer to prosesser. Den første prosessen dekoder Freq når den er i "utvalg" -tilstand eller Pitch når den er i "play" -modus. I "pause" -modus dekoder modulen for å vise pausesymbolet. Når du ser på VHDL -koden, kan du se at den binære dekoderen faktisk dekoder inngangen til to forskjellige signaler, katode1 og katode2. Katode1 representerer bokstaven som tilsvarer tonehøyden som skal vises, og katode2 representerer det flate symbolet (b) hvis det er en. Årsaken til dette er den andre prosessen som seg_display -modulen utfører.
På et basys3 -bord har segmentdisplayet vanlige katoder. Mens anodene styrer hvilket siffer som er slått på, kontrollerer katodene hvilke segmenter som er på. Siden displayet har vanlige katoder, betyr det at du bare kan vise ett sett med segmenter om gangen. Det utgjør et problem for dette prosjektet fordi vi ønsker å vise en bokstav på det første sifferet og flatt symbol, om nødvendig, samtidig. Husker du nå 7seg -klokkesignalet? For å omgå dette problemet endrer vi anoder og katoder frem og tilbake på 7seg klokkesignal. Fordi klokkesignalet er 240 Hz og vi bruker to siffer, vil hvert siffer svinge ved 60 Hz. For det menneskelige øyet vil det se ut som sifrene ikke svinger i det hele tatt.
Vær også oppmerksom på at basys3 -kortdisplayet bruker negativ logikk. Dette betyr at hvis en anode eller katode er satt til '0', vil sifferet eller segmentet være på, og omvendt.
Innganger
- Pitch (binært tall for en note, brukt i play -tilstand)
- Freq (frekvensbrytere, brukt i valgtilstand)
- P_state (nåværende tilstand fra PPS FSM)
- Clk_240Hz (klokkesignal fra Clk_div_7seg, dobbelt 120 fordi vi bare bruker den stigende kanten)
Utganger
- Katode (buss som styrer segmenter på displayet, endelig utgang)
- Anode (buss som kontrollerer sifre på displayet, endelig utgang)
Komponenter
- Klinke
- MUX
- D registrere
Trinn 15: Endelig valg
Endelig valg er den siste modulen som ble brukt i dette prosjektet. En annen enkel modul, denne modulen styrer den endelige utgangen som skal til DAC. Når den er i "utvalg" eller "pause" -modus, sender modulen ut en statisk "0000" slik at det ikke spilles musikk fra høyttalerne. I "play" -tilstanden sender modulen ut de oscillerende 4-bitene som bestemt av square_wave.
Innganger
- P_state (nåværende tilstand fra PPS FSM)
- DAC_input (de oscillerende 4-bitene fra square_wave)
Utganger
DAC (tilsvarer DAC_inngang i avspillingstilstand, endelig utgang)
Komponenter
MUX
Trinn 16: Eksterne enheter: DAC
En digital til analog omformer (DAC) tar et diskret signal og konverterer det til et kontinuerlig signal. Vår DAC har fire bits og er laget av en summerende forsterker. Ved å bruke et forhold mellom motstander i tilførsels- og tilbakemeldingssløyfen, var vi i stand til å lage et system som sender ut på 16 forskjellige nivåer og skaper ved "summering" av hver gren. Bit0, den øvre grenen, bærer minst vekt og bidrar med det minste potensialet når det er høyt på grunn av det forgrener høyere motstand. Vekten øker når du går ned grenene. Hvis du skulle telle i binær opp og deretter tilbake med bitinngangene, ville utgangsspenningene se ut som en trinnvis sinusbølge. Inngangen til DAC ble koblet til en av PMODene på brettet for å overføre 4-bits signalet.
DAC ble opprinnelig montert for en elektroteknikk -klasse og ble designet og loddet av oss, ikke kjøpt fra en butikk. Over er et bilde av designfilen for å lage kretskortet.
Trinn 17: Eksterne enheter: Høyttaler
For dette prosjektet har du ikke tenkt å kjøpe et superfint par høyttalere. Som du kan se, er lyden ganske grunnleggende. Vi gikk og kjøpte et sett med datamaskiner på $ 8 fra Best Buy. Alt med hodetelefonkontakt fungerer fint. Monoton fungerer også bra. Du kan til og med bruke hodetelefoner, men du kan blåse dem ut!
For å koble utgangen fra DAC til høyttalerne brukte vi hoppekabler og holdt utgangskabelen til spissen av hodetelefonkontakten og kabelen for jord til basen. Vi prøvde å bruke elektrisk tape for å holde kablene på plass, men det forårsaket mye interferens. Å prøve en annen båndstil kan løse dette problemet.
For høyttalerne våre snudde vi dem til den høyeste innstillingen og fikk en anstendig høy lyd.
Og det er det siste trinnet for å lage en digital sequencer fra et FPGA -kort! Gå til de to neste seksjonene for å laste ned all vår VHDL -kode og se sequencer i aksjon.
Trinn 18: Videodemo
Denne videoen viser den endelige versjonen av arbeidsprosjektet, inkludert prosessen med å tildele bryterne til 4 forskjellige tonehøyder, og høyttalerne spiller de respektive notene.
Trinn 19: VHDL -kode
Her er koden for hele prosjektet, inkludert begrensningen og simfilene som ble brukt mens du bygger sequencer. Vær oppmerksom på at ubrukte designfiler sier det i arkitekturen.
Anbefalt:
Enkel sekvensering: 16 trinn (med bilder)
Simple Sequencer: En av nøklene til å lage god musikk er tankeløs repetisjon. Det er det den enkle sequencer er god til. Den gjør det samme igjen og igjen i en sekvens på åtte toner. Du kan justere frekvensen til notatet, varigheten av notatet og
Trinn-for-trinns utdanning i robotikk med et sett: 6 trinn
Trinn-for-trinns utdanning i robotikk med et sett: Etter ganske mange måneder med å bygge min egen robot (vennligst se alle disse), og etter to ganger å ha deler mislyktes, bestemte jeg meg for å ta et skritt tilbake og tenke på mitt eget strategi og retning. Flere måneders erfaring var til tider veldig givende, og
11 trinns rube Goldberg -maskin: 8 trinn
11 Step Rube Goldberg Machine: Dette prosjektet er en 11 Step Rube Goldberg Machine, som er designet for å danne en enkel oppgave på en komplisert måte. Oppgaven til dette prosjektet er å fange en såpestang
Innkapsling av trinns servomotor med seriell kontroll via Arduino ved bruk av en 3D -skriver - Pt4: 8 trinn
Innkapsling av trinnservomotoren med seriell kontroll via Arduino ved hjelp av en 3D -skriver - Pt4: I denne fjerde videoen i Motor Step -serien bruker vi det vi tidligere har lært for å bygge en stepper servomotor med kontroll via seriell kommunikasjon og ekte posisjon tilbakemelding ved hjelp av en resistiv encoder overvåket av en Arduino. I
4-trinns trådløs Qi-lader: 9 trinn (med bilder)
4-trinns trådløs Qi-lader: Ladestasjonen er laserskåret av kryssfiner av varierende tykkelse og polyetylen, deretter montert med en hånd full av rustfritt #2 x 3/8 " og #4 x 1/2 " flatt hode, metallskruer. En 60W CO2 -laser er tilstrekkeligBaltic Birch kryssfiner i