Tartalomjegyzék:

Basys3 FPGA digitális hangszintetizátor: 5 lépés
Basys3 FPGA digitális hangszintetizátor: 5 lépés

Videó: Basys3 FPGA digitális hangszintetizátor: 5 lépés

Videó: Basys3 FPGA digitális hangszintetizátor: 5 lépés
Videó: Knight Rider - Basys 2 rulez! 2024, Július
Anonim
Image
Image
Basys3 FPGA digitális hangszintetizátor
Basys3 FPGA digitális hangszintetizátor
Basys3 FPGA digitális hangszintetizátor
Basys3 FPGA digitális hangszintetizátor

Ez a digitális szinuszhullámú billentyűzet -szintetizátor a felhasználói bemeneteket egy sor pillanatnyi kapcsolón keresztül veszi fel, mint egy billentyűzet, és egy hanghullámot ad ki egy hangszórón keresztül. A felhasználói adatok alapján a készülék különböző frekvenciájú szinuszhullámokat generál C4 -től C6 -ig. A felhasználó C4 -től C6 -ig (összesen 25 hangjegy) és egyszerre négy billentyűt írhat be - ha négynél több gombot nyom meg, akkor a négy legalacsonyabb hang szólal meg.

Ezt a projektet Ryan Morris és Mavis Tsoi készítette a Cal Poly CPE 133 Digital Design osztályunk számára:)

1. lépés: Elmélet

Az FPGA kártya csak digitális jeleket képes kiadni. Más szóval, csak magas (3,3 V) vagy alacsony (0 V) feszültséget tud előállítani. Az audio jelek azonban analógok, és végtelen sok feszültségfokozattal rendelkezhetnek. Ennek kiküszöbölésére PWM (impulzus szélesség moduláció) jelet használunk az analóg hullám emulálására. Ha nem tudja, mi az a PWM, akkor nézze meg ezt:

2. lépés: Hozzávalók és eszközök

  • Számítógép telepítve Vivadóval
  • A Vivado 2017.2 verzióját fogjuk használni
  • Basys3 FPGA kártya
  • 25 SPDT végálláskapcsoló (ezeket használtuk)
  • 30 áthidaló vezeték (egyik végük dugó, másik végük mindegy), 12 hüvelyk
  • Drótvágók
  • Huzalhúzók
  • Tartalék huzal forrasztáshoz
  • Gyantamagos forrasztó
  • Forrasztópáka
  • ¼”női audio jack
  • Erősítő/hangszóró
  • Valami, amire fel lehet szerelni a kapcsolókat (protoboard + fadobozt használtunk)

3. lépés: Vezetékek és hardver beállítása

Vezetékek és hardver beállítása
Vezetékek és hardver beállítása
Vezetékek és hardver beállítása
Vezetékek és hardver beállítása
Vezetékek és hardver beállítása
Vezetékek és hardver beállítása

Rendszer Felépítés

Lásd az 1. ábrát: 25 rendelkezésre álló bemenet → Basys3 Board → erősítő és hangszóró.

Kimenet

Lásd 2. ábra: Basys3 tábla → 1/2 hüvelykes női audiocsatlakozó → Hangszóró (erősítővel)

Bemenet

A Basys3 kártyán található pmod csatlakozásokat földhöz kell csatlakoztatni, hogy alacsony bemenetet láthassanak, és nem működnek megfelelően, ha nyitott áramkörként hagyják. Emiatt minden jegyzetkulcsunkhoz SPDT kapcsolókat kell használnunk. Az SPDT kapcsoló alapvetően lehetővé teszi a felhasználó számára az áramkörök közötti váltást, amikor megnyomja őket, ezért azokat „gombjainkként” használjuk alacsony (0V) vagy magas (3,3V) jelek bevitelére a Basys3 kártyára.

Minden kapcsolóhoz az NO (normál nyitott) csatlakozó 3.3V -ra, az NC (normál esetben zárt) csatlakozója a GND -hez, a COM (közös) csatlakozó pedig az FPGA bemenethez lesz csatlakoztatva. Lásd a 3. ábrát.

Mivel 25 végálláskapcsolónk van, mindegyikük közös 3.3V -os és közös GND -vonalat fog használni. Ezután az egyes végálláskapcsolók jelvezetékét 8 fős csoportokba gyűjtik, és összekapcsolják a Basod3 tábla pmod csatlakozóival, cipzáras áthidaló vezetékekkel, hogy minimalizálják az általunk okozott monumentális rendetlenséget. Lásd a 4. ábrát vagy egy példát az első nyolc billentyűre.

4. lépés: VHDL beállítás (Vivado)

VHDL beállítás (Vivado)
VHDL beállítás (Vivado)
VHDL beállítás (Vivado)
VHDL beállítás (Vivado)

A szinuszhullám -generátort és a PWM -generátort először teszteltük, hogy megbizonyosodjunk arról, hogy működik -e a koncepciónk, majd integrálták a bemeneti korlátozót és az amplitúdó -összeadót/-váltót. Az egyes folyamatblokkok funkciójának és I/O -jának részletei az ábrán láthatók. A kód alább látható, de VHD és txt fájlként is csatolva van. Ha eltérések vannak, menjen a VHD fájlokhoz.

BTW: Valószínűleg le kellett volna rövidítenünk a sorainkat, de az Instructables -be történő kódbeágyazás is elég bosszantónak bizonyult, így a távolság nem a legnagyobb, és nincs szintaktikai kiemelés. Ha rendelkezik Vivadóval, és szeretné követni a kódot, erősen javasoljuk, hogy csak töltse le a fájlt.

Először nézzük a szinuszhullám -generátor modult.

könyvtár IEEE; használja az IEEE. STD_LOGIC_1164. ALL; használja az IEEE. NUMERIC_STD. ALL; entitás Wave_Generator a Port (Trigger: az STD_LOGIC -ban; - Nyomja meg a Freq_Cnt -t: a STD_LOGIC_VECTOR -ban (15 -től 0 -ig); - Számlálóérték = 100 MHz / (Megjegyzés Frekvencia*64 szinuszhullám -osztás) (kerek a legközelebbi számig) - átnevezve a Freq wavegenCLK -tól: az STD_LOGIC -ban; - Basys3 100 MHz -es CLK WaveOut: ki STD_LOGIC_VECTOR (9 -től 0 -ig)); - A hullámvég Wave_Generator előjeles amplitúdója; architektúra A Wave_Generator viselkedése az i jel: 0 és 64 közötti egész tartomány: = 0; -az amplitúdó memória bank típusa index memória_típus a -64 és 63 közötti egész tartomány tömbje (0-63); - memóriabank (ROM) létrehozása az amplitúdó értékek tárolására- ez a RAM vagy ROM csak kíváncsi… jel amplitúdója: memória_típus: = (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); - amplitúdó memóriabank a szinuszhullám-indítási folyamathoz (wavegenCLK, Trigger) változószámláló: unsigned (15-től 0-ig): = to_unsigned (0, 16); - óraosztó számláló, a count1-ből átnevezve kezdődik, ha (emelkedő_szél (wavegenCLK)), majd ha (Trigger = '1'), akkor- gomb megnyomása számláló: = számláló + 1; ha (számláló = előjel nélküli (Freq_Cnt)) akkor - Freq_Cnt = 100Mhz / (jegyezze fel a frekvenciát * a szinuszhullám 64 osztása) - állítsa vissza a számlálót, és rendeljen amplitúdó adatokat a kimeneti számlálóhoz: = to_unigned (0, 16); WaveOut <= STD_LOGIC_VECTOR (to_signed (amplitúdó (i), 10)); - növekmény i a következő olvasáshoz i <= i + 1; - nullázza az i-t, ha egy szinuszhullám befejeződött, ha (i = 63), akkor i <= 0; fejezze be, ha; fejezze be, ha; - (számláló = előjel nélküli (Freq_Cnt)) else- nincs megnyomva- a kimenet, az amplitúdó index és a számláló WaveOut visszaállítása <= "0000000000"; i <= 0; számláló: = aláírás nélküli (0, 16); -kimeneti amplitúdó = -64, ha nincs hang, akkor vége, ha; - (Trigger = '1') vége, ha; - (emelkedő szélű (CLK)) befejezési folyamat; vége Viselkedés;

A belső óra és a ROM segítségével digitális szinuszhullámot generálunk a Basys3 -ban. Ez a ROM 64 értéket tárol, amelyek a szinuszhullámon 64 amplitúdót képviselnek. Lásd az 1. ábrát. Az általunk használt 64 érték szinuszhullámot emulál, elég jó felbontással.

A belső óra használatával olyan értékre számolunk, amely az órajel sebességét osztja a kívánt hullám frekvenciájával és 64: Clk div = 100MHz / (Freq * 64) Minden alkalommal, amikor számlálónk eléri ezt az értéket, hívunk egy számot a a ROM -ot, és küldje el a hullámgenerátor modulunkból. Hullámunk frekvenciája attól függ, hogy milyen gyorsan nevezzük ezeket az amplitúdókat.

25 almodulunk lesz, mindegyikhez egy frekvencia/hang.

Itt található a Sine Wave Generator modulokat hívó kód fennmaradó része:

könyvtár IEEE; használja az IEEE. STD_LOGIC_1164. ALL; használja az IEEE. NUMERIC_STD. ALL; entitás Two_Octave_Synth a port (CLK: STD_LOGIC -ban; O4: STD_LOGIC_VECTOR -ban (11 -től 0 -ig); O5: STD_LOGIC_VECTOR -ban (12 -től 0 -ig); output: out STD_LOGIC); end Two_Octave_Synth; architektúra A Two_Octave_Synth viselkedése összetevő Wave_Generator port (Trigger: STD_LOGIC -ban; Freq_Cnt: STD_LOGIC_VECTOR -ban (15 -től 0 -ig); wavegenCLK: STD_LOGIC -ban; WaveOut: out STD_LOGIC_VECTOR (9 -től 0 -ig)); végkomponens; --------------------------- kimeneti jelek a hullámgenerátorból ------------------ ----- jel WaveC4, WaveCs4, WaveD4, WaveDs4, WaveE4, WaveF4, WaveFs4, WaveG4, WaveGs4, WaveA4, WaveAs4, WaveB4, WaveC5, WaveCs5, WaveD5, WaveDs5, WaveE5, WaveE5, WaveE5, WaveE5 WaveAs5, WaveB5, WaveC6: aláírt (9 -től 0 -ig); -------------------------------- a jegyzetválasztási logikához -------------- ------ jel 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: előjel nélküli (4 -től 0 -ig); jel cntC4, cntCs4, cntD4, cntDs4, cntE4, cntF4, cntFs4, cntG4, cntGs4, cntA4, cntAs4, cntB4, cntC5, cntCs5, cntD5, cntDs5, cntE5, cntCs5, cntC5, cntC5: előjel nélküli (4 -től 0 -ig); jel hiba: STD_LOGIC; ----------------------------------- szinuszhullámok hozzáadásához ----------- --------------- jel Wave0, Wave1, Wave2, Wave3: aláírt (9-től 0-ig); -jelek a Wave Generator modul WaveSum kimeneti jelétől: STD_LOGIC_VECTOR (9-től 0-ig); -jel az összesített szinuszhullámokra (2 bókja -512-511) pozitív WaveSum: STD_LOGIC_VECTOR (9 -től 0 -ig); -0-1023-ig, PWM generátorban való használatra ----------------------------------- PWM generálására ------------------------------- jel ping_length: unsigned (9-től 0-ig): = unsigned (pozitívWaveSum); -jel ki_hossza: előjel nélküli (6 -tól 0 -ig): = aláírás nélküli (127, 7) -előjel nélküli (WAVE); jel PWM: unsigned (9 to 0): = to_unsigned (0, 10); start Note_C4: Wave_Generator port map (Trigger => O4 (0), Freq_Cnt => X "1755", wavegenCLK => CLK, aláírt (WaveOut) => WaveC4); --5973, 261,63 Hz Megjegyzés_Cs4: Wave_Generator porttérkép (Trigger => O4 (1), Freq_Cnt => X "1606", wavegenCLK => CLK, aláírt (WaveOut) => WaveCs4);-5638, 277,18 Hz Note_D4: Wave_Generator porttérkép (Trigger => O4 (2), Freq_Cnt => X "14C9", wavegenCLK => CLK, aláírt (WaveOut) => WaveD4); --5321, 293,66 Hz Megjegyzés_Ds4: Wave_Generator porttérkép (Trigger => O4 (3), Freq_Cnt => X "139F", wavegenCLK => CLK, aláírt (WaveOut) => WaveDs4);-5023, 311,13 Hz Note_E4: Wave_Generator porttérkép (Trigger => O4 (4), Freq_Cnt => X "1285", wavegenCLK => CLK, aláírt (WaveOut) => WaveE4); --4741, 329,63 Hz Megjegyzés_F4: Hullám_generátor porttérkép (Trigger => O4 (5), Freq_Cnt => X "117B", wavegenCLK => CLK, aláírt (WaveOut) => WaveF4); --4475, 349,23 Hz Megjegyzés_Fs4: Wave_Generator porttérkép (Trigger => O4 (6), Freq_Cnt => X "1080", wavegenCLK => CLK, aláírt (WaveOut) => WaveFs4);-4224, 369,99 Hz Note_G4: Wave_Generator porttérkép (Trigger => O4 (7), Freq_Cnt => X "0F92", wavegenCLK => CLK, aláírt (WaveOut) => WaveG4); --3986, 392,00 Hz Note_Gs4: Wave_Generator port map (Trigger => O4 (8), Freq_Cnt => X "0EB3", wavegenCLK => CLK, signated (WaveOut) => WaveGs4);-3763, 415,30 Hz Note_A4: Wave_Generator porttérkép (Trigger => O4 (9), Freq_Cnt => X "0DE0", wavegenCLK => CLK, aláírt (WaveOut) => WaveA4); --3552, 440,00 Hz Note_As4: Wave_Generator port map (Trigger => O4 (10), Freq_Cnt => X "0D18", wavegenCLK => CLK, signated (WaveOut) => WaveAs4);-3352, 466,16 Hz Note_B4: Wave_Generator port map (Trigger => O4 (11), Freq_Cnt => X "0C5C", wavegenCLK => CLK, aláírt (WaveOut) => WaveB4); --3164, 493,88 Hz -------------------------------------------- -------------------------------------------------- --------------------------- Note_C5: Wave_Generator port map (Trigger => O5 (0), Freq_Cnt => X "0BAB", wavegenCLK => CLK, aláírt (WaveOut) => WaveC5); --2987, 523,25 Hz Megjegyzés_Cs5: Wave_Generator porttérkép (Trigger => O5 (1), Freq_Cnt => X "0B03", wavegenCLK => CLK, aláírt (WaveOut) => WaveCs5);-2819, 554,37 Hz Note_D5: Wave_Generator port map (Trigger => O5 (2), Freq_Cnt => X "0A65", wavegenCLK => CLK, aláírt (WaveOut) => WaveD5); --2661, 587,33 Hz Megjegyzés_Ds5: Wave_Generator porttérkép (Trigger => O5 (3), Freq_Cnt => X "09D0", wavegenCLK => CLK, aláírt (WaveOut) => WaveDs5);-2512, 622,25 Hz Note_E5: Wave_Generator porttérkép (Trigger => O5 (4), Freq_Cnt => X "0943", wavegenCLK => CLK, aláírt (WaveOut) => WaveE5); --2371, 659,25 Hz Megjegyzés_F5: Hullám_generátor porttérkép (Trigger => O5 (5), Freq_Cnt => X "08Be", wavegenCLK => CLK, aláírt (WaveOut) => WaveF5); --2238, 698,46 Hz Megjegyzés_Fs5: Hullám_generátor porttérkép (Trigger => O5 (6), Freq_Cnt => X "0840", wavegenCLK => CLK, aláírt (WaveOut) => WaveFs5);-2112, 739,99 Hz Note_G5: Wave_Generator porttérkép (Trigger => O5 (7), Freq_Cnt => X "07CA", wavegenCLK => CLK, aláírt (WaveOut) => WaveG5); --1994, 783,99 Hz Note_Gs5: Wave_Generator port map (Trigger => O5 (8), Freq_Cnt => X "075A", wavegenCLK => CLK, signated (WaveOut) => WaveGs5);-1882, 830.61 Hz Note_A5: Wave_Generator porttérkép (Trigger => O5 (9), Freq_Cnt => X "06F0", wavegenCLK => CLK, aláírt (WaveOut) => WaveA5); --1776, 880,00 Hz Note_As5: Wave_Generator port map (Trigger => O5 (10), Freq_Cnt => X "068C", wavegenCLK => CLK, signated (WaveOut) => WaveAs5);-1676, 932,33 Hz Note_B5: Wave_Generator port map (Trigger => O5 (11), Freq_Cnt => X "062E", wavegenCLK => CLK, aláírt (WaveOut) => WaveB5); --1582, 987,77 Hz Megjegyzés_C6: Hullám_generátor porttérkép (Trigger => O5 (12), Freq_Cnt => X "05D6", wavegenCLK => CLK, aláírt (WaveOut) => WaveC6); --1494, 1046,5 Hz ------------ jegyzetválasztási logika ------------ 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; Kiválasztás: folyamat (WaveC4, WaveCs4, WaveD4, WaveDs4, WaveE4, WaveF4, WaveFs4, WaveG4, WaveGs4, WaveA4, WaveAs4, WaveB4, WaveC5, WaveCs5, WaveD5, WaveDs5, WaveG5, Wave5 WaveB5, WaveC6) akkor kezdődik, ha (cntC6 = "00000"), majd --------------- ha nem generál jeleket Wave0 <= "0000000000"; Hullám1 <= "0000000000"; Hullám2 <= "0000000000"; Hullám3 <= "0000000000"; egyébként ha (O4 (0) = '1') akkor ------------------- megjegyzés C4 játszott Wave0 Wave0 Wave1 hiba Wave0 Wave1 Wave2 hiba Wave0 Wave1 Wave2 Wave3 hiba Wave0 Wave1 Wave2 Wave3 hiba Wave0 Wave1 Wave2 Wave3 hiba Wave0 Wave1 Wave2 Wave3 hiba Wave0 Wave1 Wave2 Wave3 hiba Wave0 Wave1 Wave2 Wave3 hiba Wave0 Wave1 Wave2 Wave3 Wave1 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Hullám2 Hullám3 hiba = WaveC6; Hullám1 <= "0000000000"; Hullám2 <= "0000000000"; Hullám3 Hullám1 <= HullámC6; Hullám2 <= "0000000000"; Hullám3 Hullám2 <= HullámC6; Wave3 Wave3 hiba Wave1 <= "0000000000"; Hullám2 <= "0000000000"; Hullám3 Hullám2 <= "0000000000"; Hullám3 Hullám3 hiba <= '1'; vég tok; fejezze be, ha; fejezze be, ha; folyamat befejezése; ------------- szinuszhullám összeadó -------------------- Hullámösszeg <= STD_LOGIC_VECTOR (Hullám0 + Hullám1 + Hullám2 + Hullám3); --------- pozitív szinuszhullám beállítása pwm esetén --------------------- pozitívWaveSum <= nem WaveSum (9) & WaveSum (8 to 0); ------------- PWM generátor --------------------- folyamat (CLK)-változószám: előjel nélküli (1-től 0-ig)): = aláírás nélküli (0, 2); kezdődik, ha (emelkedő szél (CLK)), majd -szám: = szám + 1; --if (szám = alá nem írtak (4, 2)), majd-szám: = alá nem írtak (0, 2); --if (PWM = to_ if (PWM <ping_length), akkor kimenet <= '1'; else output <= '0'; end if; PWM <= PWM + 1; ping_length <= unsigned (pozitívWaveSum); --end ha; vége ha, befejezi a folyamatot, befejezi a viselkedést;

4 Megjegyzésválasztó A projekt legbonyolultabb része mindössze négy frekvencia kiválasztása. Csináltunk egy csomó IF utasítást, és jeleket használtunk a változók helyett, hogy a folyamat szimulálható és hibakereshető legyen. Más módszereket is kipróbáltunk változók és FOR ciklusok használatával, de futási hibákba ütközünk. Így végül úgy döntöttünk, hogy ha működik, akkor hagyjuk békén. Ne javítsa ki azt, ami nem törött amirit?

A négy kimeneti hullám Wave0, Wave1, Wave2, Wave3 felirattal van ellátva - ezeket összeadjuk a végső kimenethez.

A kódot nézve egy csomó C4, Cs4, D4, Ds4 feliratú jel látható. Ezek 5 bites jelek, amelyek az O4 (4. oktáv) vagy az O5 (5. oktáv) megfelelő kiváltó jelet vesznek 5 bites hozzáadáshoz.

Ezután a cntC4, cntCs4 stb. Változók jelzik, hogy a célhangnál hány hangot játszottak le, beleértve a célhangot is. Például, ha C4, E4, G4, A#4 és D5 szólal meg (C9 akkord), cntC4 1, cntE4 2, cntG4 3 stb.

Ezután, amikor egy hangot eljátsszanak, a céljegy hangját megvizsgálják, hogy lássák, hová kössék a hangjelzést. Például, ha D5 hangot játszik le (ami azt jelenti, hogy az O5 (2) magas), és a cntD5 3, akkor jelenleg 3 hangot játszik le, 2 hangjelrel alacsonyabban, mint a D5, így a D5 hullámot a Wave2 -hez kapcsoljuk (a harmadik hullám jelszámlálás a hullámból0). Alternatív megoldásként, ha a cntD5 5, akkor jelenleg 5 hangot játszanak le, 4 hangjel alacsonyabb, mint a D5, így a waveD5 lógni fog, és nem teszünk vele semmit.

Az IF utasításokat ezután megismétlik, hogy lefedjék mind a 25 jegyzet esetét.

Amplitúdó -összeadó

A legalacsonyabb 4 hullám kiválasztása után össze kell adnunk őket. Az ok, amiért csak négy hangot adunk össze, az az, hogy a kimenetünkre használt PWM -ötlet csak bizonyos felbontású lehet, amíg a PWM túl lassan fut, és a hangszóró elkezdi felvenni a PWM négyzethullámot. Például, ha 8192 (13 bit) felbontást használnánk, akkor mind a 8192 pontnak meg kell felelnie a fedélzeti óra emelkedő szélének. Tehát 100MHz / 8192 = 12,2kHz, ami jóval az emberi hallás tartományán belül van.

Az amplitúdók tényleges hozzáadása szuper egyszerű, csak meg kell győződnie arról, hogy nagyon gyorsan tud -e futni.

PWM kimenet

A PWM teljesítményciklusa jelzi a kimeneti hullámunk amplitúdóját abban a pillanatban. Például, ha az amplitúdótartományunk 0 és 128 között van, akkor a 0 0%-os teljesítményciklus, a 64 az 50%, a 128 100%stb. Ez a PWM rendkívül gyorsan fog futni (a miénk 97,6 kHz), olyan gyorsan, hogy a hangszóró nem fogja felismerni az egyes négyzethullámokat, hanem az átlagos feszültséget nézi, és létrehozza az „analóg” jelünket.

Kényszerfájl

Lehet, hogy másképpen csatlakoztatta a hardvert, ezért csak győződjön meg arról, hogy a korlátozási fájl megegyezik.

5. lépés: Kódletöltések

Az alábbiakban található a Vivado kódja.txt és.vhd formátumban is. A Wave_Generator a hullámgenerátor almodul, a Two_Octave_Synth pedig a legfelső modul minden mással.

Ajánlott: