Innholdsfortegnelse:

4 trinns digital sekvensering: 19 trinn (med bilder)
4 trinns digital sekvensering: 19 trinn (med bilder)

Video: 4 trinns digital sekvensering: 19 trinn (med bilder)

Video: 4 trinns digital sekvensering: 19 trinn (med bilder)
Video: Stealing Baldi's Ruler and Swapping It With Funny Things!!! 2024, November
Anonim
4 trinns digital sekvensering
4 trinns digital sekvensering
4 trinns digital sekvensering
4 trinns digital sekvensering

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

Brukerbetjening av Digital Sequencer
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

Tekniske detaljer
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

Tekniske detaljer
Tekniske detaljer

Trinn 4: 7-segment Clock Divider

7-segment Clock Divider
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

Beats Per Minute Clock Divider
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
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

Spill/Pause/Velg State Machine
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

Spill/Pause/Velg State Machine
Spill/Pause/Velg State Machine

Trinn 9: Utdata FSM

Utgang FSM
Utgang 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

Utgang FSM
Utgang FSM

Trinn 11: Merk Tildel

Merk Tildel
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

Velg utgang
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

Square Wave Gen
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

7-segmenters skjerm
7-segmenters skjerm

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
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

Eksterne enheter: DAC
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

Eksterne enheter: Høyttaler
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: