Агуулгын хүснэгт:

Basys3 FPGA дижитал аудио синтезатор: 5 алхам
Basys3 FPGA дижитал аудио синтезатор: 5 алхам

Видео: Basys3 FPGA дижитал аудио синтезатор: 5 алхам

Видео: Basys3 FPGA дижитал аудио синтезатор: 5 алхам
Видео: EEE5722 LAB 03 KEYBOARD interfacing with Basys3 part 01 2024, Долдугаар сарын
Anonim
Image
Image
Basys3 FPGA дижитал аудио синтезатор
Basys3 FPGA дижитал аудио синтезатор
Basys3 FPGA дижитал аудио синтезатор
Basys3 FPGA дижитал аудио синтезатор

Энэхүү дижитал синус долгионы гар синтезатор нь хэрэглэгчийн оролтыг гар шиг байрлуулсан хэд хэдэн түр зуурын унтраалгаар дамжуулж, чанга яригчаар дамжуулан аудио долгион гаргах болно. Хэрэглэгчийн оролт дээр үндэслэн төхөөрөмж нь C4 -аас C6 хүртэлх янз бүрийн давтамжийн синус долгион үүсгэх болно. Хэрэглэгч C4 -ээс C6 хүртэлх тэмдэглэл оруулах боломжтой (нийт 25 тэмдэглэл), мөн дөрвөн товчлуурыг нэгэн зэрэг оруулах боломжтой - хэрэв 4 -өөс дээш товчлуур дарагдсан бол хамгийн бага дөрвөн дууг тоглуулах болно.

Энэхүү төслийг Райан Моррис, Мавис Цой нар манай Cal Poly CPE 133 дижитал дизайны ангиар хийсэн болно:)

Алхам 1: Онол

FPGA самбар нь зөвхөн дижитал дохиог гаргаж чаддаг. Өөрөөр хэлбэл энэ нь зөвхөн өндөр (3.3V) хүчдэл эсвэл бага (0V) хүчдэл гаргаж чаддаг. Гэсэн хэдий ч аудио дохио нь аналог бөгөөд хүчдэлийн хязгааргүй олон тооны өсөлттэй байж болно. Үүнийг даван туулахын тулд бид аналог долгионыг дууриахын тулд PWM (импульсийн өргөн модуляци) дохиог ашиглах болно. Хэрэв та ХОУХ гэж юу болохыг мэдэхгүй бол эндээс үзээрэй:

Алхам 2: Найрлага ба багаж хэрэгсэл

  • Vivado суулгасан компьютер
  • Бид Vivado 2017.2 хувилбарыг ашиглах болно
  • Basys3 FPGA самбар
  • 25 SPDT хязгаарын унтраалга (бид эдгээрийг ашигласан)
  • 30 холбогч утас (нэг үзүүр нь эрэгтэй, нөгөө үзүүр нь хамаагүй), 12 инч
  • Утас таслагч
  • Утас хуулагч
  • Гагнах зориулалттай сэлбэг утас
  • Давирхайн цөмт гагнуур
  • Гагнуурын төмөр
  • ¼”эмэгтэй аудио залгуур
  • Өсгөгч/чанга яригч
  • Шилжүүлэгчийг холбох ямар нэгэн зүйл (бид протобоард + модон хайрцаг ашигласан)

Алхам 3: Утас ба тоног төхөөрөмжийн тохиргоо

Утас ба тоног төхөөрөмжийн тохиргоо
Утас ба тоног төхөөрөмжийн тохиргоо
Утас ба тоног төхөөрөмжийн тохиргоо
Утас ба тоног төхөөрөмжийн тохиргоо
Утас ба тоног төхөөрөмжийн тохиргоо
Утас ба тоног төхөөрөмжийн тохиргоо

Системийн архитектур

Зураг 1 -ийг үзнэ үү: 25 боломжтой оролт → Basys3 Board → өсгөгч ба чанга яригч.

Гаралт

Зураг 2 -ийг үзнэ үү: Basys3 Board → 1/2 Эмэгтэй аудио залгуур → Чанга яригч (өсгөгчтэй)

Оролт

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)

Синус долгионы үүсгүүр ба ХОУХ -ны генераторыг эхлээд бидний үзэл баримтлал ажиллаж байгаа эсэхийг шалгахын тулд оролтын хязгаарлагч ба далайцын нэмэгдүүлэгч/шилжүүлэгчийг нэгтгэсэн болно. Процессийн блок бүрийн функц ба I/O -ийн дэлгэрэнгүй мэдээллийг Зураг дээр үзүүлэв. Кодыг доор харуулсан боловч VHD болон txt файл хэлбэрээр хавсаргасан болно. Хэрэв зөрүү байгаа бол VHD файлуудыг дагана уу.

BTW: Бид шугамаа богиносгох ёстой байсан ч Instructables дээр код оруулах нь харьцангуй ядаргаатай санагдсан тул зай нь хамгийн том биш бөгөөд синтаксийг тодруулаагүй болно. Хэрэв танд Vivado байгаа бөгөөд кодыг дагахыг хүсч байвал файлыг татаж авахыг зөвлөж байна.

Эхлээд синус долгионы генераторын модулийг авч үзье.

номын сан IEEE; IEEE. STD_LOGIC_1164. ALL ашиглах; IEEE. NUMERIC_STD. ALL ашиглах; Wave_Generator бол порт (Trigger: STD_LOGIC; - Freq_Cnt товчлуурыг дарах: STD_LOGIC_VECTOR -д (15 -аас доош 0); - Тоолуурын утга = 100MHz / (Тэмдэглэлийн давтамж*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'), дараа нь- товчлуур дарагдсан бол: = тоолуур + 1; if (тоолуур = гарын үсэг зураагүй (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"; би <= 0; тоолуур: = to_unsigned (0, 16); -output Amplitude = -64, хэрэв ямар ч тэмдэглэл тоглоогүй бол дуусна; - (Trigger = '1') хэрэв бол; - (өсөлтийн ирмэг (CLK)) төгсгөлийн процесс; зан үйлийн төгсгөл;

Бид дотоод цаг болон ROM ашиглан Basys3 дээр дижитал синус долгион үүсгэх болно. Энэхүү ROM нь синус долгионы 64 далайцыг илэрхийлдэг 64 утгыг хадгалах болно. Зураг 1 -ийг үзнэ үү. Бидний ашигладаг 64 утга нь маш сайн нарийвчлалтай синус долгионыг дуурайдаг.

Дотоод цагийг ашиглан бид хүссэн долгионы давтамжид хуваагдсан цагийн хурдыг илэрхийлсэн утгыг тоолж, 64: Clk div = 100MHz / (Давтамж * 64) Манай тоолуур энэ утганд хүрэх бүрт бид дугаарыг дууддаг. ROM -ийг манай долгионы генераторын модульд илгээнэ үү. Бидний долгионы давтамж нь эдгээр далайцыг хэр хурдан дуудахаас хамаарна.

Бид тус бүр нэг давтамж/тэмдэглэлтэй холбоотой 25 дэд модультай болно.

Синус долгионы генераторын модулийг дууддаг кодын үлдсэн хэсгийг энд харуулав.

номын сан 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 -ийн архитектурын зан төлөв бол Wave_Generator бол порт (Trigger: STD_LOGIC; Freq_Cnt: in STD_LOGIC_VECTOR (15 downto 0); wavegenCLK: in STD_LOGIC; WaveOut: out STD_LOGIC_VECTOR) (9 уруу) төгсгөлийн бүрэлдэхүүн хэсэг; --------------------------- долгионы үүсгүүрээс гарах дохио ----- дохио WaveC4, WaveCs4, WaveD4, WaveDs4, WaveE4, WaveF4, WaveFs4, WaveG4, WaveGs4, WaveA4, WaveAs4, WaveB4, WaveC5, WaveCs5, WaveD5, Wave5, 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: гарын үсэг зураагүй (4 -ээс 0 хүртэл); дохионы алдаа: STD_LOGIC; ----------------------------------- синус долгион нэмэх зориулалттай ----------- --------------- дохио Wave0, Wave1, Wave2, Wave3: гарын үсэг зурсан (9 уруу 0 хүртэл); -Wave Generator модулийн гаралтын дохионы дохио WaveSum: STD_LOGIC_VECTOR (9 уруу 0 хүртэл); -нэгтгэсэн синус долгионы дохио (2 -ийн магтаал -512 -аас 511 хүртэл) эерэг дохио долгионы нийлбэр: STD_LOGIC_VECTOR (9 -ээс 0 хүртэл); -ХОУХ генераторт ашиглахын тулд 0-ээс 1023 хүртэл гарын үсэг зураагүй ----------------------------------- ХОУХ үүсгэх ------------------------------- дохионы ping_length: тэмдэггүй (0-ээс 9 хүртэл): = тэмдэггүй (эерэгWaveSum); --signal off_length: unsigned (6 downto 0): = to_unsigned (127, 7) -unsigned (WAVE); дохио ХОУХ: гарын үсэггүй (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 Гц 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 Гц 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 Гц 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 Гц 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, Wave5, Wave5. WaveB5, WaveC6) хэрэв (cntC6 = "00000"), дараа нь дохио үүсгэхгүй бол --------------- эхэлнэ Wave0 <= "0000000000"; Wave1 <= "0000000000"; Wave2 <= "0000000000"; Wave3 <= "0000000000"; өөр (хэрэв O4 (0) = '1') бол ------------------- тэмдэглэл C4 тоглосон Wave0 Wave0 Wave1 алдаа Wave0 Wave1 Wave2 алдаа Wave0 Wave1 Wave2 Wave3 алдаа Wave0 Wave1 Wave2 Wave3 алдаа Wave0 Wave2 Wave3 Wave1 Wave2 Wave3 Wave2 Wave2 Wave2 Wave3 алдаа Wave0 Wave2 Wave3 Wave1 Wave2 Wave2 Wave2 Wave2 = 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 хүртэл); ------------- ХОУХ генератор --------------------- процесс (CLK)-хувьсах тоо: гарын үсэггүй (1 доош 0 хүртэл)): = гарын үсэг зураагүй (0, 2); эхлэх (эхлэх_хүрээ (CLK)) дараа нь -тоолох: = тоолох + 1; --if (тоолох = to_unsigned (4, 2)) дараа нь --count: = to_unsigned (0, 2); --if (PWM = to_ if (PWM <ping_length) бол гаралт <= '1'; өөр гаралт <= '0'; хэрэв дуусвал; PWM <= PWM + 1; ping_length <= unsigned (эерэгWaveSum);-төгсгөл if; end if if; end process; end Behavioral;

4 Тэмдэглэл сонгогч Энэ төслийн хамгийн хэцүү хэсэг нь ердөө дөрвөн давтамжийг сонгох явдал юм. Бид үүнийг бүхэл бүтэн 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 байна, одоогоор D5 -аас доогуур 2 ноттой 3 тэмдэглэл тоглож байгаа тул бид долгион D5 -ийг Wave2 -тэй холбоно (гурав дахь давалгаа) долгионоос дохио тоолох0). Эсвэл, хэрэв cntD5 нь 5 бол, одоогоор D5 -аас доогуур 4 ноттой 5 тэмдэглэл тоглож байгаа тул бид waveD5 -ийг өлгөсөн хэвээр үлдээж, түүнтэй юу ч хийхгүй.

Дараа нь IF -ийн мэдэгдлийг 25 тэмдэглэлийн бүх тохиолдлуудыг давтах болно.

Амплитуд Аддер

Хамгийн бага 4 долгионыг сонгосны дараа бид тэдгээрийг нэгтгэх ёстой. Зөвхөн дөрвөн тэмдэглэлийг хамтад нь нэмэх болсон шалтгаан нь бидний гаралтанд ашиглаж буй ХОУХШ -ийн санаа нь ХОУХ хэт удаан ажиллаж, чанга яригч ХОУХ -ны дөрвөлжин долгионыг авах хүртэл тодорхой нарийвчлалтай байж чаддагт оршино. Жишээлбэл, хэрэв бид 8192 (13 бит) нарийвчлалтай бол эдгээр 8192 цэг бүр нь онгоцны цагны өсөн нэмэгдэж буй ирмэгтэй тохирч байх ёстой. Тиймээс 100МГц / 8192 = 12.2 кГц нь хүний сонсголын хүрээнд маш сайн байдаг.

Далайн далайцыг нэмэх нь маш энгийн бөгөөд та үүнийг үнэхээр хурдан ажиллуулж чадах эсэхийг шалгах хэрэгтэй.

ХОУХ -ны гаралт

ХОУХ -ны үүргийн мөчлөг нь бидний гаралтын долгионы далайцыг илэрхийлэх болно. Жишээлбэл, хэрэв бид 0 -ээс 128 хүртэлх далайцтай бол 0 нь 0%-ийн ажлын мөчлөг, 64 нь 50%, 128 нь 100%гэх мэт байх болно. Энэ ХОУХ нь маш хурдан ажиллах болно (биднийх 97.6 кГц), чанга яригч нь квадрат долгион тус бүрийг танихгүй бөгөөд дундаж хүчдэлийг хараад бидний "аналог" дохиог бий болгодог.

Хязгаарлалтын файл

Та техник хангамжаа өөр аргаар холбосон байж магадгүй тул хязгаарлалтын файл таарч байгаа эсэхийг шалгаарай.

Алхам 5: Код татаж авах

Vivado -д зориулсан.txt формат болон.vhd хоёуланг нь хоёуланг нь доор харуулав. Wave_Generator бол долгионы үүсгүүрийн дэд модуль бөгөөд Two_Octave_Synth бол бусад бүх зүйлтэй хамгийн сайн модуль юм.

Зөвлөмж болгож буй: