Obsah:

Digitálny zvukový syntetizátor Basys3 FPGA: 5 krokov
Digitálny zvukový syntetizátor Basys3 FPGA: 5 krokov

Video: Digitálny zvukový syntetizátor Basys3 FPGA: 5 krokov

Video: Digitálny zvukový syntetizátor Basys3 FPGA: 5 krokov
Video: Roland FP-E50 Digital Piano with Roland Cloud Expansion Overview 2024, Júl
Anonim
Image
Image
Digitálny syntetizátor zvuku Basys3 FPGA
Digitálny syntetizátor zvuku Basys3 FPGA
Digitálny zvukový syntetizátor Basys3 FPGA
Digitálny zvukový syntetizátor Basys3 FPGA

Tento digitálny sínusový klávesový syntetizátor bude preberať užívateľské vstupy prostredníctvom série okamžitých prepínačov rozložených ako klávesnica a reprodukovať zvukovú vlnu cez reproduktor. Na základe vstupov používateľa zariadenie vygeneruje sínusové vlny rôznych frekvencií od C4 do C6. Užívateľ môže zadávať noty od C4 do C6 (celkom 25 tónov) a až štyri klávesy súčasne - ak stlačíte viac ako štyri klávesy, zaznejú štyri najnižšie tóny.

Tento projekt urobili Ryan Morris a Mavis Tsoi pre našu triedu digitálneho dizajnu Cal Poly CPE 133:)

Krok 1: Teória

Doska FPGA môže vydávať iba digitálne signály. Inými slovami, môže produkovať iba vysoké (3,3 V) napätie alebo nízke (0 V) napätie. Zvukové signály sú však analógové a môžu mať nekonečne veľa prírastkov napätia. Aby sme to obišli, použijeme na emuláciu analógovej vlny signál PWM (modulácia šírky impulzov). Ak neviete, čo je to PWM, pozrite sa na toto:

Krok 2: Prísady a nástroje

  • Počítač s nainštalovaným Vivado
  • Budeme používať Vivado verzie 2017.2
  • Doska FPGA Basys3
  • 25 koncových spínačov SPDT (použili sme ich)
  • 30 prepojovacích káblov (jeden koniec samec, druhý koniec nezáleží), 12 palcov
  • Strihač káblov
  • Odizolovače drôtov
  • Náhradný drôt na spájkovanie
  • Spájka so živicovým jadrom
  • Spájkovačka
  • ¼”ženský zvukový konektor
  • Zosilňovač/reproduktor
  • Niečo na montáž spínačov (použili sme protoboard + drevenú skrinku)

Krok 3: Zapojenie a nastavenie hardvéru

Inštalácia káblov a hardvéru
Inštalácia káblov a hardvéru
Inštalácia káblov a hardvéru
Inštalácia káblov a hardvéru
Inštalácia káblov a hardvéru
Inštalácia káblov a hardvéru

Architektúra systému

Pozrite si obrázok 1: 25 dostupných vstupov → doska Basys3 → zosilňovač a reproduktor.

Výkon

Pozrite si obrázok 2: Doska Basys3 → 1/2 ženský zvukový konektor → reproduktor (so zosilňovačom)

Vstup

Pripojenia pmod na doske Basys3 musia byť pripojené k zemi, aby bol viditeľný nízky vstup, a nebudú správne fungovať, ak budú ponechané ako otvorený obvod. Z tohto dôvodu musíme pre všetky naše klávesy poznámok používať prepínače SPDT. Prepínač SPDT v zásade umožňuje používateľovi prepínať medzi obvodmi po stlačení, takže ich použijeme ako „tlačidlá“na vstup nízkych (0 V) alebo vysokých (3,3 V) signálov na dosku Basys3.

Každý prepínač bude mať svorku NO (normálne otvorený) pripojený na 3,3 V, svorku NC (normálne zatvorenú) pripojenú na GND a svorku COM (spoločnú) pripojenú na vstup FPGA. Pozri obrázok 3.

Pretože máme 25 koncových spínačov, všetky budú zdieľať spoločné 3,3 V vedenie a spoločné GND vedenie. Potom bude signálna linka z každého koncového spínača zoskupená do skupín po 8 a prepojená s konektormi pmod na doske Basys3 pomocou prepojovacích káblov na zapínanie na zips, aby sa minimalizoval monumentálny neporiadok, ktorý urobíme. Pozrite si obrázok 4 alebo príklad prvých ôsmich klávesov.

Krok 4: Nastavenie VHDL (Vivado)

Nastavenie VHDL (Vivado)
Nastavenie VHDL (Vivado)
Nastavenie VHDL (Vivado)
Nastavenie VHDL (Vivado)

Generátor sínusových vĺn a generátor PWM boli najskôr testované, aby sa ubezpečil, že náš koncept funguje, a potom boli integrované obmedzovač vstupu a sčítač/prepínač amplitúdy. Podrobnosti o funkcii a I/O každého bloku procesu sú uvedené na obrázku. Kód je zobrazený nižšie, ale je tiež priložený ako súbory VHD a txt. Ak existujú nezrovnalosti, pokračujte so súbormi VHD.

BTW: Pravdepodobne sme mali skrátiť naše riadky, ale vkladanie kódu do Instructables sa tiež ukázalo ako dosť nepríjemné pri riešení, takže medzery nie sú najväčšie a nie je potrebné zvýrazňovať syntax. Ak máte Vivado a chceli by ste sa riadiť kódom, dôrazne vám odporúčame súbor si jednoducho stiahnuť.

Najprv sa pozrime na modul Sine Wave Generator.

knižnica IEEE; použite IEEE. STD_LOGIC_1164. ALL; použite IEEE. NUMERIC_STD. ALL; entita Wave_Generator je port (spúšťač: v STD_LOGIC; - stlačenie klávesu Freq_Cnt: v STD_LOGIC_VECTOR (15 až 0); - hodnota počítadla = 100 MHz / (poznámka Frekvencia*64 divízií sínusovej vlny) (zaokrúhlené na najbližšie číslo) - premenované z Freq wavegenCLK: v STD_LOGIC; - Basys3 100MHz CLK WaveOut: out STD_LOGIC_VECTOR (9 až 0)); - Podpísaná amplitúda konca vlny Wave_Generator; architektúra Behavioral of Wave_Generator is signal i: integer range 0 to 64: = 0; -index typu banky pamäte amplitúdy typ pamäťový_typ je pole (0 až 63) s celočíselným rozsahom -64 až 63; - vytvoriť pamäťovú banku (ROM) na uchovávanie hodnôt amplitúdy- zaujíma sa táto pamäť RAM alebo ROM … amplitúda signálu: typ pamäte: = (0, 7, 13, 19, 25, 30, 35, 40, 45, 49, 52, 55, 58, 60, 62, 63, 63, 63, 62, 60, 58, 55, 52, 49, 45, 40, 35, 30, 25, 19, 13, 7, 0, -7, -13, -19, -25, -30, -35, -40, -45, -49, -52, -55, -58, -60, -62, -63, -63, -63, -62, - 60, -58, -55, -52, -49, -45, -40, -35, -30, -25, -19, -13, -7); - banka amplitúdovej pamäte pre proces začiatku sínusovej vlny (wavegenCLK, Trigger) variabilné počítadlo: bez znamienka (15 až 0): = to_unsigned (0, 16); - počítadlo deliča hodín, premenované z count1 begin if (rise_edge (wavegenCLK)) then if (Trigger = '1') then- key isPress counter counter: = counter + 1; if (counter = unsigned (Freq_Cnt)) then - Freq_Cnt = 100Mhz / (note freq * 64 delitions of the sine wave) - vynulovanie počítadla a priradenie dát amplitúdy výstupnému počítadlu: = to_unsigned (0, 16); WaveOut <= STD_LOGIC_VECTOR (to_signed (amplitúda (i), 10)); - prírastok i pre ďalšie čítanie i <= i + 1; - resetujte i, ak bola dokončená jedna sínusová vlna, ak (i = 63) potom i <= 0; koniec Ak; koniec Ak; - (počítadlo = bez znamienka (Freq_Cnt)) else- kláves nie je stlačený- reset výstupu, indexu amplitúdy a počítadla WaveOut <= "0000000000"; i <= 0; počítadlo: = to_unsigned (0, 16); -výstupná amplitúda = -64, keď sa nehrá žiadna nota, koniec, ak; - (Spúšťač = '1') koniec, ak; - (rise_edge (CLK)) koncový proces; koniec Behaviorálne;

V Basys3 vygenerujeme digitálnu sínusovú vlnu pomocou vnútorných hodín a pamäte ROM. Táto ROM bude ukladať 64 hodnôt, ktoré predstavujú 64 amplitúd na sínusovej vlne. Pozri obrázok 1. 64 hodnôt, ktoré používame, napodobňuje sínusovú vlnu s celkom dobrým rozlíšením.

Použitím vnútorných hodín počítame do hodnoty, ktorá predstavuje rýchlosť hodín delenú frekvenciou požadovanej vlny a 64: Clk div = 100MHz / (Freq * 64) Zakaždým, keď náš čítač dosiahne túto hodnotu, zavoláme číslo z ROM a pošlite ho z nášho modulu generátora vĺn. Frekvencia našej vlny bude závisieť od toho, ako rýchlo tieto amplitúdy nazývame.

Budeme mať 25 čiastkových modulov, z ktorých každý bude spojený s jednou frekvenciou/poznámkou.

Tu je zostávajúci kód, ktorý volá moduly generátora sinusových vĺn:

knižnica IEEE; použite IEEE. STD_LOGIC_1164. ALL; použite IEEE. NUMERIC_STD. ALL; entita Two_Octave_Synth je port (CLK: v STD_LOGIC; O4: v STD_LOGIC_VECTOR (11 až 0); O5: v STD_LOGIC_VECTOR (12 až 0); výstup: mimo STD_LOGIC); koniec Two_Octave_Synth; architektúra Behavioral of Two_Octave_Synth je komponent Wave_Generator je Port (Trigger: in STD_LOGIC; Freq_Cnt: in STD_LOGIC_VECTOR (15 downto 0); wavegenCLK: in STD_LOGIC; WaveOut: out STD_LOGIC_VECTOR (9 downto 0)); koncová zložka; --------------------------- výstupné signály z generátora vĺn ------------------ ----- signál WaveC4, WaveCs4, WaveD4, WaveDs4, WaveE4, WaveF4, WaveFs4, WaveG4, WaveGs4, WaveA4, WaveAs4, WaveB4, WaveC5, WaveCs5, WaveD5, WaveDs5, WaveE5, WaveE5, WaveE5, WaveE5 WaveAs5, WaveB5, WaveC6: podpísané (9 až 0); -------------------------------- pre logiku výberu noty -------------- ------ signál C4, Cs4, D4, Ds4, E4, F4, Fs4, G4, Gs4, A4, As4, B4, C5, Cs5, D5, Ds5, E5, F5, Fs5, G5, Gs5, A5, As5, B5, C6: bez znamienka (4 až 0); signál cntC4, cntCs4, cntD4, cntDs4, cntA5, cntA5: bez znamienka (4 až 0); chyba signálu: STD_LOGIC; ----------------------------------- na pridanie sínusových vĺn ----------- --------------- signál Wave0, Wave1, Wave2, Wave3: podpísané (9 až 0); --signály z výstupného signálu modulu generátora vlny WaveSum: STD_LOGIC_VECTOR (9 až 0); -signál pre súčet sínusových vĺn (kompliment 2 -512 až 511) signál positiveWaveSum: STD_LOGIC_VECTOR (9 až 0); -nepodpísané 0 až 1023, na použitie v generátore PWM ----------------------------------- na generovanie PWM ------------------------------- dĺžka signálu ping: bez znamienka (9 až 0): = bez znamienka (positiveWaveSum); --signál off_length: unsigned (6 downto 0): = to_unsigned (127, 7) -unsigned (WAVE); signál PWM: bez znamienka (9 až 0): = to_signed (0, 10); začať Note_C4: Mapa portu Wave_Generator (Trigger => O4 (0), Freq_Cnt => X "1755", wavegenCLK => CLK, podpísané (WaveOut) => WaveC4); --5973, 261,63 Hz Poznámka_Cs4: Mapa portu Wave_Generator (Spúšťač => O4 (1), Freq_Cnt => X "1606", wavegenCLK => CLK, podpísaný (WaveOut) => WaveCs4);-5638, 277,18 Hz Poznámka_D4: Mapa portu Wave_Generator (Trigger => O4 (2), Freq_Cnt => X "14C9", wavegenCLK => CLK, podpísané (WaveOut) => WaveD4); --5321, 293,66 Hz Poznámka_Ds4: Mapa portu Wave_Generator (Spúšťač => O4 (3), Freq_Cnt => X "139F", wavegenCLK => CLK, podpísaný (WaveOut) => WaveDs4);-5023, 311,13 Hz Poznámka_E4: Mapa portu Wave_Generator (Trigger => O4 (4), Freq_Cnt => X "1285", wavegenCLK => CLK, podpísané (WaveOut) => WaveE4); --4741, 329,63 Hz Poznámka_F4: Mapa portu Wave_Generator (Trigger => O4 (5), Freq_Cnt => X "117B", wavegenCLK => CLK, podpísané (WaveOut) => WaveF4); --4475, 349,23 Hz Note_Fs4: Mapa portu Wave_Generator (Trigger => O4 (6), Freq_Cnt => X "1080", wavegenCLK => CLK, podpísané (WaveOut) => WaveFs4);-4224, 369,99 Hz Note_G4: Mapa portu Wave_Generator (Trigger => O4 (7), Freq_Cnt => X "0F92", wavegenCLK => CLK, podpísané (WaveOut) => WaveG4); --3986, 392,00 Hz Note_Gs4: Mapa portu Wave_Generator (Trigger => O4 (8), Freq_Cnt => X "0EB3", wavegenCLK => CLK, signované (WaveOut) => WaveGs4);-3763, 415,30 Hz Poznámka_A4: Mapa portu Wave_Generator (Trigger => O4 (9), Freq_Cnt => X "0DE0", wavegenCLK => CLK, podpísané (WaveOut) => WaveA4); --3552, 440,00 Hz Poznámka_As4: Mapa portu Wave_Generator (Spúšťač => O4 (10), Freq_Cnt => X "0D18", wavegenCLK => CLK, podpísaný (WaveOut) => WaveAs4);-3352, 466,16 Hz Poznámka_B4: Mapa portu Wave_Generator (Trigger => O4 (11), Freq_Cnt => X "0C5C", wavegenCLK => CLK, podpísané (WaveOut) => WaveB4); --3164, 493,88 Hz -------------------------------------------- ---------------------------------------------------------- --------------------------- Note_C5: Mapa portu Wave_Generator (Trigger => O5 (0), Freq_Cnt => X "0BAB", wavegenCLK => CLK, podpísané (WaveOut) => WaveC5); --2987, 523,25 Hz Poznámka_Cs5: Mapa portu Wave_Generator (Spúšťač => O5 (1), Freq_Cnt => X "0B03", wavegenCLK => CLK, podpísaný (WaveOut) => WaveCs5);-2819, 554,37 Hz Poznámka_D5: Mapa portu Wave_Generator (Trigger => O5 (2), Freq_Cnt => X "0A65", wavegenCLK => CLK, podpísané (WaveOut) => WaveD5); --2661, 587,33 Hz Poznámka_Ds5: Mapa portu Wave_Generator (Spúšťač => O5 (3), Freq_Cnt => X "09D0", wavegenCLK => CLK, podpísaný (WaveOut) => WaveDs5);-2512, 622,25 Hz Poznámka_E5: Mapa portu Wave_Generator (Trigger => O5 (4), Freq_Cnt => X "0943", wavegenCLK => CLK, podpísané (WaveOut) => WaveE5); --2371, 659,25 Hz Poznámka_F5: Mapa portu Wave_Generator (Trigger => O5 (5), Freq_Cnt => X "08Be", wavegenCLK => CLK, signované (WaveOut) => WaveF5); --2238, 698,46 Hz Note_Fs5: Mapa portu Wave_Generator (Trigger => O5 (6), Freq_Cnt => X "0840", wavegenCLK => CLK, signované (WaveOut) => WaveFs5);-2112, 739,99 Hz Note_G5: Mapa portu Wave_Generator (Trigger => O5 (7), Freq_Cnt => X "07CA", wavegenCLK => CLK, podpísané (WaveOut) => WaveG5); --1994, 783,99 Hz Note_Gs5: Mapa portu Wave_Generator (Trigger => O5 (8), Freq_Cnt => X "075A", wavegenCLK => CLK, signované (WaveOut) => WaveGs5);-1882, 830,61 Hz Note_A5: Mapa portu Wave_Generator (Trigger => O5 (9), Freq_Cnt => X "06F0", wavegenCLK => CLK, podpísané (WaveOut) => WaveA5); --1776, 880,00 Hz Poznámka_As5: Mapa portu Wave_Generator (Spúšťač => O5 (10), Freq_Cnt => X "068C", wavegenCLK => CLK, podpísaný (WaveOut) => WaveAs5);-1676, 932,33 Hz Poznámka_B5: Mapa portu Wave_Generator (Trigger => O5 (11), Freq_Cnt => X "062E", wavegenCLK => CLK, podpísané (WaveOut) => WaveB5); --1582, 987,77 Hz Poznámka_C6: Mapa portu Wave_Generator (Trigger => O5 (12), Freq_Cnt => X "05D6", wavegenCLK => CLK, signované (WaveOut) => WaveC6); --1494, 1046,5 Hz ------------ logika výberu noty ------------ C4 <= "0000" & O4 (0); Cs4 <= "0000" & O4 (1); D4 <= "0000" & O4 (2); Ds4 <= "0000" & O4 (3); E4 <= "0000" & O4 (4); F4 <= "0000" & O4 (5); Fs4 <= "0000" & O4 (6); G4 <= "0000" & O4 (7); Gs4 <= "0000" & O4 (8); A4 <= "0000" & O4 (9); As4 <= "0000" & O4 (10); B4 <= "0000" & O4 (11); C5 <= "0000" & O5 (0); Cs5 <= "0000" & O5 (1); D5 <= "0000" & O5 (2); Ds5 <= "0000" & O5 (3); E5 <= "0000" & O5 (4); F5 <= "0000" & O5 (5); Fs5 <= "0000" & O5 (6); G5 <= "0000" & O5 (7); Gs5 <= "0000" & O5 (8); A5 <= "0000" & O5 (9); As5 <= "0000" & O5 (10); B5 <= "0000" & O5 (11); C6 <= "0000" & O5 (12); cntC4 <= C4; cntCs4 <= C4 + Cs4; cntD4 <= C4 + Cs4 + D4; cntDs4 <= C4 + Cs4 + D4 + Ds4; cntE4 <= C4 + Cs4 + D4 + Ds4 + E4; cntF4 <= C4 + Cs4 + D4 + Ds4 + E4 + F4; cntFs4 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4; cntG4 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4; cntGs4 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4; cntA4 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4; cntAs4 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4; cntB4 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4; cntC5 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5; cntCs5 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5 + Cs5; cntD5 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5 + Cs5 + D5; cntDs5 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5 + Cs5 + D5 + Ds5; cntE5 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5 + Cs5 + D5 + Ds5 + E5; cntF5 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5 + Cs5 + D5 + Ds5 + E5 + F5; cntFs5 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5 + Cs5 + D5 + Ds5 + E5 + F5 + Fs5; cntG5 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5 + Cs5 + D5 + Ds5 + E5 + F5 + Fs5 + G5; cntGs5 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5 + Cs5 + D5 + Ds5 + E5 + F5 + Fs5 + G5 + Gs5; cntA5 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5 + Cs5 + D5 + Ds5 + E5 + F5 + Fs5 + G5 + Gs5 + A5; cntAs5 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5 + Cs5 + D5 + Ds5 + E5 + F5 + Fs5 + G5 + Gs5 + A5 + As5; cntB5 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5 + Cs5 + D5 + Ds5 + E5 + F5 + Fs5 + G5 + Gs5 + A5 + As5 + B5; cntC6 <= C4 + Cs4 + D4 + Ds4 + E4 + F4 + Fs4 + G4 + Gs4 + A4 + As4 + B4 + C5 + Cs5 + D5 + Ds5 + E5 + F5 + Fs5 + G5 + Gs5 + A5 + As5 + B5 + C6; Výber: proces (WaveC4, WaveCs4, WaveD4, WaveDs4, WaveE4, WaveF4, WaveFs4, WaveG4, WaveGs4, WaveA4, WaveAs4, WaveB4, WaveC5, WaveCs5, WaveD5, WaveDs5, WaveE5 WaveB5, WaveC6) začať if (cntC6 = "00000") potom --------------- ak nie sú generované žiadne signály Wave0 <= "0000000000"; Vlna1 <= "0000000000"; Vlna2 <= "0000000000"; Wave3 <= "0000000000"; else if (O4 (0) = '1') then ------------------- poznámka C4 hral Wave0 Wave0 Wave1 error Wave0 Wave1 Wave2 error Wave0 Wave1 Wave2 Wave3 error Wave0 Wave1 Wave2 Wave3 error Wave0 Wave1 Wave2 Wave3 error Wave0 Wave1 Wave2 Wave3 error Wave0 Wave1 Wave2 Wave3 error Wave0 Wave1 Wave2 error Wave0 Wave1 Wave2 error3 Wave0 Wave1 Wave2 Wave3 error Wave0 Wave1 Wave2 Wave2 Wave3 error Wave0 Wave1 Wave2 Wave3 error Wave0 Wave1 Wave2 Wave3 error Wave0 Wave1 Wave2 Wave3 error Wave0 Wave1 Wave2 error Wave0 Wave1 Wave2 error3 Wave0 Wave2 Wave2 = WaveC6; Vlna1 <= "0000000000"; Wave2 <= "0000000000"; Wave3 Wave1 <= WaveC6; Vlna2 <= "0000000000"; Wave3 Wave2 <= WaveC6; Wave3 Wave3 error Wave1 <= "0000000000"; Vlna2 <= "0000000000"; Wave3 Wave2 <= "0000000000"; Wave3 Chyba Wave3 <= '1'; koncový prípad; koniec Ak; koniec Ak; konečný proces; ------------- sínusová vlna -------------------- WaveSum <= STD_LOGIC_VECTOR (Wave0 + Wave1 + Wave2 + Wave3); --------- urobte sínusovú vlnu pozitívnou pre pwm --------------------- positiveWaveSum <= nie WaveSum (9) & WaveSum (8 až 0); ------------- Generátor PWM --------------------- proces (CLK)-premenlivý počet: bez znamienka (1 až 0): = to_unsigned (0, 2); begin if (rise_edge (CLK)) then --count: = count + 1; --if (count = to_unsigned (4, 2)) then --count: = to_unsigned (0, 2); -ak (PWM = to_ if (PWM <dĺžka ping) potom výstup <= '1'; inak výstup <= '0'; koniec ak; PWM <= PWM + 1; dĺžka pingu <= bez znamienka (positiveWaveSum); --end ak; ukončiť ak; ukončiť proces; ukončiť behaviorálne;

4 Selector SelectorNajťažšia časť tohto projektu je výber iba štyroch frekvencií. Urobili sme to pomocou príkazov IF lotta lotta a namiesto premenných sme použili signály, aby bolo možné proces simulovať a ladiť. Vyskúšali sme iné metódy pomocou premenných a slučiek FOR, ale narazili sme na chyby pri spustení. Nakoniec sme sa rozhodli, že ak to bude fungovať, necháme to tak. Nespravíte, čo nie je zlomený amirit?

Štyri výstupné vlny sú označené Wave0, Wave1, Wave2, Wave3 - to sú položky, ktoré sa spoja a vytvoria konečný výstup.

Pri pohľade na kód uvidíte veľa signálov označených C4, Cs4, D4, Ds4 atď. Jedná sa o 5-bitové signály, ktoré preberajú zodpovedajúci spúšťač z O4 (oktáva 4) alebo O5 (oktáva 5) a vytvoria ich. 5-bitový na pridanie.

Ďalej premenné cntC4, cntCs4 atď. Predstavujú, koľko tónov nižších ako cieľová nota bolo odohraných, vrátane cieľovej noty. Napríklad, ak sa hrajú C4, E4, G4, A#4 a D5 (akord C9), cntC4 bude 1, cntE4 bude 2, cntG4 bude 3 atď.

Potom, kedykoľvek zaznie nota, sa preskúma počet cieľových tónov, aby sa zistilo, kam je potrebné pripojiť signál tónu. Ak napríklad hráte notu D5 (čo znamená, že O5 (2) je vysoká) a cntD5 je 3, potom sa práve hrajú 3 tóny, pričom 2 tóny sú nižšie ako D5, takže pripojíme waveD5 k Wave2 (tretia vlna) počítanie signálu z Wave0). Alternatívne, ak je cntD5 5, tak sa v súčasnosti hrá 5 nôt, pričom o 4 tóny je menej ako D5, takže waveD5 necháme visieť a nič s tým neurobíme.

Výkazy IF sa potom opakujú, aby sa pokryli prípady pre všetkých 25 poznámok.

Zosilňovač amplitúdy

Potom, čo sú vybraté najnižšie 4 vlny, ich musíme sčítať. Dôvod, prečo spolu pridáme iba štyri poznámky, je ten, že myšlienka PWM, ktorú používame na výstup, môže mať iba určité rozlíšenie, kým PWM beží príliš pomaly a reproduktor nezačne zachytávať štvorcovú vlnu PWM. Ak by sme napríklad použili rozlíšenie 8192 (13 bitov), každý z týchto 8192 bodov musí zodpovedať stúpajúcej hrane palubných hodín. 100 MHz / 8192 = 12,2 kHz, čo je v rozsahu ľudského sluchu.

Skutočné sčítanie amplitúd je veľmi jednoduché, stačí sa uistiť, že môže bežať skutočne rýchlo.

PWM výstup

Pracovný cyklus PWM bude v tomto okamihu predstavovať amplitúdu našej výstupnej vlny. Napríklad, ak máme rozsah amplitúdy 0 až 128, 0 by bol 0%pracovný cyklus, 64 by bolo 50%, 128 by bolo 100%atď. Tento PWM pobeží extrémne rýchlo (náš je 97,6 kHz), tak rýchlo, že reproduktor nerozpozná jednotlivé štvorcové vlny a namiesto toho sa pozerá na priemerné napätie, čím vytvára náš „analógový“signál.

Súbor obmedzení

Možno ste zapojili svoj hardvér inak, takže sa uistite, že sa súbor obmedzení zhoduje.

Krok 5: Sťahovanie kódu

Nasleduje kód vo formáte.txt aj.vhd pre Vivado. Wave_Generator je podmodul generátora vĺn a Two_Octave_Synth je najlepší modul so všetkým ostatným.

Odporúča: