Turinys:

„Basys3 FPGA“skaitmeninis garso sintezatorius: 5 žingsniai
„Basys3 FPGA“skaitmeninis garso sintezatorius: 5 žingsniai

Video: „Basys3 FPGA“skaitmeninis garso sintezatorius: 5 žingsniai

Video: „Basys3 FPGA“skaitmeninis garso sintezatorius: 5 žingsniai
Video: Chord Dave обзор ЦАПа с акустикой ProAC D48 и High End усилителем Plinius Hiato 2024, Liepa
Anonim
Image
Image
„Basys3 FPGA“skaitmeninis garso sintezatorius
„Basys3 FPGA“skaitmeninis garso sintezatorius
„Basys3 FPGA“skaitmeninis garso sintezatorius
„Basys3 FPGA“skaitmeninis garso sintezatorius

Šis skaitmeninis sinusinių bangų klaviatūros sintezatorius priims vartotojo įvestį per keletą momentinių jungiklių, išdėstytų kaip klaviatūra, ir išves garso bangą per garsiakalbį. Remiantis vartotojo įvestimi, prietaisas generuos įvairaus dažnio sinusines bangas nuo C4 iki C6. Vartotojas gali įvesti pastabas nuo C4 iki C6 (iš viso 25 natos) ir iki keturių klavišų vienu metu - jei paspausite daugiau nei keturis klavišus, bus leidžiami keturi žemiausi tonai.

Šį projektą atliko Ryanas Morrisas ir Mavisas Tsoi mūsų skaitmeninio dizaino „Cal Poly CPE 133“klasei:)

1 žingsnis: teorija

FPGA plokštė gali perduoti tik skaitmeninius signalus. Kitaip tariant, jis gali gaminti tik aukštą (3,3 V) arba žemą (0 V) įtampą. Tačiau garso signalai yra analoginiai ir gali turėti be galo daug įtampos pakopų. Norėdami tai išspręsti, mes naudosime PWM (impulsų pločio moduliacijos) signalą, kad imituotume analoginę bangą. Jei nežinote, kas yra PWM, patikrinkite tai:

2 žingsnis: Ingredientai ir įrankiai

  • Kompiuteris su įdiegtu „Vivado“
  • Mes naudosime „Vivado“versiją 2017.2
  • „Basys3“FPGA plokštė
  • 25 SPDT ribiniai jungikliai (mes juos naudojome)
  • 30 jungiamųjų laidų (vienas galas, kitas galas nesvarbu), 12 colių
  • Vielos pjaustytuvai
  • Vielos nuėmikliai
  • Atsarginė viela litavimui
  • Dervos šerdies lydmetalis
  • Lituoklis
  • Audio “moterų garso lizdas
  • Stiprintuvas/garsiakalbis
  • Kažkas, prie kurio reikia prijungti jungiklius (naudojome protoboard + medinę dėžę)

3 žingsnis: laidų ir aparatūros sąranka

Laidų ir aparatūros sąranka
Laidų ir aparatūros sąranka
Laidų ir aparatūros sąranka
Laidų ir aparatūros sąranka
Laidų ir aparatūros sąranka
Laidų ir aparatūros sąranka

architektūros sistema

Žr. 1 paveikslą: 25 galimi įėjimai → „Basys3 Board“→ stiprintuvas ir garsiakalbis.

Išvestis

Žr. 2 paveikslą: „Basys3“plokštė → 1/2 colio moteriškas garso lizdas → garsiakalbis (su stiprintuvu)

Įvestis

„Basys3“plokštės „pmod“jungtys turi būti prijungtos prie žemės, kad būtų matomas žemas įėjimas, ir tinkamai neveiks, jei bus paliktas kaip atvira grandinė. Dėl šios priežasties visiems užrašų klavišams turime naudoti SPDT jungiklius. SPDT jungiklis iš esmės leidžia vartotojui perjungti grandines, kai paspaudžiamas, todėl mes juos naudosime kaip „mygtukus“, kad įvestume žemus (0 V) arba aukštus (3,3 V) signalus į „Basys3“plokštę.

Prie kiekvieno jungiklio NO (paprastai atidarytas) gnybtas bus prijungtas prie 3.3V, NC (paprastai uždarytas) - prie GND, o COM (bendras) - prie FPGA įvesties. Žr. 3 pav.

Kadangi turime 25 ribinius jungiklius, jie visi turės bendrą 3.3V liniją ir bendrą GND liniją. Tada signalo linija iš kiekvieno galinio jungiklio bus suskirstyta į 8 grupes ir prijungta prie „Basod3“plokštės „pmod“jungčių, naudojant užtraukiamus trumpiklius, kad būtų sumažinta monumentali netvarka. Žr. 4 paveikslą arba pirmųjų aštuonių klavišų pavyzdį.

4 žingsnis: VHDL sąranka („Vivado“)

VHDL sąranka („Vivado“)
VHDL sąranka („Vivado“)
VHDL sąranka („Vivado“)
VHDL sąranka („Vivado“)

Sinusinių bangų generatorius ir PWM generatorius pirmiausia buvo išbandyti, siekiant įsitikinti, kad mūsų koncepcija veikia, tada buvo integruoti įvesties ribotuvai ir amplitudės sumotojai/perjungikliai. Išsami informacija apie kiekvieno proceso bloko funkciją ir įvestį/išvestį yra parodyta paveikslėlyje. Kodas rodomas žemiau, bet taip pat pridedamas kaip VHD ir txt failai. Jei yra neatitikimų, eikite su VHD failais.

BTW: tikriausiai turėjome sutrumpinti eilutes, tačiau kodų įterpimas į „Instructables“taip pat pasirodė gana erzinantis, todėl tarpai nėra patys didžiausi ir nėra sintaksės paryškinimo. Jei turite „Vivado“ir norite sekti kodą, labai rekomenduojame tiesiog atsisiųsti failą.

Pirmiausia pažvelkime į sinusinių bangų generatoriaus modulį.

biblioteka IEEE; naudokite IEEE. STD_LOGIC_1164. ALL; naudoti IEEE. NUMERIC_STD. ALL; objekto „Wave_Generator“yra prievadas (aktyviklis: STD_LOGIC; - klavišo paspaudimas Freq_Cnt: STD_LOGIC_VECTOR (nuo 15 iki 0); - skaitiklio vertė = 100 MHz / (pastabos dažnis*64 sinusinės bangos skyriai) (apvalinama iki artimiausio skaičiaus) - pervadinta iš „Freq wavegenCLK“: STD_LOGIC; - „Basys3 100MHz CLK WaveOut“: išvestis STD_LOGIC_VECTOR (nuo 9 iki 0)); - signalo bangos galo amplitudė Wave_Generator; architektūra „Wave_Generator“elgsena yra signalas i: sveikųjų skaičių diapazonas nuo 0 iki 64: = 0; -amplitudės atminties banko tipo „memory_type“indeksas yra masyvas (nuo 0 iki 63), kurio skaičius yra nuo -64 iki 63; - sukurti atminties banką (ROM) amplitudės vertėms laikyti- ar ši RAM ar ROM tiesiog įdomu … signalo amplitudė: atminties tipas: = (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); - sinusinės bangos pradžios proceso amplitudės atminties bankas (wavegenCLK, Trigger) kintamasis skaitiklis: nepasirašytas (nuo 15 iki 0): = to_unigned (0, 16); - laikrodžio daliklio skaitiklis, pervadintas iš skaičiaus1, prasideda, jei (kylančioji briauna (wavegenCLK)), tada, jei (trigeris = '1'), tada- klavišas paspaudžiamas skaitiklis: = skaitiklis + 1; if (skaitiklis = nepasirašytas (Freq_Cnt)) tada - Freq_Cnt = 100Mhz / (atkreipkite dėmesį į dažnį * 64 sinusinės bangos padalijimai) - iš naujo nustatykite skaitiklį ir priskirkite amplitudės duomenis išvesties skaitikliui: = to_unigned (0, 16); „WaveOut“<= STD_LOGIC_VECTOR (iki_ženklo (amplitudė (i), 10)); - padidėjimas i kitam skaitymui i <= i + 1; - iš naujo nustatykite i, jei viena sinusinė banga buvo baigta, jei (i = 63), tada i <= 0; pabaiga, jei; pabaiga, jei; - (skaitiklis = nepasirašytas (Freq_Cnt)) else- klavišas nespaudžiamas- išvesties, amplitudės indekso ir skaitiklio WaveOut atstatymas <= "0000000000"; i <= 0; skaitiklis: = to_unigned (0, 16); -išvesties amplitudė = -64, kai nėra grojamos natos, pasibaigia, jei; - (Trigeris = '1') galas, jei; - (kylančio krašto (CLK)) pabaigos procesas; pabaiga Elgesys;

Naudodami vidinį laikrodį ir ROM, „Basys3“sukursime skaitmeninę sinusinę bangą. Šiame ROM bus saugomos 64 reikšmės, reprezentuojančios 64 amplitudes sinusine banga. Žr. 1 paveikslą. 64 mūsų naudojamos vertės imituoja sinusinę bangą, kurios skiriamoji geba yra gana gera.

Naudodami vidinį laikrodį, mes skaičiuojame iki vertės, kuri parodo laikrodžio greitį, padalytą iš norimos bangos dažnio ir 64: Clk div = 100MHz / (Freq * 64) Kiekvieną kartą, kai mūsų skaitiklis pasiekia šią vertę, mes skambiname numeriu iš ROM ir išsiųskite tai iš mūsų bangų generatoriaus modulio. Mūsų bangos dažnis priklausys nuo to, kaip greitai mes vadinsime šias amplitudes.

Turėsime 25 submodulius, kiekvienas susietas su vienu dažniu/užrašu.

Štai likęs kodas, kuris iškviečia sinusinių bangų generatoriaus modulius:

biblioteka IEEE; naudokite IEEE. STD_LOGIC_1164. ALL; naudoti IEEE. NUMERIC_STD. ALL; subjektas Two_Octave_Synth yra prievadas (CLK: STD_LOGIC; O4: STD_LOGIC_VECTOR (nuo 11 iki 0); O5: STD_LOGIC_VECTOR (nuo 12 iki 0); išvestis: out STD_LOGIC); end Two_Octave_Synth; architektūra „Two_Octave_Synth“elgsena yra komponentas „Wave_Generator“yra prievadas (trigeris: STD_LOGIC; dažn. galinis komponentas; --------------------------- išėjimo signalai iš bangų generatoriaus ------------------ ----- signalas WaveC4, WaveCs4, WaveD4, WaveDs4, WaveE4, WaveF4, WaveFs4, WaveG4, WaveGs4, WaveA4, WaveAs4, WaveB4, WaveC5, WaveCs5, WaveD5, WaveDs5, WaveE5, WaveE5, WaveE5, WaveE5 WaveAs5, WaveB5, WaveC6: pasirašyta (nuo 9 iki 0); -------------------------------- užrašų pasirinkimo logikai -------------- ------ signalas 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: nepasirašytas (nuo 4 iki 0); signalas cntC4, cntCs4, cntD4, cntDs4, cntE4, cntF4, cntFs4, cntG4, cntGs4, cntA4, cntAs4, cntB4, cntC5, cntCs5, cntD5, cntDs5, cntE5, cntCs5, cntC5, cntC5, cntC5: be parašo (4 iki 0); signalo klaida: STD_LOGIC; ----------------------------------- už sinusinių bangų pridėjimą ----------- --------------- signalas Wave0, Wave1, Wave2, Wave3: pasirašytas (nuo 9 iki 0); -signalai iš „Wave Generator“modulio išėjimo signalo „WaveSum“: STD_LOGIC_VECTOR (nuo 9 iki 0); -susumuotų sinusinių bangų signalas (2 komplimentas nuo 512 iki 511) signalizuoja teigiamaiWaveSum: STD_LOGIC_VECTOR (nuo 9 iki 0); -neskirtas nuo 0 iki 1023, skirtas naudoti PWM generatoriuje ----------------------------------- PWM generavimui ------------------------------- signalo ping_length: unsigned (nuo 9 iki 0): = nepasirašytas (teigiama bangos suma); --signal off_length: unsigned (6 iki 0): = to_unigned (127, 7) -unsigned (WAVE); signalas PWM: nepasirašytas (nuo 9 iki 0): = to_unigned (0, 10); pradėti Pastaba_C4: „Wave_Generator“prievadų žemėlapis (Trigger => O4 (0), Freq_Cnt => X "1755", wavegenCLK => CLK, pasirašytas (WaveOut) => WaveC4); --5973, 261,63 Hz Pastaba_Cs4: „Wave_Generator“prievado žemėlapis (Trigger => O4 (1), Freq_Cnt => X "1606", wavegenCLK => CLK, pasirašytas (WaveOut) => WaveCs4);-5638, 277,18 Hz Note_D4: „Wave_Generator“prievado žemėlapis (Trigger => O4 (2), Freq_Cnt => X "14C9", wavegenCLK => CLK, pasirašytas (WaveOut) => WaveD4); --5321, 293,66 Hz. „Wave_Generator“prievado žemėlapis (Trigger => O4 (4), Freq_Cnt => X "1285", wavegenCLK => CLK, pasirašytas (WaveOut) => WaveE4); --4741, 329,63 Hz Pastaba_F4: „Wave_Generator“prievadų žemėlapis (Trigger => O4 (5), Freq_Cnt => X "117B", wavegenCLK => CLK, pasirašytas (WaveOut) => WaveF4); --4475, 349,23 Hz Pastaba_Fs4: „Wave_Generator“prievado žemėlapis (Trigger => O4 (6), Freq_Cnt => X "1080", wavegenCLK => CLK, pasirašytas (WaveOut) => WaveFs4);-4224, 369,99 Hz Pastaba_G4: „Wave_Generator“prievado žemėlapis (Trigger => O4 (7), Freq_Cnt => X "0F92", wavegenCLK => CLK, pasirašytas (WaveOut) => WaveG4); --3986, 392,00 Hz Pastaba_Gs4: „Wave_Generator“prievadų žemėlapis (Trigger => O4 (8), Freq_Cnt => X "0EB3", wavegenCLK => CLK, pasirašytas (WaveOut) => WaveGs4);-3763, 415,30 Hz Note_A4: „Wave_Generator“prievado žemėlapis (Trigger => O4 (9), Freq_Cnt => X "0DE0", wavegenCLK => CLK, pasirašytas (WaveOut) => WaveA4); --3552, 440,00 Hz Pastaba_As4: „Wave_Generator“prievadų žemėlapis (Trigger => O4 (10), Freq_Cnt => X "0D18", wavegenCLK => CLK, pasirašytas (WaveOut) => WaveAs4);-3352, 466,16 Hz Pastaba_B4: „Wave_Generator“prievado žemėlapis (Trigger => O4 (11), Freq_Cnt => X "0C5C", wavegenCLK => CLK, pasirašytas (WaveOut) => WaveB4); --3164, 493,88 Hz -------------------------------------------- -------------------------------------------------- --------------------------- Pastaba_C5: „Wave_Generator“prievadų žemėlapis (Trigger => O5 (0), Freq_Cnt => X "0BAB", wavegenCLK => CLK, pasirašytas (WaveOut) => WaveC5); --2987, 523,25 Hz Pastaba_Cs5: „Wave_Generator“prievadų žemėlapis (Trigger => O5 (1), Freq_Cnt => X "0B03", wavegenCLK => CLK, pasirašytas (WaveOut) => WaveCs5);-2819, 554,37 Hz Pastaba_D5: „Wave_Generator“prievado žemėlapis (Trigger => O5 (2), Freq_Cnt => X "0A65", wavegenCLK => CLK, pasirašytas (WaveOut) => WaveD5); --2661, 587,33 Hz Pastaba_Ds5: „Wave_Generator“prievadų žemėlapis (Trigger => O5 (3), Freq_Cnt => X "09D0", wavegenCLK => CLK, pasirašytas (WaveOut) => WaveDs5);-2512, 622,25 Hz pastaba_E5: „Wave_Generator“prievado žemėlapis (Trigger => O5 (4), Freq_Cnt => X "0943", wavegenCLK => CLK, pasirašytas (WaveOut) => WaveE5); --2371, 659,25 Hz pastaba_F5: „Wave_Generator“prievado žemėlapis (Trigger => O5 (5), Freq_Cnt => X "08Be", wavegenCLK => CLK, pasirašytas (WaveOut) => WaveF5); --2238, 698,46 Hz Pastaba_Fs5: „Wave_Generator“prievado žemėlapis (Trigger => O5 (6), Freq_Cnt => X "0840", wavegenCLK => CLK, pasirašytas (WaveOut) => WaveFs5);-2112, 739,99 Hz Note_G5: „Wave_Generator“prievado žemėlapis (Trigger => O5 (7), Freq_Cnt => X "07CA", wavegenCLK => CLK, pasirašytas (WaveOut) => WaveG5); --1994, 783,99 Hz Pastaba_Gs5: „Wave_Generator“prievadų žemėlapis (Trigger => O5 (8), Freq_Cnt => X "075A", wavegenCLK => CLK, pasirašytas (WaveOut) => WaveGs5);-1882, 830,61 Hz Pastaba_A5: „Wave_Generator“prievado žemėlapis (Trigger => O5 (9), Freq_Cnt => X "06F0", wavegenCLK => CLK, pasirašytas (WaveOut) => WaveA5); --1776, 880,00 Hz Note_As5: „Wave_Generator“prievadų žemėlapis (Trigger => O5 (10), Freq_Cnt => X "068C", wavegenCLK => CLK, pasirašytas (WaveOut) => WaveAs5);-1676, 932,33 Hz pastaba_B5: „Wave_Generator“prievado žemėlapis (Trigger => O5 (11), Freq_Cnt => X "062E", wavegenCLK => CLK, pasirašytas (WaveOut) => WaveB5); --1582, 987,77 Hz Pastaba_C6: „Wave_Generator“prievadų žemėlapis (Trigger => O5 (12), Freq_Cnt => X "05D6", wavegenCLK => CLK, pasirašytas (WaveOut) => WaveC6); --1494, 1046,5 Hz ------------ natų pasirinkimo 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; Pasirinkimas: procesas (WaveC4, WaveCs4, WaveD4, WaveDs4, WaveE4, WaveF4, WaveFs4, WaveG4, WaveGs4, WaveA4, WaveAs4, WaveB4, WaveC5, WaveCs5, WaveD5, WaveDs5, WaveA5, WaveE5, WaveE5, WaveE5 WaveB5, WaveC6) prasideda, jei (cntC6 = "00000"), tada --------------- jei signalai nėra generuojami Wave0 <= "0000000000"; Banga1 <= "0000000000"; Banga2 <= "0000000000"; Banga3 <= "0000000000"; kitaip jei (O4 (0) = '1') tada ------------------- pastaba C4 grojo „Wave0 Wave0 Wave1“klaida Wave0 Wave1 Wave2 Wave0 Wave0 Wave1 Wave2 Wave3 error Wave0 Wave1 Wave2 Wave3 klaida Wave0 Wave1 Wave2 Wave3 klaida Wave0 Wave1 Wave2 Wave3 klaida Wave0 Wave1 Wave2 Wave3 klaida Wave0 Wave1 Wave2 Wave3 klaida Wave0 Wave1 Wave2 Wave3 Wave1 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave1 Wave2 Wave3 klaida Wave0 Wave1 Wave2 Wave3 klaida Wave0 Wave1 Wave2 Wave3 klaida Wave0 Wave1 Wave2 Wave3 klaida Wave0 Wave1 Wave2 Wave3 klaida Wave0 Wave1 Wave2 Wave3 Wave0 Wave3 Wave2 Wave3 Wave2 Wave3 Wave2 Wave3 = BangaC6; Banga1 <= "0000000000"; Banga2 <= "0000000000"; Wave3 Wave1 <= WaveC6; Banga2 <= "0000000000"; Wave3 Wave2 <= WaveC6; Wave3 Wave3 klaida Wave1 <= "0000000000"; Banga2 <= "0000000000"; Wave3 Wave2 <= "0000000000"; „Wave3 Wave3“klaida <= '1'; pabaigos atvejis; pabaiga, jei; pabaiga, jei; pabaigos procesas; ------------- sinusinės bangos sumavimo priemonė -------------------- WaveSum <= STD_LOGIC_VECTOR (Wave0 + Wave1 + Wave2 + Wave3); --------- padarykite sinusinę bangą teigiamą pwm --------------------- teigiamąWaveSum <= ne WaveSum (9) & WaveSum (8 iki 0); ------------- PWM generatorius --------------------- procesas (CLK)-kintamųjų skaičius: nepasirašytas (nuo 1 iki 0): = nepasirašytas (0, 2); pradėti, jei (kylančioji briauna (CLK)) tada -skaičius: = skaičius + 1; --if (skaičius = nepasirašytas (4, 2)) tada-skaičius: = nepasirašytas (0, 2); --if (PWM = to_ if (PWM <ping_length), tada išvestis <= '1'; else output <= '0'; end if; PWM <= PWM + 1; ping_length <= nepasirašytas (teigiamaWaveSum); --end jei; baigti, jei; baigti procesą; baigti elgesį;

4 Pastabos parinkiklis Kebliausia šio projekto dalis yra tik keturių dažnių pasirinkimas. Mes tai padarėme su daugybe IF teiginių ir vietoj kintamųjų naudojome signalus, kad procesą būtų galima imituoti ir derinti. Mes bandėme kitus metodus, naudodami kintamuosius ir FOR kilpas, tačiau susidūrėme su vykdymo laiko klaidomis. Taigi galiausiai nusprendėme, kad jei tai pavyks, paliksime tai ramybėje. Nesutvarkyk to, kas nesugadinta amirito?

Keturios išvesties bangos yra pažymėtos „Wave0“, „Wave1“, „Wave2“, „Wave3“- štai kas bus sudedama, kad būtų suformuota galutinė išvestis.

Žiūrėdami į kodą, pamatysite daugybę signalų, pažymėtų C4, Cs4, D4, Ds4 ir tt. Tai yra 5 bitų signalai, kurie paleidžia atitinkamą trigerį iš O4 (4 oktava) arba O5 (5 oktava) ir daro juos 5 bitų pridėjimui.

Tada kintamieji „cntC4“, „cntCs4“ir tt parodo, kiek natų, mažesnių už tikslinę, buvo paleista, įskaitant tikslinę. Pavyzdžiui, jei grojami C4, E4, G4, A#4 ir D5 (C9 akordas), cntC4 bus 1, cntE4 bus 2, cntG4 bus 3 ir kt.

Tada, kai tik grojamas užrašas, bus išnagrinėtas tikslinės natos skaičius, kad sužinotumėte, kur prijungti natos signalą. Pvz., Jei grojama D5 nata (o tai reiškia, kad O5 (2) yra aukšta), o cntD5 yra 3, šiuo metu grojamos 3 natos, 2 natomis mažesnės nei D5, todėl mes sujungsime bangą D5 su banga2 (trečioji banga) signalų skaičiavimas iš bangos0). Arba, jei cntD5 yra 5, šiuo metu yra grojamos 5 natos, 4 natos žemesnės nei D5, todėl mes tiesiog paliksime „waveD5“kabinti ir nieko su juo nedarysime.

Tada IF teiginiai kartojami, kad apimtų visų 25 pastabų atvejus.

Amplitudės sumuotojas

Pasirinkę žemiausias 4 bangas, turime jas sudėti. Priežastis, dėl kurios pridėsime tik keturias natas, yra ta, kad PWM idėja, kurią naudojame savo produkcijai, gali turėti tik tam tikrą skiriamąją gebą, kol PWM veikia per lėtai ir garsiakalbis pradės rinkti PWM kvadratinę bangą. Pavyzdžiui, jei naudosime 8192 (13 bitų) skiriamąją gebą, kiekvienas iš šių 8192 taškų turi atitikti kylantį borto laikrodžio kraštą. Taigi, 100MHz / 8192 = 12,2kHz, kuris yra gerai žmogaus klausos diapazone.

Tikrasis amplitudžių pridėjimas yra labai paprastas, jūs tiesiog turite įsitikinti, kad jis gali veikti tikrai greitai.

PWM išvestis

PWM darbo ciklas parodys mūsų išėjimo bangos amplitudę tuo momentu. Pavyzdžiui, jei amplitudės diapazonas yra nuo 0 iki 128, 0 būtų 0%darbo ciklas, 64 būtų 50%, 128 būtų 100%ir tt Šis PWM veiks nepaprastai greitai (mūsų yra 97,6 kHz), taip greitai, kad garsiakalbis neatpažins atskirų kvadratinių bangų, o pažvelgs į vidutinę įtampą, sukurdamas „analoginį“signalą.

Apribojimų failas

Galbūt skirtingai prijungėte aparatūrą, todėl įsitikinkite, kad apribojimų failas sutampa.

5 veiksmas: kodo atsisiuntimai

Žemiau yra „Vivado“kodas.txt formatu ir.vhd. „Wave_Generator“yra bangų generatoriaus submodulis, o „Two_Octave_Synth“yra viršutinis modulis su visa kita.

Rekomenduojamas: