Բովանդակություն:

Basys3 FPGA թվային աուդիո սինթեզատոր ՝ 5 քայլ
Basys3 FPGA թվային աուդիո սինթեզատոր ՝ 5 քայլ

Video: Basys3 FPGA թվային աուդիո սինթեզատոր ՝ 5 քայլ

Video: Basys3 FPGA թվային աուդիո սինթեզատոր ՝ 5 քայլ
Video: Basys 3 Introduction 2024, Հուլիսի
Anonim
Image
Image
Basys3 FPGA թվային աուդիո սինթեզատոր
Basys3 FPGA թվային աուդիո սինթեզատոր
Basys3 FPGA թվային աուդիո սինթեզատոր
Basys3 FPGA թվային աուդիո սինթեզատոր

Այս թվային սինուս -ալիքի ստեղնաշարի սինթեզատորը օգտվողի մուտքերը կտեղափոխի ստեղնաշարի պես շարված մի քանի ակնթարթային անջատիչների միջոցով և ձայնային ալիք կհաղորդի բարձրախոսի միջոցով: Օգտագործողի մուտքի հիման վրա սարքը կստեղծի տարբեր հաճախականությունների սինուս ալիքներ C4- ից C6- ից: Օգտագործողը կարող է գրառումներ կատարել C4- ից մինչև C6 (ընդամենը 25 նոտա) և միաժամանակ մինչև չորս ստեղն, եթե չորսից ավելի ստեղներ սեղմվեն, կհնչեն չորս ամենացածր հնչերանգները:

Այս նախագիծը կատարեցին Ռայան Մորիսը և Մավիս soոյը ՝ մեր Cal Poly CPE 133 թվային դիզայնի դասի համար:)

Քայլ 1: Տեսություն

FPGA տախտակը կարող է թողարկել միայն թվային ազդանշաններ: Այլ կերպ ասած, այն կարող է արտադրել միայն բարձր (3.3V) կամ ցածր (0V) լարման: Այնուամենայնիվ, աուդիո ազդանշանները անալոգային են և կարող են ունենալ անսահման շատ լարման աճ: Այս ամենը շրջանցելու համար մենք կօգտագործենք PWM (զարկերակի լայնության մոդուլյացիա) ազդանշան ՝ նմանակելու անալոգային ալիքը: Եթե չգիտեք, թե ինչ է PWM- ը, ստուգեք սա ՝

Քայլ 2: Բաղադրիչներ և գործիքներ

  • Տեղադրված է Vivado համակարգիչ
  • Մենք կօգտագործենք Vivado տարբերակը 2017.2
  • Basys3 FPGA խորհուրդը
  • 25 SPDT սահմանափակիչ անջատիչ (մենք դրանք օգտագործում էինք)
  • 30 թռիչքային լար (մի ծայրը արու է, մյուս ծայրը նշանակություն չունի), 12 դյույմ
  • Մետաղալար կտրիչներ
  • Մետաղալարեր
  • Areոդման համար պահեստային մետաղալար
  • Խեժի միջուկի զոդում
  • Oldոդման երկաթ
  • ¼ »կանացի աուդիո խցիկ
  • Ուժեղացուցիչ/բարձրախոս
  • Անջատիչները միացնելու համար ինչ -որ բան կա (մենք օգտագործում էինք նախատախտակ + փայտե տուփ)

Քայլ 3: Հաղորդալարերի և սարքավորումների տեղադրում

Հաղորդալարերի և սարքավորումների կարգավորում
Հաղորդալարերի և սարքավորումների կարգավորում
Հաղորդալարերի և սարքավորումների կարգավորում
Հաղորդալարերի և սարքավորումների կարգավորում
Հաղորդալարերի և սարքավորումների կարգավորում
Հաղորդալարերի և սարքավորումների կարգավորում

Համակարգի ճարտարապետություն

Տե՛ս Նկար 1: 25 հասանելի մուտքերը → Basys3 Board → ուժեղացուցիչ և բարձրախոս:

Ելք

Տես նկ.

Մուտք

Modածր մուտքը տեսնելու համար Basys3 տախտակի վրա գտնվող pmod կապերը պետք է միացված լինեն գետնին և չեն գործի ճիշտ, եթե մնան որպես բաց միացում: Դրա պատճառով մենք պետք է օգտագործենք SPDT անջատիչներ մեր նշման բոլոր ստեղների համար: SPDT անջատիչը հիմնականում թույլ է տալիս օգտվողին սեղմելիս անցնել սխեմաների միջև, ուստի դրանք կօգտագործենք որպես մեր «կոճակներ» ՝ Basys3 տախտակին ցածր (0V) կամ բարձր (3.3V) ազդանշաններ մուտքագրելու համար:

Յուրաքանչյուր անջատիչ կունենա NO (սովորաբար բացված) տերմինալը միացված 3.3V, NC (սովորաբար փակ) տերմինալը `GND- ին, և COM (ընդհանուր) տերմինալը` FPGA մուտքին: Տես նկար 3:

Քանի որ մենք ունենք 25 սահմանային անջատիչ, նրանք բոլորը կկիսեն ընդհանուր 3.3 Վ գիծ և ընդհանուր GND գիծ: Այնուհետև յուրաքանչյուր սահմանային անջատիչից ազդանշանային գիծը կմիավորվի 8 -հոգանոց խմբերում և կպչվի Basys3 տախտակի վրա գտնվող pmod միացումներին ՝ օգտագործելով կայծակաճարմանչ լարերը ՝ նվազագույնի հասցնելու մեր ստեղծած մոնումենտալ խառնաշփոթը: Տես նկար 4 կամ առաջին ութ բանալիների օրինակ:

Քայլ 4: VHDL կարգավորում (Vivado)

VHDL կարգավորում (Vivado)
VHDL կարգավորում (Vivado)
VHDL կարգավորում (Vivado)
VHDL կարգավորում (Vivado)

Սկզբում փորձարկվեցին սինուսային ալիքների գեներատորը և PWM գեներատորը `համոզվելու համար, որ մեր հայեցակարգը գործում է, այնուհետև ինտեգրվեցին մուտքի սահմանափակիչը և ամպլիտուդային ավելացուցիչը/փոփոխիչը: Յուրաքանչյուր գործընթացի բլոկի գործառույթի և մուտքի/ելքի մանրամասները ներկայացված են Նկարում: Կոդը ցուցադրվում է ստորև, բայց նաև կցված է որպես VHD և txt ֆայլեր: Եթե կան անհամապատասխանություններ, անցեք VHD ֆայլերով:

BTW. Մենք, հավանաբար, պետք է մեր տողերն ավելի կարճ դարձնեինք, բայց Instructables- ում տեղադրված ծածկագիրը նույնպես բավականին ձանձրացնող էր, ուստի տարածությունը ամենամեծը չէ և շարահյուսության ընդգծում չկա: Եթե ունեք Vivado և կցանկանայիք հետևել ծածկագրին, խորհուրդ ենք տալիս պարզապես ներբեռնել ֆայլը:

Նախ, եկեք նայենք Sine Wave Generator մոդուլին:

գրադարան IEEE; օգտագործել IEEE. STD_LOGIC_1164. ALL; օգտագործել IEEE. NUMERIC_STD. ALL; սուբյեկտ Wave_Generator- ը Պորտ է (Գործարկիչ ՝ STD_LOGIC- ում; - Հիմնական սեղմում Freq_Cnt: STD_LOGIC_VECTOR (15 -ից 0); - Հաշվիչի արժեք = 100 ՄՀց / (Նշում Հաճախականությունը*64 Սինուս ալիքի ստորաբաժանումներ) (կլոր մոտակա համարին) - վերանվանված Freq wavegenCLK- ից ՝ STD_LOGIC- ում; - Basys3 100 ՄՀց CLK WaveOut. դուրս STD_LOGIC_VECTOR (9 իջնում է 0 -ից)); - ալիքի վերջի ստորագրված ամպլիտուդ Wave_Generator; ճարտարապետություն Wave_Generator- ի վարքագիծը ազդանշան i- ն է `0 -ից մինչև 64 ամբողջական թիվ = = 0; -ամպլիտուդային հիշողության բանկի տիպի memory_type զանգվածը (0 -ից 63) ամբողջ միջակայքի -64 -ից 63 -ն է. - ստեղծել հիշողության բանկ (ROM) ամպլիտուդային արժեքներ պահելու համար. այս RAM- ը կամ ROM- ն ուղղակի հետաքրքրու՞մ են … ազդանշանի ամպլիտուդ `memory_type: = (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); - ամպլիտուդային հիշողության բանկը սինուսային ալիքի սկսման գործընթացի համար (wavegenCLK, Trigger) փոփոխական հաշվիչ ՝ անստորագիր (15-ից 0-ից ներքև). - ժամացույցի բաժանարար հաշվիչը, որը վերանվանվել է count1- ից, սկսվում է եթե (բարձրանում_եզր (wavegenCLK)) ապա եթե (ձգան = '1') ապա- ստեղնը սեղմված է հաշվիչ. = հաշվիչ + 1; եթե (հաշվիչ = անստորագիր (Freq_Cnt)) ապա - Freq_Cnt = 100 ՄՀց / (նշեք հաճախականությունը * սինուսային ալիքի 64 ստորաբաժանումներ) - զրոյական հաշվիչ զետեղել և ամպլիտուդիայի տվյալները նշանակել ելքային հաշվիչին. = to_unsigned (0, 16); WaveOut <= STD_LOGIC_VECTOR (դեպի_ստորագրված (ամպլիտուդ (i), 10)); - ավելացում i հաջորդ ընթերցման համար i <= i + 1; - վերականգնել i, եթե մեկ սինուս ալիքն ավարտվել է, եթե (i = 63), ապա i <= 0; ավարտ, եթե; ավարտ, եթե; - (հաշվիչ = անստորագիր (Freq_Cnt)) այլ բան- բանալին սեղմված չէ- վերակայել ելքը, ամպլիտուդի ինդեքսը և հաշվիչ WaveOut <= "0000000000"; i <= 0; հաշվիչ `= դեպի_անուն ստորագրված (0, 16); -ելքային ամպլիտուդիա = -64, երբ ոչ մի նոտա չի նվագվում, եթե; - (ձգան = '1') վերջ, եթե; - (բարձրացման եզր) (CLK)) ավարտի գործընթաց; վերջ Վարքագծային;

Մենք կստեղծենք թվային սինուս ալիք Basys3- ում ՝ օգտագործելով ներքին ժամացույցը և ROM- ը: Այս ROM- ը կպահի 64 արժեք, որոնք ներկայացնում են 64 ամպլիտուդներ սինուսային ալիքի վրա: Տե՛ս Գծապատկեր 1. Մեր օգտագործած 64 արժեքները նմանակում են սինուսային ալիքին ՝ բավականին լավ լուծաչափով:

Օգտագործելով ներքին ժամացույցը, մենք հաշվում ենք մի արժեքի, որը ներկայացնում է ժամացույցի արագությունը բաժանված մեր ուզած ալիքի հաճախության և 64: ROM- ը և ուղարկեք այն մեր ալիքի գեներատորի մոդուլից: Մեր ալիքի հաճախականությունը կախված կլինի նրանից, թե որքան արագ ենք մենք անվանում այս ամպլիտուդները:

Մենք կունենանք 25 ենթամոդուլ, որոնցից յուրաքանչյուրը կապված է մեկ հաճախականության/նոտայի հետ:

Ահա մնացած կոդը, որը կոչում է Sine Wave Generator մոդուլներ.

գրադարան IEEE; օգտագործել IEEE. STD_LOGIC_1164. ALL; օգտագործել IEEE. NUMERIC_STD. ALL; Two_Octave_Synth է նավահանգիստ (CLK ՝ STD_LOGIC; O4 ՝ STD_LOGIC_VECTOR (11 -ից 0), O5 ՝ STD_LOGIC_VECTOR (12 ներքև 0); ելք ՝ STD_LOGIC); վերջ Two_Octave_Synth; ճարտարապետություն Two_Octave_Synth է բաղադրիչ վերջնական բաղադրիչ; --------------------------- ալիքային գեներատորի ելքային ազդանշաններ ------------------ ----- ազդարարել WaveC4, WaveCs4, WaveD4, WaveDs4, WaveE4, WaveF4, WaveFs4, WaveG4, WaveGs4, WaveA4, WaveAs4, WaveB4, WaveC5, WaveCs5, WaveD5, WaveDs5, WaveE5, WaveF5, WaveFs5, WaveG5, WaveGs5, WaveA5, WaveAs5, WaveB5, WaveC6 ՝ ստորագրված (9 -ից 0 -ի դիմաց); -------------------------------- նշումների ընտրության տրամաբանության համար -------------- ------ ազդանշան 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. Անստորագիր (4 -ից 0 -ի վրա); ազդանշան cntC4, cntCs4, cntD4, cntDs4, cntE4, cntF4, cntFs4, cntG4, cntGs4, cntA4, cntAs4, cntB4, cntC5, cntCs5, cntD5, cntDs5, cntE5, cntF5, cntFs5, cntG5, cntGs5, cntA5, cntAs5, cntB5, cntC6 ՝ անստորագիր (4 -ից 0 -ի վրա); ազդանշանի սխալ ՝ STD_LOGIC; --------------------------------------- սինուսային ալիքներ ավելացնելու համար ----------- --------------- ազդանշան Wave0, Wave1, Wave2, Wave3: ստորագրված է (9-ից 0-ի վրա); -ազդանշաններ Wave Generator մոդուլի ելքային ազդանշանից WaveSum: STD_LOGIC_VECTOR (9 դեպի 0); -ազդանշան ամփոփված սինուսային ալիքների համար (2 -ի հաճոյախոսություն -512 -ից 511) ազդանշան դրական WaveSum: STD_LOGIC_VECTOR (9 դեպի 0); -չստորագրված 0-ից 1023-ը, PWM գեներատորում օգտագործելու համար --------------------------------------- PWM գեներացնողի համար ------------------------------- ազդանշանի ping_length: անստորագիր (9-ից 0-ի դիմաց). -ազդանշան off_length: անստորագիր (6 -ից 0 -ի վրա). = անստորագիր (127, 7) -անստորագիր (ԱԼԻՔ); ազդանշան PWM: անստորագիր (9 -ից 0 -ը). սկսել Նշում_C4. Wave_Generator նավահանգստի քարտեզ (ձգան => O4 (0), Freq_Cnt => X "1755", wavegenCLK => CLK, ստորագրված (WaveOut) => WaveC4); --5973, 261.63 Հց Նշում_Cs4. Wave_Generator նավահանգստի քարտեզ (ձգան => O4 (1), Freq_Cnt => X "1606", wavegenCLK => CLK, ստորագրված (WaveOut) => WaveCs4);-5638, 277.18 Հց Նշում_Դ 4: Wave_Generator նավահանգստի քարտեզ (ձգան => O4 (2), Freq_Cnt => X "14C9", wavegenCLK => CLK, ստորագրված (WaveOut) => WaveD4); --5321, 293.66 Հց Նշում_Ds4. Wave_Generator նավահանգստի քարտեզ (ձգան => O4 (3), Freq_Cnt => X "139F", wavegenCLK => CLK, ստորագրված (WaveOut) => WaveDs4);-5023, 311.13 Հց Նշում_Է 4: Wave_Generator նավահանգստի քարտեզ (ձգան => O4 (4), Freq_Cnt => X "1285", wavegenCLK => CLK, ստորագրված (WaveOut) => WaveE4); --4741, 329.63 Հց Նշում_F4. Wave_Generator նավահանգստի քարտեզ (ձգան => O4 (5), Freq_Cnt => X "117B", wavegenCLK => CLK, ստորագրված (WaveOut) => WaveF4); --4475, 349.23 Հց Նշում_Ֆս 4. Wave_Generator նավահանգստի քարտեզ (ձգան => O4 (6), Freq_Cnt => X "1080", wavegenCLK => CLK, ստորագրված (WaveOut) => WaveFs4);-4224, 369.99 Հց Նշում_G4: Wave_Generator նավահանգստի քարտեզ (ձգան => O4 (7), Freq_Cnt => X "0F92", wavegenCLK => CLK, ստորագրված (WaveOut) => WaveG4); --3986, 392.00 Հց Նշում_Gs4. Wave_Generator նավահանգստի քարտեզ (ձգան => O4 (8), Freq_Cnt => X "0EB3", wavegenCLK => CLK, ստորագրված (WaveOut) => WaveGs4);-3763, 415.30 Հց Նշում_Ա 4: Wave_Generator նավահանգստի քարտեզ (ձգան => O4 (9), Freq_Cnt => X "0DE0", wavegenCLK => CLK, ստորագրված (WaveOut) => WaveA4); --3552, 440.00 Հց Նշում_Ազ 4. Wave_Generator նավահանգստի քարտեզ (ձգան => O4 (10), Freq_Cnt => X "0D18", wavegenCLK => CLK, ստորագրված (WaveOut) => WaveAs4);-3352, 466.16 Հց Նշում_B4: Wave_Generator նավահանգստի քարտեզ (ձգան => O4 (11), Freq_Cnt => X "0C5C", wavegenCLK => CLK, ստորագրված (WaveOut) => WaveB4); --3164, 493.88 Հց ------------------------------------------------ ------------------------------------------------------ --------------------------- Նշում_C5. Wave_Generator նավահանգստի քարտեզ (ձգան => O5 (0), Freq_Cnt => X "0BAB", wavegenCLK => CLK, ստորագրված (WaveOut) => WaveC5); --2987, 523.25 Հց Նշում_Cs5. Wave_Generator նավահանգստի քարտեզ (ձգան => O5 (1), Freq_Cnt => X "0B03", wavegenCLK => CLK, ստորագրված (WaveOut) => WaveCs5);-2819, 554.37 Հց Նշում_Դ 5: Wave_Generator նավահանգստի քարտեզ (ձգան => O5 (2), Freq_Cnt => X "0A65", wavegenCLK => CLK, ստորագրված (WaveOut) => WaveD5); --2661, 587.33 Հց Նշում_Դս 5. Wave_Generator նավահանգստի քարտեզ (ձգան => O5 (3), Freq_Cnt => X "09D0", wavegenCLK => CLK, ստորագրված (WaveOut) => WaveDs5);-2512, 622.25 Հց Նշում_Է 5: Wave_Generator նավահանգստի քարտեզ (ձգան => O5 (4), Freq_Cnt => X "0943", wavegenCLK => CLK, ստորագրված (WaveOut) => WaveE5); --2371, 659.25 Հց Նշում_F5. Wave_Generator նավահանգստի քարտեզ (ձգան => O5 (5), Freq_Cnt => X "08Be", wavegenCLK => CLK, ստորագրված (WaveOut) => WaveF5); --2238, 698.46 Հց Նշում_Ֆս 5. Wave_Generator նավահանգստի քարտեզ (ձգան => O5 (6), Freq_Cnt => X "0840", wavegenCLK => CLK, ստորագրված (WaveOut) => WaveFs5);-2112, 739.99 Հց Նշում_5: Wave_Generator նավահանգստի քարտեզ (ձգան => O5 (7), Freq_Cnt => X "07CA", wavegenCLK => CLK, ստորագրված (WaveOut) => WaveG5); --1994, 783.99 Հց Նշում_Gs5. Wave_Generator նավահանգստի քարտեզ (ձգան => O5 (8), Freq_Cnt => X "075A", wavegenCLK => CLK, ստորագրված (WaveOut) => WaveGs5);-1882, 830.61 Հց Նշում_Ա5: Wave_Generator նավահանգստի քարտեզ (ձգան => O5 (9), Freq_Cnt => X "06F0", wavegenCLK => CLK, ստորագրված (WaveOut) => WaveA5); --1776, 880.00 Հց Նշում_Աս 5. Wave_Generator նավահանգստի քարտեզ (ձգան => O5 (10), Freq_Cnt => X "068C", wavegenCLK => CLK, ստորագրված (WaveOut) => WaveAs5);-1676, 932.33 Հց Նշում_Բ5: Wave_Generator նավահանգստի քարտեզ (ձգան => O5 (11), Freq_Cnt => X "062E", wavegenCLK => CLK, ստորագրված (WaveOut) => WaveB5); --1582, 987.77 Հց Նշում_C6. Wave_Generator նավահանգստի քարտեզ (ձգան => O5 (12), Freq_Cnt => X "05D6", wavegenCLK => CLK, ստորագրված (WaveOut) => WaveC6); --1494, 1046.5 Հց ------------ նշումների ընտրության տրամաբանություն ------------ 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; Ընտրությունը: գործընթաց (WaveC4, WaveCs4, WaveD4, WaveDs4, WaveE4, WaveF4, WaveFs4, WaveG4, WaveGs4, WaveA4, WaveAs4, WaveB4, WaveC5, WaveCs5, WaveD5, WaveDs5, WaveE5, WaveF5, WaveFs5, WaveG5, WaveGs5, WaveA5, WaveAs5, WaveB5, WaveC6) սկսվում են եթե (cntC6 = "00000") ապա --------------- եթե ազդանշաններ չեն ստեղծվում Wave0 <= "0000000000"; Ալիք 1 <= "0000000000"; Ալիք 2 <= "0000000000"; Ալիք 3 <= "0000000000"; այլապես, եթե (O4 (0) = '1') ապա ------------------- նշում C4- ը խաղացել է Wave0 Wave0 Wave0 սխալ Wave0 Wave1 Wave2 սխալ Wave0 Wave1 Wave2 Wave3 սխալ Wave0 Wave1 Wave2 Wave3 սխալ Wave0 Wave1 Wave2 Wave3 սխալ Wave0 Wave1 Wave2 Wave3 սխալ Wave0 Wave1 Wave2 Wave3 սխալ Wave0 Wave1 Wave2 Wave3 սխալ Wave0 Wave1 Wave2 Wave3 սխալ Wave0 Wave1 Wave2 Wave3 սխալ Wave0 Wave1 Wave2 Wave3 սխալ Wave0 Wave1 Wave2 Wave3 սխալ Wave0 Wave1 Wave2 Wave3 սխալ Wave0 Wave1 Wave2 Wave3 սխալ Wave0 Wave1 Wave2 Wave3 սխալ Wave0 Wave1 Wave2 Wave3 սխալ Wave0 Wave1 Wave2 Wave3 սխալ Wave0 Wave1 Wave2 Wave3 սխալ Wave0 Wave1 Wave2 Wave3 սխալ Wave0 Wave1 Wave2 Wave3 սխալ Wave0 Wave1 Wave2 Wave3 սխալ Wave0 Wave1 Wave2 Wave3 սխալ Wave0 Wave1 Wave2 Wave3 սխալ Wave0 < = WaveC6; Ալիք 1 <= "0000000000"; Ալիք 2 <= "0000000000"; Wave3 Wave1 <= WaveC6; Ալիք 2 <= "0000000000"; Wave3 Wave2 <= WaveC6; Wave3 Wave3 սխալ Wave1 <= "0000000000"; Ալիք 2 <= "0000000000"; Wave3 Wave2 <= "0000000000"; Wave3 Wave3 սխալ <= '1'; վերջնական գործ; ավարտ, եթե; ավարտ, եթե; ավարտի գործընթացը; ------------- սինուսային ալիք ավելացնող -------------------- WaveSum <= STD_LOGIC_VECTOR (Wave0 + Wave1 + Wave2 + Wave3); --------- սինուսային ալիքը դրական դարձրեք pwm- ի համար --------------------- դրականWaveSum <= ոչ WaveSum (9) & WaveSum (8 ներքև 0); ------------- PWM գեներատոր --------------------- գործընթաց (CLK)-փոփոխականների հաշվարկ. Անստորագիր (1 դեպի 0): = անստորագիր (0, 2); սկսել եթե (բարձրանալու_սահման (CLK)) ապա --հաշիվ ՝ = հաշվել + 1; --if (count = to_unsigned (4, 2)) then --count: = to_sunsigned (0, 2); --if (PWM = to_ if (PWM <ping_length) then output <= '1'; else output <= '0'; end if; PWM <= PWM + 1; ping_length <= unsigned (positiveWaveSum); --end եթե; վերջ եթե; ավարտել գործընթացը; վերջ վարքագծային;

4 Noteանոթագրությունների ընտրիչ Այս նախագծի ամենադժվար մասը միայն չորս հաճախականություններ ընտրելն է: Մենք դա արեցինք մի ամբողջ լոտա IF հայտարարությամբ և փոփոխականների փոխարեն օգտագործեցինք ազդանշաններ, որպեսզի գործընթացը մոդելավորվի և կարգաբերվի: Մենք փորձեցինք այլ մեթոդներ ՝ օգտագործելով փոփոխականներ և FOR loops, բայց հանդիպեցինք սխալների ընթացքում: Այսպիսով, ի վերջո, մենք որոշեցինք, որ եթե այն աշխատի, մենք նրան հանգիստ կթողնենք:Մի շտկեք այն, ինչ ամիրիտը չի կոտրվել:

Չորս ելքային ալիքները պիտակավորված են ՝ Wave0, Wave1, Wave2, Wave3.

Նայելով ծածկագրին ՝ կտեսնեք մի շարք ազդանշաններ ՝ պիտակավորված C4, Cs4, D4, Ds4 և այլն: Սրանք 5-բիթանոց ազդանշաններ են, որոնք վերցնում են O4 (օկտավա 4) կամ O5 (օկտավա 5) համապատասխան ձգանը և դրանք դարձնում 5-բիթ ավելացնելու համար:

Հաջորդը, cntC4, cntCs4 և այլն փոփոխականները ներկայացնում են թիրախային նոտայից ցածր նոտաների նվագարկումը, ներառյալ թիրախային նոտան: Օրինակ, եթե խաղարկվեն C4, E4, G4, A#4 և D5 (C9 ակորդներ) cntC4- ը կլինի 1, cntE4- ը ՝ 2, cntG4- ը ՝ 3 և այլն:

Այնուհետև, երբ որևէ նոտա է նվագվում, թիրախային նոտայի հաշվարկը կքննվի `տեսնելու, թե ուր է պետք միացնել նոտայի ազդանշանը: Օրինակ, եթե նվագարկվում է D5 նոտան (ինչը նշանակում է, որ O5- ը (2) բարձր է), իսկ cntD5- ը ՝ 3, ապա ներկայումս նվագվում է 3 նոտա, որոնցից 2 նոտան ցածր է D5- ից, այնպես որ մենք waveD5- ը կկապենք Wave2- ի հետ (երրորդ ալիքը ազդանշանի հաշվարկը Wave0- ից): Այլապես, եթե cntD5- ը 5 է, ապա ներկայումս նվագարկվում է 5 նոտա, որոնցից 4 նոտան ցածր է D5- ից, այնպես որ մենք պարզապես թողնում ենք waveD5- ը կախված և ոչինչ չենք անի դրա հետ:

IF- ի հայտարարություններն այնուհետև կրկնվում են `ընդգրկելով բոլոր 25 գրառումների դեպքերը:

Amplitude Adder

Ամենացածր 4 ալիքները ընտրելուց հետո մենք պետք է դրանք միասին ավելացնենք: Պատճառն այն է, որ մենք ընդամենը չորս նշումներ կավելացնենք միասին, այն է, որ PWM գաղափարը, որը մենք օգտագործում ենք մեր ելքի համար, կարող է ունենալ միայն որոշակի լուծում, մինչև PWM- ն չափազանց դանդաղ աշխատի, և բարձրախոսը սկսի վերցնել PWM քառակուսի ալիքը: Օրինակ, եթե մենք օգտագործենք 8192 (13 բիթ) թույլատրելիություն, այդ 8192 կետերից յուրաքանչյուրը պետք է համապատասխանի բորտ ժամացույցի բարձրացող եզրին: Այսպիսով, 100 ՄՀց / 8192 = 12.2 կՀց, ինչը լավ է գտնվում մարդու լսողության սահմաններում:

Ամպլիտուդների փաստացի ավելացումը չափազանց պարզ է, պարզապես պետք է համոզվել, որ այն կարող է իսկապես արագ աշխատել:

PWM ելք

PWM- ի աշխատանքային ցիկլը կներկայացնի այդ պահին մեր ելքային ալիքի ամպլիտուդը: Օրինակ, եթե մենք ունենք 0 -ից 128 ամպլիտուդային տիրույթ, 0 -ը կլինի 0%աշխատանքային ցիկլ, 64 -ը ՝ 50%, 128 -ը ՝ 100%և այլն: Այս PWM- ը կաշխատի չափազանց արագ (մերն է 97,6 կՀց), այնքան արագ, որ բարձրախոսը չի ճանաչի առանձին քառակուսի ալիքները և փոխարենը նայելու է միջին լարմանը ՝ ստեղծելով մեր «անալոգային» ազդանշանը:

Սահմանափակումների ֆայլ

Հնարավոր է ՝ դուք այլ կերպ եք միացրել ձեր սարքաշարը, այնպես որ համոզվեք, որ սահմանափակումների ֆայլը համընկնում է:

Քայլ 5: Կոդի ներլցումներ

Ստորև բերված է կոդը ՝ ինչպես.txt ձևաչափով, այնպես էլ.vhd Vivado- ի համար: Wave_Generator- ը ալիքների գեներատորի ենթամոդուլն է, իսկ Two_Octave_Synth- ը ՝ ամենաբարձր մոդուլը ՝ մնացած ամեն ինչով:

Խորհուրդ ենք տալիս: