Мазмуну:

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 нота), жана бир эле убакта төрт баскычка чейин - эгерде төрттөн ашык баскыч басылса, эң төмөнкү төрт обон ойнотулат.

Бул долбоорду биздин Cal Poly CPE 133 Digital Design классы үчүн Райан Моррис жана Мавис Цой жасаган:)

1 -кадам: Теория

FPGA тактасы санарип сигналдарды гана чыгара алат. Башкача айтканда, ал жогорку (3.3V) чыңалууну же төмөн (0V) чыңалууну гана өндүрө алат. Бирок, аудио сигналдар аналог болуп саналат жана чыңалууда чексиз көп кадамдарга ээ болушу мүмкүн. Муну айланып өтүү үчүн биз аналогдук толкунду тууроо үчүн PWM (импульстун туурасы модуляциясы) сигналын колдонобуз. Эгерде сиз PWM деген эмне экенин билбесеңиз, муну текшериңиз:

2 -кадам: Ингредиенттер жана куралдар

  • Vivado орнотулган компьютер
  • Биз Vivado версиясын 2017.2 колдонобуз
  • Basys3 FPGA тактасы
  • 25 SPDT Limit Switch (биз муну колдондук)
  • 30 секирүүчү зым (бир учу эркек, экинчи учу мааниге ээ эмес), 12 дюйм
  • Сым кескичтер
  • Сым тазалагычтар
  • Лайкоо үчүн запастык зым
  • Чайыр өзөктүү Solder
  • Кандооч
  • ¼”аял аудио уячасы
  • Күчөткүч/динамик
  • Которгучтарды орнотуу үчүн бир нерсе (биз протоборд + жыгач кутучаны колдондук)

3 -кадам: Зымдарды жана жабдыктарды орнотуу

Зымдарды жана жабдыктарды орнотуу
Зымдарды жана жабдыктарды орнотуу
Зымдарды жана жабдыктарды орнотуу
Зымдарды жана жабдыктарды орнотуу
Зымдарды жана жабдыктарды орнотуу
Зымдарды жана жабдыктарды орнотуу

Системалык архитектура

1 -сүрөттү караңыз: 25 жеткиликтүү киргизүү → Basys3 Board → күчөткүч жана динамик.

Output

2 -сүрөттү караңыз: Basys3 Board → 1/2 Female Audio Jack → Speaker (Күчөткүч менен)

Киргизүү

Basys3 тактасындагы pmod туташуулары аз кирүүнү көрүү үчүн жерге туташтырылышы керек жана ачык схема катары калтырылганда туура иштебейт. Ушундан улам, биз бардык нота ачкычтары үчүн SPDT которуштургучтарын колдонушубуз керек. Негизинен SPDT которгучу колдонуучуга басылганда микросхемалардын ортосунда өтүүгө мүмкүндүк берет, ошондуктан биз аларды Basys3 тактасына төмөн (0V) же жогорку (3.3V) сигналдарды киргизүү үчүн "баскычтарыбыз" катары колдонобуз.

Ар бир которгучта 3.3V туташкан NO (кадимкидей ачылган) терминалы, GNDге туташкан NC (кадимкидей жабык) терминалы жана FPGA киришине туташкан COM (жалпы) терминалы болот. 3 -сүрөттү караңыз.

Бизде 25 чектөө өчүргүчтөрү болгондуктан, алардын бардыгы жалпы 3.3V линиясын жана жалпы GND линиясын бөлүшүшөт. Андан кийин, ар бир чек которгучтан келген сигнал линиясы 8 топко бириктирилет жана биз жасай турган эстелик башаламандыкты азайтуу үчүн сыдырма секирүүчү зымдарды колдонуп Basys3 тактасындагы pmod байланыштарына туташтырылат. Сүрөт 4тү же биринчи сегиз ачкычтын мисалын караңыз.

4 -кадам: VHDL орнотуу (Vivado)

VHDL орнотуу (Vivado)
VHDL орнотуу (Vivado)
VHDL орнотуу (Vivado)
VHDL орнотуу (Vivado)

Синус толкуну генератору жана PWM генератору биздин концепциянын иштешине ынануу үчүн биринчи жолу текшерилген, андан кийин киргизүү чектегичи жана амплитудалык кошкуч/которуштуруучу интеграцияланган. Ар бир технологиялык блоктун функциясы жана I/O жөнүндө маалыматтар Сүрөттө көрсөтүлгөндөй. Код төмөндө көрсөтүлгөн, бирок 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МГц / (Эскертүү Frequency*64 Синус Толкунунун Бөлүмдөрү) (тегерегине жакын номерге) - аталышы өзгөртүлгөн Freq wavegenCLKтен: STD_LOGICте; - Basys3 100MHz CLK WaveOut: STD_LOGIC_VECTOR (9дан 0го чейин)); - Wave_Generator толкунунун кол коюлган амплитудасы; Wave_Generatorдун архитектурасы i сигнал: 0дөн 64кө чейинки бүтүн сандар диапазону: = 0; -амплитудалык эс тутумдун индекси memory_type -64төн 63кө чейинки бүтүн диапазондогу массив (0дөн 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) өзгөрмөлүү эсептегич: unsigned (15 downto 0): = to_unsigned (0, 16); - count1 деп аталып калган саат бөлүштүргүч эсептегич, эгер башталса (жогорулоо_чеги (wavegenCLK)) анда, эгерде (Trigger = '1') анда- баскыч эсептегичке басылат: = counter + 1; if (counter = unsigned (Freq_Cnt)) then - Freq_Cnt = 100Mhz / (синус толкунунун freq * 64 бөлүмдөрүнө көңүл буруңуз) - эсептегичти баштапкы абалга келтирип, чыгаруу эсептегичке амплитудалык дайындарды дайындаңыз: = to_unsigned (0, 16); WaveOut <= STD_LOGIC_VECTOR (to_signed (амплитудасы (i), 10)); - кийинки окууга i көбөйтүү i <= i + 1; - i синхрондоштуруу аягына чыкса, эгерде i (63) болсо, анда i <= 0; эгерде бүтсө; эгерде бүтсө; - (counter = unsigned (Freq_Cnt)) else- баскычы басылбайт- чыгарууну, амплитуда индексин жана WaveOut эсептегичти баштапкы абалга келтирүү <= "0000000000"; i <= 0; эсептегич: = to_unsigned (0, 16); -Output Amplitude = -64, эгер нота ойнолбосо, эгер аяктаса; - (Trigger = '1') end if; - (жогорулатуу_чеги (CLK)) бүтүрүү процесси; жүрүм -турумду токтотуу;

Биз ички саатты жана ROMду колдонуу менен Basys3тө санарип синус толкунун пайда кылабыз. Бул ROM синус толкунунда 64 амплитуданы билдирген 64 маанини сактайт. Карагыла. Сүрөт 1. Биз колдонгон 64 баалуулуктар синус толкунун абдан жакшы чечилишине окшоштурушат.

Ички саатты колдонуп, биз каалаган толкундун жыштыгына бөлүнгөн сааттын ылдамдыгын көрсөтүүчү мааниге чейин эсептейбиз: Clk div = 100MHz / (Freq * 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 чыкпайт); end Two_Octave_Synth; Архитектура Two_Octave_Synth компоненти болуп саналат Wave_Generator порт болуп саналат (Триггер: STD_LOGICте; Freq_Cnt: STD_LOGIC_VECTORдо (15 төмөн 0); wavegenCLK: STD_LOGICте; WaveOut: STD_LOGIC_VECTOR) (9 төмөн) акыркы компонент; --------------------------- толкун генераторунан чыккан сигналдар ------------------ ----- сигнал WaveC4, WaveCs4, WaveD4, WaveDs4, WaveE4, WaveF4, WaveFs4, WaveG4, WaveGs4, WaveA4, WaveAs4, WaveB4, WaveC5, WaveCs5, WaveD5, WaveDs5, Wave5, Wave5, 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: unsigned (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: unsigned (9дан 0го чейин): = unsigned (оңой WaveSum); --signal off_length: unsigned (6 downto 0): = to_unsigned (127, 7) -unsigned (WAVE); сигнал PWM: unsigned (9 төмөн 0): = to_unsigned (0, 10); баштоо Note_C4: Wave_Generator порт картасы (Trigger => O4 (0), Freq_Cnt => X "1755", wavegenCLK => CLK, кол коюлган (WaveOut) => WaveC4); --5973, 261.63 Гц Note_Cs4: Wave_Generator порт картасы (Trigger => O4 (1), Freq_Cnt => X "1606", wavegenCLK => CLK, кол коюлган (WaveOut) => WaveCs4);-5638, 277.18 Гц Note_D4: Wave_Generator порт картасы (Trigger => O4 (2), Freq_Cnt => X "14C9", wavegenCLK => CLK, кол коюлган (WaveOut) => WaveD4); --5321, 293.66 Гц Note_Ds4: Wave_Generator порт картасы (Trigger => O4 (3), Freq_Cnt => X "139F", wavegenCLK => CLK, кол коюлган (WaveOut) => WaveDs4);-5023, 311.13 Гц Note_E4: Wave_Generator порт картасы (Trigger => O4 (4), Freq_Cnt => X "1285", wavegenCLK => CLK, кол коюлган (WaveOut) => WaveE4); --4741, 329.63 Гц Note_F4: Wave_Generator порт картасы (Trigger => O4 (5), Freq_Cnt => X "117B", wavegenCLK => CLK, кол коюлган (WaveOut) => WaveF4); --4475, 349.23 Гц Note_Fs4: Wave_Generator порт картасы (Trigger => O4 (6), Freq_Cnt => X "1080", wavegenCLK => CLK, кол коюлган (WaveOut) => WaveFs4);-4224, 369.99 Гц Note_G4: Wave_Generator порт картасы (Trigger => O4 (7), Freq_Cnt => X "0F92", wavegenCLK => CLK, кол коюлган (WaveOut) => WaveG4); --3986, 392.00 Hz Note_Gs4: Wave_Generator порт картасы (Trigger => O4 (8), Freq_Cnt => X "0EB3", wavegenCLK => CLK, кол коюлган (WaveOut) => WaveGs4);-3763, 415.30 Гц Note_A4: Wave_Generator порт картасы (Trigger => O4 (9), Freq_Cnt => X "0DE0", wavegenCLK => CLK, кол коюлган (WaveOut) => WaveA4); --3552, 440.00 Hz Note_As4: Wave_Generator порт картасы (Trigger => O4 (10), Freq_Cnt => X "0D18", wavegenCLK => CLK, кол коюлган (WaveOut) => WaveAs4);-3352, 466.16 Гц Note_B4: Wave_Generator порт картасы (Trigger => O4 (11), Freq_Cnt => X "0C5C", wavegenCLK => CLK, кол коюлган (WaveOut) => WaveB4); --3164, 493.88 Гц -------------------------------------------- -------------------------------------------------- --------------------------- Note_C5: Wave_Generator порт картасы (Trigger => O5 (0), Freq_Cnt => X "0BAB", wavegenCLK => CLK, кол коюлган (WaveOut) => WaveC5); --2987, 523.25 Гц Note_Cs5: Wave_Generator порт картасы (Trigger => O5 (1), Freq_Cnt => X "0B03", wavegenCLK => CLK, кол коюлган (WaveOut) => WaveCs5);-2819, 554.37 Гц Note_D5: Wave_Generator порт картасы (Trigger => O5 (2), Freq_Cnt => X "0A65", wavegenCLK => CLK, кол коюлган (WaveOut) => WaveD5); --2661, 587.33 Гц Note_Ds5: Wave_Generator порт картасы (Trigger => O5 (3), Freq_Cnt => X "09D0", wavegenCLK => CLK, кол коюлган (WaveOut) => WaveDs5);-2512, 622.25 Гц Note_E5: Wave_Generator порт картасы (Trigger => O5 (4), Freq_Cnt => X "0943", wavegenCLK => CLK, кол коюлган (WaveOut) => WaveE5); --2371, 659.25 Гц Note_F5: Wave_Generator порт картасы (Trigger => O5 (5), Freq_Cnt => X "08Be", wavegenCLK => CLK, кол коюлган (WaveOut) => WaveF5); --2238, 698.46 Гц Note_Fs5: Wave_Generator порт картасы (Trigger => O5 (6), Freq_Cnt => X "0840", wavegenCLK => CLK, кол коюлган (WaveOut) => WaveFs5);-2112, 739.99 Гц Note_G5: Wave_Generator порт картасы (Trigger => O5 (7), Freq_Cnt => X "07CA", wavegenCLK => CLK, кол коюлган (WaveOut) => WaveG5); --1994, 783.99 Hz Note_Gs5: Wave_Generator порт картасы (Trigger => O5 (8), Freq_Cnt => X "075A", wavegenCLK => CLK, кол коюлган (WaveOut) => WaveGs5);-1882, 830.61 Гц Note_A5: Wave_Generator порт картасы (Trigger => O5 (9), Freq_Cnt => X "06F0", wavegenCLK => CLK, кол коюлган (WaveOut) => WaveA5); --1776, 880.00 Hz Note_As5: Wave_Generator порт картасы (Trigger => O5 (10), Freq_Cnt => X "068C", wavegenCLK => CLK, кол коюлган (WaveOut) => WaveAs5);-1676, 932.33 Гц Note_B5: Wave_Generator порт картасы (Trigger => O5 (11), Freq_Cnt => X "062E", wavegenCLK => CLK, кол коюлган (WaveOut) => WaveB5); --1582, 987.77 Гц Note_C6: Wave_Generator порт картасы (Trigger => 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, Wave5 Wave, 5, Wave5. WaveB5, WaveC6) башталат, эгерде (cntC6 = "00000") анда --------------- эгерде эч кандай сигнал түзүлбөсө Wave0 <= "0000000000"; Wave1 <= "0000000000"; Wave2 <= "0000000000"; Wave3 <= "0000000000"; else if (O4 (0) = '1') then ------------------- note C4 Wave0 Wave0 Wave1 ката Wave0 Wave1 Wave2 ката Wave0 Wave1 Wave2 Wave3 error Wave0 Wave1 ойногон Wave2 Wave3 ката Wave0 Wave1 Wave2 Wave3 ката Wave0 Wave1 Wave2 Wave3 ката Wave0 Wave1 Wave2 Wave3 ката Wave0 Wave1 Wave3 Wave3 error Wave2 Wave3 ката Wave0 Wave1 Wave2 Wave3 ката Wave0 Wave1 Wave2 Wave3 ката Wave0 Wave1 Wave2 Wave3 ката Wave0 Wave1 Wave3 Wave3 error = WaveC6; Wave1 <= "0000000000"; Wave2 <= "0000000000"; Wave3 Wave1 <= WaveC6; Wave2 <= "0000000000"; Wave3 Wave2 <= WaveC6; Wave3 Wave3 катасы Wave1 <= "0000000000"; Wave2 <= "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гө чейин)): = to_unsigned (0, 2); баштоо эгер (көтөрүлүүчү_чеги (CLK)) анда --сана: = саноо + 1; -If (count = to_unsigned (4, 2)) then --count: = to_unsigned (0, 2); --if (PWM = to_ if (PWM <ping_length) анда чыгаруу <= '1'; башка чыгаруу <= '0'; end if; PWM <= PWM + 1; ping_length <= unsigned (оңой WaveSum);-аягы if; end if; end process; end behavioral;

Бул долбоордун эң татаал бөлүгү төрт жыштыкты тандоо. Биз муну Lotta IF билдирүүлөрү менен жасадык жана процессти симуляциялоо жана мүчүлүштүктөрдү оңдоо үчүн өзгөрмөлөрдүн ордуна сигналдарды колдондук. Биз өзгөрмөлөрдү жана FOR циклдерин колдонуп башка ыкмаларды колдонуп көрдүк, бирок иштөө убактысында каталарга туш болдук. Ошентип, акыры, эгерде ал иштесе, биз аны жалгыз калтырабыз деп чечтик. Амирит бузулбаган нерсени оңдобойсузбу?

Төрт чыгуу толкуну Wave0, Wave1, Wave2, Wave3 деп белгиленген - булар акыркы жыйынтыкты түзүү үчүн кошулат.

Кодду карасаңыз, сиз C4, Cs4, D4, Ds4 ж.б белги коюлган сигналдарды көрөсүз. Бул 5 биттик сигналдар, алар O4 (октава 4) же О5тен (октава 5) тиешелүү триггерди алат жана аларды түзөт Кошуу үчүн 5 бит.

Кийинки cntC4, cntCs4, ж.б. Мисалы, эгер C4, E4, G4, A#4 жана D5 ойнотулса (C9 аккорд) cntC4 1 болот, cntE4 2 болот, cntG4 3 болот ж.б.

Андан кийин, нота ойнотулганда, нота сигналынын кайда илинерин билүү үчүн максаттуу нотанын саны каралат. Мисалы, эгер D5 нотасы ойнотулса (бул O5 (2) бийик дегенди билдирет) жана cntD5 3 болсо, анда азыркы учурда 3 ноталар ойнотулуп жатат, D5тен 2 нотасы төмөн, ошондуктан биз waveD5ти Wave2ге илебиз (үчүнчү толкун) Wave0) сигналын эсептөө. Же болбосо, эгер cntD5 5 болсо, анда учурда 5 нота ойнотулуп жатат, D5тен төмөн 4 нотасы бар, ошондуктан биз waveD5 асылып туруп, аны менен эч нерсе кылбайбыз.

IF билдирүүлөрү бардык 25 эскертүүлөр үчүн иштерди жабуу үчүн кайталанат.

Amplitude Adder

Эң төмөнкү 4 толкун тандалгандан кийин биз аларды бирге кошушубуз керек. Бирге төрт нотаны кошуунун себеби, биз чыгарган PWM идеясы PWM өтө жай иштегенге чейин жана спикер PWM чарчы толкунун ала баштаганда гана белгилүү бир чечимге ээ боло алат. Мисалы, эгерде биз 8192 (13 бит) токтомун колдоно турган болсок, анда ошол 8192 чекиттин ар бири борттогу сааттын көтөрүлүп турган четине туура келиши керек. Ошентип, 100МГц / 8192 = 12.2кГц, бул адамдын угуу чегинде.

Амплитудалардын иш жүзүндө кошулушу өтө жөнөкөй, анын чындап чуркай алаарына ынануу керек.

PWM Output

PWMдин иштөө цикли ошол учурда биздин чыгаруу толкунубуздун амплитудасын билдирет. Мисалы, эгерде бизде 0 ден 128ге чейинки амплитудалык диапазон болсо, 0 0%цикл болмок, 64%50%, 128 100%болмок, ж.б. Бул PWM өтө тез иштейт (биздики 97.6 кГц), спикер жеке квадрат толкундарын тааныбай, анын ордуна орточо чыңалууга карап, биздин "аналогдук" сигналды жаратат.

Чектөөлөр файлы

Сиз аппаратты башкача туташтыргандырсыз, андыктан чектөөлөр файлы дал келгенин текшериңиз.

5 -кадам: Кодду жүктөө

Төмөндө Vivado үчүн.txt форматындагы жана.vhd форматындагы код бар. Wave_Generator-бул толкун генераторунун суб-модулу, ал эми Two_Octave_Synth-бул калган модулдар.

Сунушталууда: