Satura rādītājs:

Basys3 FPGA digitālais audio sintezators: 5 soļi
Basys3 FPGA digitālais audio sintezators: 5 soļi

Video: Basys3 FPGA digitālais audio sintezators: 5 soļi

Video: Basys3 FPGA digitālais audio sintezators: 5 soļi
Video: Part 2: IQ demodulator with decimation: RTL hardware design and implementation 2024, Novembris
Anonim
Image
Image
Basys3 FPGA digitālais audio sintezators
Basys3 FPGA digitālais audio sintezators
Basys3 FPGA digitālais audio sintezators
Basys3 FPGA digitālais audio sintezators

Šis digitālais sinusa viļņu tastatūras sintezators uztvers lietotāju ievadi, izmantojot virkni īslaicīgu slēdžu, kas izkārtoti kā tastatūra, un izvadīs audio viļņu caur skaļruni. Pamatojoties uz lietotāja ievadīto informāciju, ierīce ģenerēs dažādu frekvenču sinusa viļņus no C4 līdz C6. Lietotājs var ievadīt piezīmes no C4 līdz C6 (kopā 25 piezīmes) un līdz četriem taustiņiem vienlaikus - ja tiek nospiests vairāk nekā četri taustiņi, tiks atskaņoti četri zemākie toņi.

Šo projektu veica Ryan Morris un Mavis Tsoi mūsu Cal Poly CPE 133 digitālā dizaina klasē:)

1. solis: teorija

FPGA plate var izvadīt tikai ciparu signālus. Citiem vārdiem sakot, tas var radīt tikai augstu (3,3 V) spriegumu vai zemu (0 V) spriegumu. Tomēr audio signāli ir analogi, un tiem var būt bezgalīgi daudz sprieguma pieauguma. Lai to apietu, mēs izmantosim PWM (impulsa platuma modulācijas) signālu, lai atdarinātu analogo viļņu. Ja jūs nezināt, kas ir PWM, pārbaudiet to:

2. darbība: sastāvdaļas un rīki

  • Dators ar instalētu Vivado
  • Mēs izmantosim Vivado versiju 2017.2
  • Basys3 FPGA padome
  • 25 SPDT ierobežojošie slēdži (mēs tos izmantojām)
  • 30 džemperu vadi (vienam galam tēviņš, otram galam nav nozīmes), 12 collas
  • Stiepļu griezēji
  • Stiepļu noņēmēji
  • Rezerves stieple lodēšanai
  • Sveķu kodolu lodētava
  • Lodāmurs
  • Audio”sieviešu audio ligzda
  • Pastiprinātājs/skaļrunis
  • Kaut kas, lai uzstādītu slēdžus (mēs izmantojām protobordu + koka kasti)

3. darbība: vadu un aparatūras iestatīšana

Elektroinstalācijas un aparatūras iestatīšana
Elektroinstalācijas un aparatūras iestatīšana
Elektroinstalācijas un aparatūras iestatīšana
Elektroinstalācijas un aparatūras iestatīšana
Elektroinstalācijas un aparatūras iestatīšana
Elektroinstalācijas un aparatūras iestatīšana

Sistēmas arhitektūra

Skatiet 1. attēlu: 25 pieejamās ieejas → Basys3 plate → pastiprinātājs un skaļrunis.

Izeja

Skatīt 2. attēlu: Basys3 plate → 1/2 collu sieviešu audio ligzda → skaļrunis (ar pastiprinātāju)

Ievadi

Lai redzētu zemu ieeju, Basys3 plates pmod savienojumiem jābūt savienotiem ar zemi, un tie nedarbosies pareizi, ja tos atstās kā atvērtu ķēdi. Šī iemesla dēļ mums visiem piezīmju taustiņiem ir jāizmanto SPDT slēdži. SPDT slēdzis būtībā ļauj lietotājam pārslēgties starp ķēdēm, kad tiek nospiests, tāpēc mēs tās izmantosim kā savas pogas, lai ievadītu Basys3 plates zemo (0V) vai augsto (3.3V) signālus.

Katram slēdzim terminālis NO (parasti atvērts) ir pievienots 3.3V, NC (parasti slēgts) termināls ir pievienots GND, un COM (kopējais) terminālis ir pievienots FPGA ieejai. Skatīt 3. attēlu.

Tā kā mums ir 25 gala slēdži, tiem visiem būs kopīga 3.3V līnija un kopēja GND līnija. Pēc tam signāla līnija no katra ierobežojošā slēdža tiks apvienota grupās pa 8 un savienota ar pmod savienojumiem Basys3 panelī, izmantojot rāvējslēdzējus ar džemperiem, lai samazinātu mūsu radīto monumentālo putru. Skatiet 4. attēlu vai pirmo astoņu taustiņu piemēru.

4. darbība: VHDL iestatīšana (Vivado)

VHDL iestatīšana (Vivado)
VHDL iestatīšana (Vivado)
VHDL iestatīšana (Vivado)
VHDL iestatīšana (Vivado)

Sinusviļņu ģenerators un PWM ģenerators vispirms tika pārbaudīti, lai pārliecinātos, ka mūsu koncepcija darbojas, pēc tam tika integrēts ieejas ierobežotājs un amplitūdas papildinātājs/pārslēdzējs. Sīkāka informācija par funkciju un katra procesa bloka I/O ir parādīta attēlā. Kods ir parādīts zemāk, bet arī pievienots kā VHD un txt faili. Ja ir neatbilstības, izmantojiet VHD failus.

BTW: mums, iespējams, vajadzēja padarīt mūsu rindas īsākas, taču koda iegulšana Instructables arī izrādījās diezgan kaitinoša, tāpēc atstarpes nav vislielākās un nav sintakses izcelšanas. Ja jums ir Vivado un vēlaties sekot līdzi kodam, mēs ļoti iesakām lejupielādēt failu.

Vispirms apskatīsim sinusa viļņu ģeneratora moduli.

bibliotēka IEEE; izmantojiet IEEE. STD_LOGIC_1164. ALL; izmantojiet IEEE. NUMERIC_STD. ALL; entītijas Wave_Generator ir ports (aktivizētājs: STD_LOGIC; - taustiņa nospiešana Freq_Cnt: STD_LOGIC_VECTOR (no 15 līdz 0); - skaitītāja vērtība = 100 MHz / (piezīmju biežums*64 sinusa viļņa nodalījumi) (apaļš līdz tuvākajam skaitlim) - pārdēvēts no Freq wavegenCLK: STD_LOGIC; - Basys3 100MHz CLK WaveOut: out STD_LOGIC_VECTOR (9 līdz 0)); - Viļņa gala Wave_Generator parakstītā amplitūda; arhitektūra Wave_Generator uzvedība ir signāls i: veselu skaitļu diapazons no 0 līdz 64: = 0; -amplitūdas atmiņas bankas tipa indekss memory_type ir masīvs (no 0 līdz 63) no vesela skaitļa diapazona -64 līdz 63; - izveidojiet atmiņas banku (ROM), lai turētu amplitūdas vērtības- vai šī RAM vai ROM tikai interesē … signāla amplitūda: atmiņas_tips: = (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ūdas atmiņas banka sinusa viļņu sākuma procesam (wavegenCLK, Trigger) mainīgo skaitītājs: neparakstīts (15 līdz 0): = līdz_ neparakstīts (0, 16); - pulksteņa dalītāja skaitītājs, kas pārdēvēts no skaita1, sākas, ja (pieaugošā mala (wavegenCLK)), tad, ja (aktivizētājs = '1'), tad- tiek nospiests skaitītājs: = skaitītājs + 1; ja (skaitītājs = neparakstīts (Freq_Cnt)) tad - Freq_Cnt = 100Mhz / (ņemiet vērā frekvenci * 64 sinusa viļņa iedalījumi) - atiestatiet skaitītāju un piešķiriet amplitūdas datus izejas skaitītājam: = to_unigned (0, 16); WaveOut <= STD_LOGIC_VECTOR (parakstīts (amplitūda (i), 10)); - pieaugums i nākamajam lasījumam i <= i + 1; - atiestatīt i, ja viens sinusa vilnis ir pabeigts, ja (i = 63), tad i <= 0; beigt, ja; beigt, ja; - (skaitītājs = neparakstīts (Freq_Cnt)) cits- taustiņš nav nospiests- atiestatīt izeju, amplitūdas indeksu un skaitītāja WaveOut <= "0000000000"; i <= 0; skaitītājs: = neparakstīts (0, 16); -izejas amplitūda = -64, ja neviena nota netiek atskaņota, beidzas, ja; - (Aktivizētājs = '1') beidzas, ja; - (pieaugošās malas (CLK)) beigu process; beigas Uzvedība;

Mēs ģenerēsim digitālo sinusa vilni Basys3, izmantojot iekšējo pulksteni un ROM. Šajā ROM tiks saglabātas 64 vērtības, kas sinusa viļņā attēlo 64 amplitūdas. Skatiet 1. attēlu. 64 izmantotās vērtības atdarina sinusoīdu ar diezgan labu izšķirtspēju.

Izmantojot iekšējo pulksteni, mēs skaitām līdz vērtībai, kas attēlo pulksteņa ātrumu, dalītu ar vēlamā viļņa frekvenci un 64: Clk div = 100MHz / (Freq * 64) Katru reizi, kad mūsu skaitītājs sasniedz šo vērtību, mēs izsaucam numuru no ROM un nosūtiet to no mūsu viļņu ģeneratora moduļa. Mūsu viļņa frekvence būs atkarīga no tā, cik ātri mēs saucam šīs amplitūdas.

Mums būs 25 apakšmoduļi, katrs saistīts ar vienu frekvenci/piezīmi.

Šeit ir atlikušais kods, kas izsauc sinusa viļņu ģeneratora moduļus:

bibliotēka IEEE; izmantojiet IEEE. STD_LOGIC_1164. ALL; izmantojiet IEEE. NUMERIC_STD. ALL; entītija Two_Octave_Synth ir osta (CLK: STD_LOGIC; O4: STD_LOGIC_VECTOR (11 līdz 0); O5: STD_LOGIC_VECTOR (12 līdz 0); output: out STD_LOGIC); beigas Two_Octave_Synth; Arhitektūra Two_Octave_Synth uzvedība ir sastāvdaļa Wave_Generator ir ports (aktivizētājs: STD_LOGIC; Freq_Cnt: STD_LOGIC_VECTOR (15 līdz 0); wavegenCLK: STD_LOGIC; WaveOut: out STD_LOGIC_VECTOR (9 līdz 0)); gala sastāvdaļa; --------------------------- izejas signāli no viļņu ģeneratora ------------------ ----- signāls WaveC4, WaveCs4, WaveD4, WaveDs4, WaveE4, WaveF4, WaveFs4, WaveG4, WaveGs4, WaveA4, WaveAs4, WaveB4, WaveC5, WaveCs5, WaveD5, WaveDs5, WaveE5, WaveE5, WaveE5, WaveE5 WaveAs5, WaveB5, WaveC6: parakstīts (9 līdz 0); -------------------------------- par piezīmju izvēles loģiku -------------- ------ signāls 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: neparakstīts (4 līdz 0); signāls cntC4, cntCs4, cntD4, cntDs4, cntE4, cntF4, cntFs4, cntG4, cntGs4, cntA4, cntAs4, cntB4, cntC5, cntCs5, cntD5, cntDs5, cntE5, cntCsnt, cntC5, cntC5: neparakstīts (4 līdz 0); signāla kļūda: STD_LOGIC; ----------------------------------- par sinusa viļņu pievienošanu ----------- --------------- signāls Wave0, Wave1, Wave2, Wave3: parakstīts (9 līdz 0); -signāli no viļņu ģeneratora moduļa izejas signāla WaveSum: STD_LOGIC_VECTOR (9 līdz 0); -signāls summētajiem sinusa viļņiem (2 kompliments -512 līdz 511) signāls pozitīvsWaveSum: STD_LOGIC_VECTOR (9 līdz 0); -neparakstīts no 0 līdz 1023, izmantošanai PWM ģeneratorā ------------------------------------ PWM ģenerēšanai ------------------------------- signāla ping_length: neparakstīts (9 līdz 0): = neparakstīts (pozitīvsWaveSum); -signāla izslēgšanas_garums: neparakstīts (6 līdz 0): = neparakstīts (127, 7) -neparakstīts (WAVE); signāls PWM: neparakstīts (9 līdz 0): = līdz_ neparakstīts (0, 10); sākt Note_C4: Wave_Generator porta karte (Trigger => O4 (0), Freq_Cnt => X "1755", wavegenCLK => CLK, parakstīts (WaveOut) => WaveC4); --5973, 261,63 Hz Piezīme_Cs4: Wave_Generator porta karte (Trigers => O4 (1), Freq_Cnt => X "1606", wavegenCLK => CLK, parakstīts (WaveOut) => WaveCs4);-5638, 277,18 Hz Piezīme_D4: Wave_Generator porta karte (Trigger => O4 (2), Freq_Cnt => X "14C9", wavegenCLK => CLK, parakstīts (WaveOut) => WaveD4); --5321, 293,66 Hz. Wave_Generator porta karte (Trigger => O4 (4), Freq_Cnt => X "1285", wavegenCLK => CLK, parakstīts (WaveOut) => WaveE4); --4741, 329,63 Hz Piezīme_F4: Viļņu_ģeneratora porta karte (Trigers => O4 (5), Freq_Cnt => X "117B", wavegenCLK => CLK, parakstīts (WaveOut) => WaveF4); --4475, 349,23 Hz. Wave_Generator porta karte (Trigger => O4 (7), Freq_Cnt => X "0F92", wavegenCLK => CLK, parakstīts (WaveOut) => WaveG4); --3986, 392,00 Hz. Wave_Generator porta karte (Trigger => O4 (9), Freq_Cnt => X "0DE0", wavegenCLK => CLK, parakstīts (WaveOut) => WaveA4); --3552, 440,00 Hz Piezīme_As4: Wave_Generator porta karte (Trigers => O4 (10), Freq_Cnt => X "0D18", wavegenCLK => CLK, parakstīts (WaveOut) => WaveAs4);-3352, 466,16 Hz Piezīme_B4: Wave_Generator porta karte (Trigger => O4 (11), Freq_Cnt => X "0C5C", wavegenCLK => CLK, parakstīts (WaveOut) => WaveB4); --3164, 493,88 Hz -------------------------------------------- -------------------------------------------------- --------------------------- Piezīme_C5: Wave_Generator porta karte (Trigers => O5 (0), Freq_Cnt => X "0BAB", wavegenCLK => CLK, parakstīts (WaveOut) => WaveC5); --2987, 523,25 Hz. Wave_Generator porta karte (Trigger => O5 (2), Freq_Cnt => X "0A65", wavegenCLK => CLK, parakstīts (WaveOut) => WaveD5); --2661, 587,33 Hz. Wave_Generator porta karte (Trigger => O5 (4), Freq_Cnt => X "0943", wavegenCLK => CLK, parakstīts (WaveOut) => WaveE5); --2371, 659,25 Hz Piezīme_F5: Viļņu_ģeneratora porta karte (Trigers => O5 (5), Freq_Cnt => X "08Be", wavegenCLK => CLK, parakstīts (WaveOut) => WaveF5); --2238, 698,46 Hz Piezīme_Fs5: Viļņu ģeneratora porta karte (Trigers => O5 (6), Freq_Cnt => X "0840", wavegenCLK => CLK, parakstīts (WaveOut) => WaveFs5);-2112, 739,99 Hz Piezīme_G5: Wave_Generator porta karte (Trigger => O5 (7), Freq_Cnt => X "07CA", wavegenCLK => CLK, parakstīts (WaveOut) => WaveG5); --1994, 783,99 Hz Piezīme_Gs5: Viļņu ģeneratora porta karte (Trigers => O5 (8), Freq_Cnt => X "075A", wavegenCLK => CLK, parakstīts (WaveOut) => WaveGs5);-1882, 830,61 Hz Piezīme_A5: Wave_Generator porta karte (Trigger => O5 (9), Freq_Cnt => X "06F0", wavegenCLK => CLK, parakstīts (WaveOut) => WaveA5); --1776, 880,00 Hz Piezīme_As5: Viļņu ģeneratora porta karte (Trigers => O5 (10), Freq_Cnt => X "068C", wavegenCLK => CLK, parakstīts (WaveOut) => WaveAs5);-1676, 932,33 Hz Piezīme_B5: Wave_Generator porta karte (Trigger => O5 (11), Freq_Cnt => X "062E", wavegenCLK => CLK, parakstīts (WaveOut) => WaveB5); --1582, 987,77 Hz Piezīme_C6: Wave_Generator porta karte (Trigers => O5 (12), Freq_Cnt => X "05D6", wavegenCLK => CLK, parakstīts (WaveOut) => WaveC6); --1494, 1046,5 Hz ------------ piezīmju izvēles loģika ------------ 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; Atlase: process (WaveC4, WaveCs4, WaveD4, WaveDs4, WaveE4, WaveF4, WaveFs4, WaveG4, WaveGs4, WaveA4, WaveAs4, WaveB4, WaveC5, WaveCs5, WaveD5, WaveDs5, WaveA5, WaveE5, WaveE5, WaveE5, WaveE5 WaveB5, WaveC6) sākas, ja (cntC6 = "00000"), tad --------------- ja netiek ģenerēti signāli Wave0 <= "0000000000"; Vilnis1 <= "0000000000"; Vilnis2 <= "0000000000"; Vilnis3 <= "0000000000"; citādi, ja (O4 (0) = '1'), tad ------------------- piezīme C4 atskaņoja Wave0 Wave0 Wave1 kļūdu Wave0 Wave1 Wave2 kļūdu Wave0 Wave1 Wave2 Wave3 kļūdu Wave0 Wave1 Wave2 Wave3 kļūda Wave0 Wave1 Wave2 Wave3 kļūda Wave0 Wave1 Wave2 Wave3 kļūda Wave0 Wave1 Wave2 Wave3 kļūda Wave0 Wave1 Wave2 Wave3 kļūda Wave0 Wave1 Wave2 Wave3 Wave0 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave Wave2 Wave3 kļūda Wave0 Wave1 Wave2 Wave3 kļūda Wave0 Wave1 Wave2 Wave3 kļūda Wave0 Wave1 Wave2 Wave3 kļūda Wave0 Wave1 Wave2 Wave3 kļūda Wave0 Wave1 Wave2 Wave3 Wave0 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave2 Wave = VilnisC6; Vilnis1 <= "0000000000"; Vilnis2 <= "0000000000"; Vilnis3 Vilnis1 <= VilnisC6; Vilnis2 <= "0000000000"; Vilnis3 Vilnis2 <= VilnisC6; Wave3 Wave3 kļūda Wave1 <= "0000000000"; Vilnis2 <= "0000000000"; Vilnis3 Vilnis2 <= "0000000000"; Wave3 Wave3 kļūda <= '1'; beigu korpuss; beigt, ja; beigt, ja; beigu process; ------------- sinusa viļņu saskaitītājs -------------------- WaveSum <= STD_LOGIC_VECTOR (Wave0 + Wave1 + Wave2 + Wave3); --------- padarīt sinusa vilni pozitīvu pwm --------------------- pozitīvuWaveSum <= nav WaveSum (9) & WaveSum (8 līdz 0); ------------- PWM ģenerators --------------------- process (CLK)-mainīgo skaits: neparakstīts (1 līdz 0): = neparakstīts (0, 2); sākt, ja (pieaugošā mala (CLK)), tad -skaits: = skaits + 1; -ja (skaits = neparakstīts (4, 2)), tad-skaitlis: = neparakstīts (0, 2); --if (PWM = līdz_, ja (PWM <ping_length), tad izvade <= '1'; cits izvads <= '0'; beigas, ja; PWM <= PWM + 1; ping_length <= neparakstīts (pozitīvsWaveSum);-beigas ja; beigt, ja; beigt procesu; beigt uzvedību;

4 Piezīmju atlasītājs Šī projekta sarežģītākā daļa ir tikai četru frekvenču izvēle. Mēs to darījām ar daudziem IF paziņojumiem, un mainīgo vietā izmantojām signālus, lai procesu varētu simulēt un atkļūdot. Mēs izmēģinājām citas metodes, izmantojot mainīgos un FOR cilpas, bet radās izpildlaika kļūdas. Tāpēc galu galā mēs nolēmām, ka, ja tas darbosies, mēs to atstāsim mierā. Nelabojiet to, kas nav salauzts amirīts?

Četri izejas viļņi ir apzīmēti kā Wave0, Wave1, Wave2, Wave3 - tie tiks saskaitīti kopā, veidojot gala izvadi.

Aplūkojot kodu, jūs redzēsit virkni signālu, kas apzīmēti ar C4, Cs4, D4, Ds4 utt. Tie ir 5 bitu signāli, kas saņem atbilstošu sprūdu no O4 (4. oktāva) vai O5 (5. oktāva) un padara tos 5 bitu pievienošanai.

Tālāk mainīgie cntC4, cntCs4 uc norāda, cik nošu, kas ir zemākas par mērķa noti, atskaņotas, ieskaitot mērķa noti. Piemēram, ja tiek atskaņoti C4, E4, G4, A#4 un D5 (C9 akords), cntC4 būs 1, cntE4 būs 2, cntG4 būs 3 utt.

Pēc tam, kad tiek atskaņota piezīme, tiks pārbaudīts mērķnotes skaits, lai noskaidrotu, kur pieslēgt piezīmes signālu. Piemēram, ja tiek atskaņota D5 nots (kas nozīmē, ka O5 (2) ir augsts) un cntD5 ir 3, tad pašlaik tiek atskaņotas 3 notis, ar 2 piezīmēm zemākas nekā D5, tāpēc viļņu D5 pieslēgsim Wave2 (trešais vilnis) signālu skaitīšana no viļņa0). Alternatīvi, ja cntD5 ir 5, tad pašlaik tiek atskaņotas 5 piezīmes ar 4 piezīmēm, kas ir zemākas par D5, tāpēc mēs vienkārši atstāsim waveD5 karājoties un neko ar to nedarīsim.

Pēc tam IF paziņojumi tiek atkārtoti, lai aptvertu visu 25 piezīmju gadījumus.

Amplitūdas saskaitītājs

Pēc tam, kad ir atlasīti zemākie 4 viļņi, mums tie jāpievieno kopā. Iemesls, kāpēc mēs kopā pievienosim tikai četras piezīmes, ir tas, ka PWM idejai, kuru mēs izmantojam savai izvadei, var būt tikai noteikta izšķirtspēja, līdz PWM darbojas pārāk lēni un skaļrunis sāks uztvert PWM kvadrātveida viļņu. Piemēram, ja mēs izmantotu izšķirtspēju 8192 (13 biti), katram no šiem 8192 punktiem jāatbilst borta pulksteņa augošajai malai. Tātad, 100MHz / 8192 = 12,2kHz, kas ir labi cilvēka dzirdes diapazonā.

Faktiskā amplitūdu pievienošana ir ļoti vienkārša, jums vienkārši jāpārliecinās, ka tā var darboties patiešām ātri.

PWM izeja

PWM darba cikls atspoguļos mūsu izejas viļņa amplitūdu tajā brīdī. Piemēram, ja amplitūdas diapazons ir no 0 līdz 128, 0 būtu 0%darba cikls, 64 būtu 50%, 128 būtu 100%utt. Šis PWM darbosies ārkārtīgi ātri (mūsējais ir 97,6 kHz), tik ātri, ka skaļrunis neatpazīst atsevišķus kvadrātveida viļņus un tā vietā aplūko vidējo spriegumu, radot mūsu “analogo” signālu.

Ierobežojumu fails

Iespējams, esat savādāk pievienojis aparatūru, tāpēc pārliecinieties, vai ierobežojumu fails sakrīt.

5. darbība: koda lejupielāde

Zemāk ir kods.txt formātā un.vhd Vivado. Wave_Generator ir viļņu ģeneratora apakšmodulis, un Two_Octave_Synth ir augšējais modulis ar visu pārējo.

Ieteicams: