Innehållsförteckning:

4 -stegs digital sequencer: 19 steg (med bilder)
4 -stegs digital sequencer: 19 steg (med bilder)

Video: 4 -stegs digital sequencer: 19 steg (med bilder)

Video: 4 -stegs digital sequencer: 19 steg (med bilder)
Video: Следки спицами БЕЗ ШВА. Узор СОВА. Подробный мастер класс. МК ДЛЯ НАЧИНАЮЩИХ. 2024, Juli
Anonim
4 -stegs digital sequencer
4 -stegs digital sequencer
4 -stegs digital sequencer
4 -stegs digital sequencer

CPE 133, Cal Poly San Luis Obispo

Projektskapare: Jayson Johnston och Björn Nelson

I dagens musikindustri är ett av de mest använda "instrumenten" den digitala synten. Varje musikgenre, från hip-hop till pop och till och med country, använder en digital synthesizer i studion för att skapa de beats och ljud de behöver för att väcka sin musik till liv. I denna handledning kommer vi att skapa en mycket enkel synthesizer med Basys 3 FPGA -kortet.

Synthesizern kommer att kunna spela fyra utvalda kvartnoter med ett konstant antal slag per minut. Användare kommer att använda omkopplarna för att tilldela varje kvartnot till en musikalisk tonhöjd. För detta projekt använder vi en 4-bitars digital till analog omvandlare (DAC) för att ta utmatningen från kortet och konvertera den till en analog signal. Utmatningen från DAC matas sedan till en vanlig datorhögtalare, vilket skapar vår musik. Sexton diskreta platser är möjliga. Vi kommer att begränsa vår synthesizer till en enda oktav på 12 toner, som ligger mellan mitt C (261,6 Hz) och B4 (493,9 Hz). Användaren har också möjlighet att tilldela flera anteckningar samtidigt, samt tilldela en vila genom att trycka på tilldelning medan ingen av tonhöjdsbrytarna flyttas uppåt. När varje ton väljs och spelas, visas bokstavsnoten på 7-segmentet. Vi kommer också att använda tre av knapparna på tavlan, en för att spela och pausa musiken, en för att återställa synthesizern och sätta den i "urvals" -läge, och den tredje för att tilldela varje ton en tonhöjd i urvalsläget.

När användaren är nöjd med valet av anteckningar, och efter att ha tryckt på uppspelningsknappen, kommer synthesizern att spela varje ton efter varandra tills användaren antingen trycker på paus eller väljer.

Här är en lista över nödvändig utrustning:

  • Vivado (eller något VHDL -arbetsutrymme)
  • Basys 3 eller liknande FPGA -kort
  • Digital till analog omvandlare (min. 4-bitars)
  • Högtalare med hörlursuttag
  • Wire leder

Steg 1: Användaranvändning av Digital Sequencer

Användaranvändning av Digital Sequencer
Användaranvändning av Digital Sequencer

Följande steg är att styra den digitala sequencern. Den digitala sequencern stöder uppspelning av 12 olika tonhöjningar (C, Db, D, Eb, E, F, Gb, G, Ab, A, Bb, B), som sträcker sig från 261,6 Hz till 493,9 Hz.

1. Tryck på vänster knapp för att sätta kortet i urvalsläge. I detta läge kommer de fyra omkopplarna längst till vänster (omkopplare 13 till 16) att användas för att lagra ett distinkt tonvärde.

2. För att göra ett val, slå på en av de vänstra omkopplarna och använd sedan de högra 4 omkopplarna (omkopplare 1 till 4) för att välja önskad tonhöjd. Tonhöjden som är associerad med en specifik kombination av högeromkopplare kommer att visas på sjusegmentsdisplayen, och displayen uppdateras till den nya associerade tonhöjden varje gång de högra omkopplarna flyttas till en ny kombination. En vila kan tilldelas genom att aldrig tilldela en tonhöjd till en av de vänstra omkopplarna eller genom att tilldela noten en tonhöjd som visas som 0 på displayen. När önskad tonhöjd har hittats och visas på displayen, tryck på nedre tilldelningsknappen för att tilldela noten den specifika tonhöjden.

3. Upprepa steg 2 för de tre återstående tonerna genom att slå på var och en av de återstående vänsteromkopplarna individuellt, välja respektive tonhöjd med de högra omkopplarna och trycka på den nedre knappen för att tilldela tonhöjden till noten. Flera anteckningar kan tilldelas samma tonhöjd genom att flytta mer än en av de vänstra omkopplarna uppåt samtidigt.

4. Nu när alla tonhöjden har tilldelats är den digitala sequencern redo att spela. För att spela noterna på högtalaren, tryck helt enkelt på höger uppspelning/pausknapp för att börja spela musiken. Ordningen för uppspelningssekvensen speglar tonhöjden som är associerad med de vänstra omkopplarna, från vänster till höger. Noterna kommer att spelas med ett bestämt antal slag per minut, i ordningen 1, 2, 3, 4, 1, 2…. Displayen visar anteckningen som spelas för när högtalarna spelar musiken. För att pausa musikuppspelningen, tryck helt enkelt på den högra knappen, så slutar musiken att spela och en paussymbol visas på displayen. Om du trycker på den högra knappen igen återupptas uppspelningen.

Steg 2: Tekniska detaljer

Tekniska detaljer
Tekniska detaljer

Vår synthesizer använder många olika digitala komponenter. Inkluderade är slutliga tillståndsmaskiner, register, multiplexer, klockavdelare och mer. För att bygga vår synthesizer använde vi 10 unika modulfiler. I stället för att göra varje modul till en komponent, delade vi ner modulfilerna efter funktion. De flesta moduler är därför mer än en komponent. Observera att bilden ovan visar varje block bunden i vår toppdesign.

Vi kommer att diskutera varje modul genom att beskriva inmatningar och utgångar, bryta ner dess komponenter och förklara dess syfte i den övergripande designen. En ZIP -fil ingår längst ner i instruktionsboken, som innehåller alla VHDL -kodfiler som används i projektet.

Ingångar

  • Clk (inbyggd klocksignal)
  • PP (spela/pausa)
  • Sel (sätt synthesizer i urvalsläge)
  • Tilldela (tilldela ett steg till en tonhöjd)
  • Steg (positionsnoteringarna)
  • Freq (switcharna som skapar önskad tonhöjd)

Utgångar

  • Anod (anoder med 7 segment)
  • Katod (katoder med 7 segment)
  • DAC (4-bitars drivning av DAC)

Steg 3: Tekniska detaljer

Tekniska detaljer
Tekniska detaljer

Steg 4: 7-segment Clock Divider

7-segment Clock Divider
7-segment Clock Divider

Vår synthesizer använder sig av tre klockavdelare som alla producerar signaler som tjänar ett annat syfte i vårt projekt. En klockdelare tar en inbyggd klocksignal och producerar en förändrad signal som har en frekvens som är mindre än den ursprungliga klocksignalen. Basys 3 är 100 MHz. Detta är frekvensen som våra klockavdelare använder. Om du använder ett annat FPGA -kort med en annan inbyggd klockfrekvens kan du behöva ändra koden.

Klockavdelaren med 7 segment producerar en signal som driver filen seg_display. Vi kommer att förklara hur den här filen fungerar mer i detalj när vi kommer till dess avsnitt. I huvudsak producerar denna klockdelare en 240 Hz signal som kommer att användas för att växla mellan anoder och katoder på displayen. Signalen är 240 Hz eftersom frekvensen vid vilken det mänskliga ögat inte kan känna igen frånvaro av ljus är 60 Hz. Vi använder två siffror, så genom att fördubbla denna frekvens kommer varje siffra att pendla vid 60 Hz. Sedan dubblar vi det för att få 240 Hz eftersom systemet bara förändras när signalen går högt, inte när den går lågt.

För att uppnå detta tar avdelaren den inbyggda 100 MHz -signalen och räknar med varje stigande kant. När räknaren når 416667 går utmatningen från låg till hög, eller vice versa.

Ingångar

Clk (inbyggd klocksignal)

Utgångar

Clk_7seg (till seg_display)

Komponenter

  • D registrera
  • MUX
  • Inverter
  • Huggorm

Steg 5: Beats Per Minute Clock Divider

Beats Per Minute Clock Divider
Beats Per Minute Clock Divider

BPM -klockavdelaren fungerar på ett liknande sätt. Denna avdelare producerar klockfrekvensen som driver växlingen mellan de fyra stegen när toner matas ut i spelläget. Vi bestämde oss för att växla mellan anteckningar vid 100 BPM. Vid 100 BPM spelas varje ton i 3/5 sekund. Den resulterande signalen skulle ha en frekvens på 1,67 Hz.

För att producera en signal med denna frekvens använde vi igen ett räknesystem, men den här gången var räkningen 60 miljoner. Varje gång räknaren träffade 60 miljoner skulle utsignalen växla högt eller lågt.

Ingångar

Clk (inbyggd klockfrekvens)

Utgångar

Clk_BPM (till output_FSM)

Komponenter

  • D registrera
  • MUX
  • Inverter
  • Huggorm

Steg 6: Pitches Clock Divider

Pitches Clock Divider
Pitches Clock Divider

Pitches Clock Divider är den största av våra klockavdelare. Denna avdelare matar ut 12 olika signaler som motsvarar de 12 olika noterna som vår synthesizer kan spela. Med hjälp av grundläggande kunskap om musikteori, drog vi slutsatsen att en bit eller buss kunde svänga med en hastighet som motsvarar frekvensen av musiknoter. För att se de frekvenser vi använde, titta här. Vi använde den fjärde oktaven av tonhöjden.

Samma räknesystem används här. För de specifika värden som vi räknade till, se filen märkt Clk_div_pitches.

Ingångar

Clk (inbyggd klockfrekvens)

Utgångar

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

Komponenter

  • D registrera
  • MUX
  • Inverter
  • Huggorm

Steg 7: Spela/Pausa/Välj tillståndsmaskin

Spela/pausa/välj tillståndsmaskin
Spela/pausa/välj tillståndsmaskin

I vårt projekt finns två finite state machines (FSM). En FSM är en logisk enhet som kan existera i endast ett tillstånd av en begränsad mängd tillstånd. Med hjälp av en FSM kan en digital krets flytta till ett nytt tillstånd baserat på en kombination av ingångar. Med hjälp av inmatningslogik ändras tillståndet för en FSM när det finns en stigande kant på klockan. Från tillståndet och ingångar till kretsen kan du skapa utgångslogik som ger utgångar som bara finns om FSM är i ett visst tillstånd.

PPS -tillståndsmaskinen är den första FSM i vår krets. Det finns tre stater i denna FSM; Spela, pausa och urvalsläge. För att gå igenom de olika tillstånden använde vi knapparna PP och Selection. Se tillståndsdiagrammet ovan för att se hur övergångar mellan tillstånd uppstår. Vi gjorde denna FSM -övergång på den stigande kanten av den inbyggda 100 MHz -klockan, så att det skulle vara omöjligt för maskinen att inte övergå när en av knapparna trycktes in, även under en mycket kort tid. Det nuvarande tillståndet (P_state) är den enda utsignalen från denna modul.

Ingångar

  • Clk (inbyggd klockfrekvens)
  • Sel (vänster knapp)
  • PP (höger knapp)

Utgångar

P_state (nuvarande tillstånd, till output_FSM, note_assign, seg_dsiplay, final_select)

Komponenter

  • MUX
  • D registrera

Steg 8: Spela/pausa/välj tillståndsmaskin

Spela/pausa/välj tillståndsmaskin
Spela/pausa/välj tillståndsmaskin

Steg 9: Mata ut FSM

Utgång FSM
Utgång FSM

Detta är den andra FSM som det hänvisas till i föregående avsnitt. Denna FSM tjänar en annan funktion än den andra, men grunden för den här är i huvudsak densamma.

Utmatningen FSM fungerar bara om det nuvarande tillståndet från den första FSM är "01" (uppspelningstillståndet). I huvudsak är detta aktiveringen för modulen. Om tillståndet är "01" kommer FSM att växla mellan tillstånd på den stigande kanten av BPM -klocksignalen. Vi gör detta eftersom output_FSM styr vilket binärt tal för den valda tonhöjden som skickas till output_select- och seg_display -modulerna. FSM har en 16-bitars ingång som kommer från nottilldelningsmodulen, som kommer att täckas härnäst. I tillståndet "00" för output_FSM kommer modulen att mata ut "xxxx" för den första noten som tilldelats. Sedan i "01" kommer det att skrivas ut "åååå" för den andra noten och så vidare för varje ton innan den rullar tillbaka till den första noten. Se tillståndsdiagrammet ovan.

Denna FSM skiljer sig från den första eftersom det inte finns någon ingångslogik för att styra växlingen mellan tillstånd. I stället kommer FSM bara att fungera när tillståndet från den första FSM är "01", och sedan kommer denna FSM att övergå mellan tillstånd endast på den stigande kanten av klocksignalen. En annan skillnad är att denna modul har utgångslogik, vilket betyder att den inte matar ut det nuvarande tillståndet, den matar ut det binära talet för tonhöjden vid det tillståndet.

Ingångar

  • Clk_BPM (BPM -klocksignal från klockavdelaren)
  • FSM1_state (PS från PPS FSM)
  • Pitch_in (pitches from note_assign)

Utgångar

Pitch_out (en tonhöjd i taget, för output_select och seg_display)

Komponenter

  • MUX
  • D registrera

Steg 10: Mata ut FSM

Utgång FSM
Utgång FSM

Steg 11: Notera Tilldela

Notera Tilldela
Notera Tilldela

Nottilldelningsmodulen är ansvarig för att faktiskt tilldela en tonhöjd till positionsnoten eller steget. Denna modul är faktiskt ganska enkel. Den kontrollerar först om kretsen är i "urvals" -läget och om en stegomkopplare (längst till vänster) är hög. Om detta är sant och tilldelningsknappen trycks in kommer modulens utgång att vara lika med det binära talet som representeras av frekvensomkopplarna (längst till höger).

Ursprungligen hade vi försökt att göra en modul som faktiskt skulle spara en av tonklockans signaler till utgången, men vi upplevde problem med att utgången ändrades för att följa ingångsklocksignalerna. Detta är den enda modulen som används mer än en gång i den slutliga designen. Varje steg har en note_assign -modul kopplad till sig, och på grund av det får varje instans av modulen en bit av Step -bussen.

Ingångar

  • P_state (nuvarande tillstånd från PPS FSM)
  • Sel (vänster knapp)
  • Brytare (ettstegsbrytare)
  • Freq (längst till höger omkopplare för tonhöjd)
  • Tilldela (nedre knappen, tilldela en anteckning)

Utgångar

Pitch (binärt tal, till output_FSM)

Komponenter

  • MUX
  • D resgister

Steg 12: Välj utmatning

Välj utmatning
Välj utmatning

Output select är ansvarig för att ta det binära numret för en tonhöjd och ansluta det till dess respektive klocksignal. Trots sin storlek är detta också en relativt enkel modul. Output_select är i huvudsak en binär avkodare, som avkodar det binära talet för en tonhöjd till en specifik klocksignal. Egentligen fungerade tilldelning av utgången till en klockfrekvens bättre här jämfört med note_assign -modulen, för allt denna modul var tvungen att MUXa klocksignalerna med det binära talet som representerar kontrollingången.

Vi ber om ursäkt för den konstiga routingen, Vivado organiserade tonhöjdssignalerna alfabetiskt för filen clk_div_pitches, men för den här filen organiserade de dem genom stigande binärt tal, vilket gjorde att tonhöjden var i en annan ordning. Observera också att om det binära talet från output_FSM var "0000" eller något som är större än "1100", skickade MUX via en platt "0" -signal.

Inmatning

  • Pitch (från output_FSM);
  • C, Db, D, Eb, E, F, Gb, G, Ab, A, Bb, B (tonklocksignaler)

Produktion

Ton (en enda bit som matchar den valda klocksignalen, till square_wave)

Komponenter

MUX

Steg 13: Square Wave Gen

Square Wave Gen
Square Wave Gen

Modul square_wave är generatorn för kvadratvågan som matas ut från kortet till DAC. Med hjälp av tonsignalen från den föregående filen inverterar denna square_wave 4 -bitars talet mellan "0000" och "1111" på tonens stigande kant. Ton är en specifik tonfrekvens, så square_wave producerar en våg med en annan frekvens när output_FSM övergår till ett annat tillstånd. 4-bitarsutmatningen från denna modul går till fin_sel-modulen, där logiken dikterar om denna buss kommer att matas ut baserat på tillståndet från PPS FSM.

Ett alternativ till denna fyrkantvågsgenerator producerar en sinusvåg. Även om detta med största sannolikhet skulle ge en bättre slutton, är det betydligt svårare att implementera, så vi valde att bara generera en fyrkantvåg.

Ingångar

Ton (oscillerande bit från output_select)

Utgångar

DAC_input (oscillerande 4-bitars buss som ändras vid samma tonfrekvens)

Komponenter

  • Inverter
  • D registrera

Steg 14: 7-segment Display

7-segment Display
7-segment Display

Seg_display-modulen styr 7-segmentskärmen på vårt grundkort. Inom modulen sker två processer. Den första processen avkodar Freq i "urvals" -läget eller Pitch när "play" -läget. I "paus" -läget avkodar modulen för att visa paussymbolen. Om man tittar på VHDL -koden kan man se att den binära avkodaren faktiskt avkodar ingången till två olika signaler, katod1 och katod2. Katod1 representerar bokstaven som motsvarar tonhöjden som ska visas, och katod2 representerar den platta symbolen (b) om det finns en. Anledningen till detta hänför sig till den andra processen som seg_display -modulen utför.

På ett basys3 -kort har segmentdisplayen gemensamma katoder. Medan anoderna styr vilken siffra som slås på, styr katoderna vilka segment som är på. Eftersom displayen har gemensamma katoder betyder det att du bara kan visa en uppsättning segment åt gången. Det är ett problem för det här projektet eftersom vi vill visa en bokstav med den första siffran och platt symbolen, om det behövs, samtidigt. Kommer du nu ihåg 7seg klocksignalen? För att komma runt detta problem ändrar vi anoder och katoder fram och tillbaka på 7seg klocksignalen. Eftersom klocksignalen är 240 Hz och vi använder två siffror kommer varje siffra att pendla vid 60 Hz. För det mänskliga ögat kommer det att se ut som om siffrorna inte oscillerar alls.

Observera också att basys3 -kortets display använder negativ logik. Det betyder att om en anod eller katod är inställd på '0', kommer den siffran eller segmentet att vara på och vice versa.

Ingångar

  • Pitch (binärt tal för en ton, används i spelläge)
  • Freq (frekvensomkopplare, används vid val)
  • P_state (nuvarande tillstånd från PPS FSM)
  • Clk_240Hz (klocksignal från Clk_div_7seg, dubbel 120 eftersom vi bara använder den stigande kanten)

Utgångar

  • Katod (buss som styr segment på displayen, slutlig utgång)
  • Anod (buss som styr siffror på displayen, slutlig utgång)

Komponenter

  • Spärr
  • MUX
  • D registrera

Steg 15: Slutval

Slutval
Slutval

Slutval är den sista modulen som används i detta projekt. En annan enkel modul, denna modul styr den slutliga utmatningen som kommer att gå till DAC. I läget "urval" eller "paus" kommer modulen att mata ut en statisk "0000" så att ingen musik kommer att spelas från högtalarna. I "play" -läget kommer modulen att mata ut de oscillerande 4-bitarna som bestäms av square_wave.

Ingångar

  • P_state (nuvarande tillstånd från PPS FSM)
  • DAC_input (de oscillerande 4-bitarna från square_wave)

Utgångar

DAC (är lika med DAC_input i spelläge, slututgång)

Komponenter

MUX

Steg 16: Externa enheter: DAC

Externa enheter: DAC
Externa enheter: DAC

En digital till analog omvandlare (DAC) tar en diskret signal och omvandlar den till en kontinuerlig signal. Vår DAC har fyra bitar och är gjord av en summeringsförstärkare. Genom att använda ett förhållande av motstånd i matnings- och återkopplingsslingan kunde vi skapa ett system som matar ut på 16 olika nivåer som skapas genom "summering" av varje gren. Bit0, den övre grenen, bär minst vikt och bidrar med minsta potential när den är hög på grund av det förgrenar högre motstånd. Vikten ökar när du går nerför grenarna. Om du skulle räkna i binärt uppåt och sedan tillbaka med bitingångarna skulle utspänningarna se ut som en stegvis sinusvåg. Ingången till DAC var ansluten till en av PMOD: erna på kortet för att överföra 4-bitars signalen.

DAC -enheten monterades ursprungligen för en elektroteknik -klass och designades och löddes av oss, inte köpt från en butik. Ovan är en bild av designfilen för att skapa kretskortet.

Steg 17: Externa enheter: Högtalare

Externa enheter: Högtalare
Externa enheter: Högtalare

För det här projektet kommer du inte att vilja köpa ett superfint par högtalare. Som du kan se är ljudet ganska enkelt. Vi gick och köpte en uppsättning datorhögtalare på $ 8 från Best Buy. Allt med hörlursuttag fungerar bra. Monoton fungerar också bra. Du kan till och med använda hörlurar, men du kan blåsa ut dem!

För att ansluta DAC -utgången till högtalarna använde vi bygelkablar och höll sedan utmatningskabeln till spetsen på hörlursuttaget och kabeln för jordning till basen. Vi försökte använda eltejp för att hålla kablarna på plats, men det orsakade mycket störningar. Att testa en annan typ av tejp kan lösa detta problem.

För våra högtalare vände vi dem till den högsta inställningen och fick ett hyfsat högt ljud.

Och det är det sista steget för att skapa en digital sequencer från ett FPGA -kort! Gå till de kommande två sektionerna för att ladda ner alla våra VHDL -koder och se sequencer i aktion.

Steg 18: Videodemo

Den här videon visar den slutliga versionen av arbetsprojektet, inklusive processen för att tilldela omkopplarna till 4 olika platser, och högtalarna som spelar respektive noter.

Steg 19: VHDL -kod

Här är koden för hela projektet, inklusive begränsningar och simfiler som används när du bygger sequencer. Observera att oanvända designfiler säger så i arkitekturen.

Rekommenderad: